Добавление линейного указателя на основе линейных данных и всплывающей подсказки указателя на линейчатой диаграмме d3 v3
Как добавить указатель и подсказку типа http://bl.ocks.org/d3noob/a22c42db65eb00d4e369 дальше .
Я добавляю / / указатель на строку/ / конец раздела кода .но указатель не генерируется должным образом .отображается только один указатель. верхний левый угол . как я могу исправить это любое предложение?
Что я уже пробовал:
<!DOCTYPE html> <meta charset="utf-8"> <style> body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .bar { fill: orange; } .bar:hover { fill: orangered ; } .x.axis path { display: none; } .d3-tip { line-height: 1; font-weight: bold; padding: 12px; background: rgba(0, 0, 0, 0.8); color: #fff; border-radius: 2px; } /* Creates a small triangle extender for the tooltip */ .d3-tip:after { box-sizing: border-box; display: inline; font-size: 10px; width: 100%; line-height: 1; color: rgba(0, 0, 0, 0.8); content: "\25BC"; position: absolute; text-align: center; } /* Style northward tooltips differently */ .d3-tip.n:after { margin: -1px 0 0 0; top: 100%; left: 0; } div.tooltip { position: absolute; text-align: center; width: 60px; height: 28px; padding: 2px; font: 12px sans-serif; background: lightsteelblue; border: 0px; border-radius: 8px; pointer-events: none; } </style> <body> <script src="http://d3js.org/d3.v3.js"></script> <script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script> <div> <svg id="graph"></svg> </div> <script> //https://bl.ocks.org/nanu146/f48ffc5ec10270f55c9e1fb3da8b38f0 function getTextWidth(text, fontSize, fontName) { c = document.createElement("canvas"); ctx = c.getContext("2d"); ctx.font = fontSize + ' ' + fontName; return ctx.measureText(text).width; } function DataSegregator(array, on) { var SegData; OrdinalPositionHolder = { valueOf: function () { thisObject = this; keys = Object.keys(thisObject); keys.splice(keys.indexOf("valueOf"), 1); keys.splice(keys.indexOf("keys"), 1); return keys.length == 0 ? -1 : d3.max(keys, function (d) { return thisObject[d] }) } , keys: function () { keys = Object.keys(thisObject); keys.splice(keys.indexOf("valueOf"), 1); keys.splice(keys.indexOf("keys"), 1); return keys; } } array[0].map(function (d) { return d[on] }).forEach(function (b) { value = OrdinalPositionHolder.valueOf(); OrdinalPositionHolder[b] = OrdinalPositionHolder > -1 ? ++value : 0; }) SegData = OrdinalPositionHolder.keys().map(function () { return []; }); array.forEach(function (d) { d.forEach(function (b) { SegData[OrdinalPositionHolder[b[on]]].push(b); }) }); return SegData; } Data = [ { Date: "1", Categories: [{ Name: "Test Exam Jan", Value: 10 }], LineCategory: [{ Name: "Line1", Value: 69 }] }, { Date: "2", Categories: [{ Name: "Test Exam Feb", Value: 1 }], LineCategory: [{ Name: "Line1", Value: 89 }] }, { Date: "3", Categories: [{ Name: "Test Exam March", Value: 1 }], LineCategory: [{ Name: "Line1", Value: 72 }] }, { Date: "4", Categories: [{ Name: "Test Exam 1", Value: 1 }], LineCategory: [{ Name: "Line1", Value: 75 }] }, { Date: "5", Categories: [{ Name: "Test Exam 2", Value: 5 }], LineCategory: [{ Name: "Line1", Value: 52 }] }, { Date: "6", Categories: [{ Name: "Test Exam 3", Value: 3 }], LineCategory: [{ Name: "Line1", Value: 40 }] }, { Date: "7", Categories: [{ Name: "Test Exam 4", Value: 12 }], LineCategory: [{ Name: "Line1", Value: 37 }] }, { Date: "8", Categories: [{ Name: "Test Exam 5", Value: 5 }], LineCategory: [{ Name: "Line1", Value: 68 }] }, { Date: "9", Categories: [{ Name: "Test Exam 6", Value: 3 }], LineCategory: [{ Name: "Line1", Value: 92 }] }, { Date: "10", Categories: [{ Name: "Test Exam 7", Value: 7 }], LineCategory: [{ Name: "Line1", Value: 95 }] }, { Date: "11", Categories: [{ Name: "Test Exam 8", Value: 2 }], LineCategory: [{ Name: "Line1", Value: 55 }] }, { Date: "12", Categories: [{ Name: "Test Exam 9", Value: 9 }], LineCategory: [{ Name: "Line1", Value: 50 }] }, { Date: "13", Categories: [{ Name: "Test Exam 10",Value: 1 }], LineCategory: [{ Name: "Line1", Value: 25 }] }, { Date: "14", Categories: [{ Name: "Test Exam 11",Value: 4 }], LineCategory: [{ Name: "Line1", Value: 99 }] }, { Date: "15", Categories: [{ Name: "Test Exam 12",Value: 7 }], LineCategory: [{ Name: "Line1", Value: 82 }] }, { Date: "16", Categories: [{ Name: "Test Exam 13",Value: 5 }], LineCategory: [{ Name: "Line1", Value: 32 }] }, ] var margin = { top: 20, right: 30, bottom: 60, left: 40 }, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var textWidthHolder = 0; /// Adding Date in LineCategory Data.forEach(function (d) { d.LineCategory.forEach(function (b) { b.Date = d.Date; }) }); var Categories = new Array(); // Extension method declaration Categories.pro var Data; var ageNames; var x0 = d3.scale.ordinal() .rangeRoundBands([0, width],.1); var XLine = d3.scale.ordinal() .rangeRoundPoints([0, width], .5); var x1 = d3.scale.ordinal(); var y = d3.scale.linear() .range([height, 0]); var YLine = d3.scale.linear().range([height, 0]) .domain([0, d3.max(Data, function (d) { return d3.max(d.LineCategory, function (b) { return b.Value }) })]); /*var color = d3.scale.ordinal() .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);*/ var line = d3.svg.line().x(function (d) { return x0(d.Date) + x0.rangeBand() / 2; }).y(function (d) { return YLine(d.Value) }); var xAxis = d3.svg.axis() .scale(x0) .orient("bottom"); var yAxis = d3.svg.axis() .scale(y) .orient("left") .tickFormat(d3.format(".2s")); var YLeftAxis = d3.svg.axis().scale(YLine).orient("right").tickFormat(d3.format(".2s")); console.log(YLeftAxis) var svg = d3.select("#graph") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var tip = d3.tip() .attr('class', 'd3-tip') .offset([-10, 0]) .html(function(d) { return "Frequency: <span style='color:red'>Test</span>"; }) svg.call(tip); // Bar Data categories Data.forEach(function (d) { d.Categories.forEach(function (b) { if (Categories.findIndex(function (c) { return c.Name===b.Name}) == -1) { b.Type = "bar"; //console.log(JSON.stringify(b)) Categories.push(b) } }) }); // Line Data categories Data.forEach(function (d) { d.LineCategory.forEach(function (b) { if (Categories.findIndex(function (c) { return c.Name === b.Name }) == -1) { b.Type = "line"; //console.log(JSON.stringify(b)) Categories.push(b) } }) }); // Processing Line data lineData = DataSegregator(Data.map(function (d) { return d.LineCategory }), "Name"); // Line Coloring LineColor = d3.scale.ordinal(); LineColor.domain(Categories.filter(function (d) { return d.Type == "line" }).map(function (d) { return d.Name })); LineColor.range(["#d40606", "#06bf00", "#98bdc5", "#671919", "#0b172b"]) x0.domain(Data.map(function (d) { return d.Date; })); XLine.domain(Data.map(function (d) { return d.Date; })); x1.domain(Categories.filter(function (d) { return d.Type == "bar" }).map(function (d) { return d.Name})).rangeRoundBands([0, x0.rangeBand()]); y.domain([0, d3.max(Data, function (d) { return d3.max(d.Categories, function (d) { return d.Value; }); })]); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); svg.append("g") .attr("class", "y axis") .attr("transform", "translate(" + (width) + ",0)") .call(YLeftAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", -10) .attr("dy", ".71em") .style("text-anchor", "end") .text("Percent"); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Population"); var state = svg.selectAll(".state") .data(Data) .enter().append("g") .attr("class", "state") .attr("transform", function (d) { return "translate(" + x0(d.Date) + ",0)"; }); state.selectAll(".bar") .data(function (d) { return d.Categories; }) .enter().append("rect") //.attr("width", x1.rangeBand()) .attr("class", "bar") .attr("width", x0.rangeBand()) //.attr("x", function (d) { return x1(d.Name); }) .attr("x", 0) .attr("y", function (d) { return y(d.Value); }) .attr("height", function (d) { return height - y(d.Value); }) //.style("fill", function (d) { return color(d.Name); }) .on("click",function(d){console.log(d)}) .on('mouseover', tip.show) .on('mouseout', tip.hide) .transition().delay(500).attrTween("height", function (d) { var i = d3.interpolate(0, height - y(d.Value)); return function (t) { return i(t); } }); // drawaing lines svg.selectAll(".lines").data(lineData).enter().append("g").attr("class", "line") .each(function (d) { Name=d[0].Name d3.select(this).append("path").attr("d", function (b) { return line(b) }).style({ "stroke-width": "2px", "fill": "none" }) .style("stroke", LineColor(Name)).transition().duration(1500); }) //Pointer on line var xdot = d3.time.scale().range([0, width]); var ydot = d3.scale.linear().range([height, 0]); svg.selectAll("dot") .data(lineData) .enter().append("circle") .attr("r", 5) .attr("cx", function(d) { //console.log(d) /*return */; d.forEach(function (a, b) { //console.log((a.Value)) return xdot(a.Value) }) }) .attr("cy", function(d) { /*return YLine(d.Value);*/ d.forEach(function (a, b) { //console.log(ydot(a.Value)) return ydot(a.Value); }) }) .on("mouseover", function(d) { div.transition() .duration(200) .style("opacity", .9); div .html(formatTime(d.date) + "<br/>" + d.close) .style("left", (d3.event.pageX) + "px") .style("top", (d3.event.pageY - 28) + "px"); }) .on("mouseout", function(d) { div.transition() .duration(500) .style("opacity", 0); }); </script> </body>