so, code here if want check out.
anyway, i'm developing multi-line graph tooltips , legend has each line disappear click. issue is, lines don't want generate inside loop (in case, datanest) let me create unique id each line.
this code need working inside loop:
svg.append("path") .attr("class", "line") .style("stroke", function() { // add colours dynamically return d.color = color(d.key); }) .attr("id", 'tag'+d.key.replace(/\s+/g, '')) // assign id .attr("d", line(d.values));
nesting data d3.nest() using key() give different data structure datanest.
nest.key(function)
...each time key registered, pushed onto end of internal keys array, , resulting map or entries have additional hierarchy level.
so have call line when filling d attribute .attr("d", line(d.values[0].values)) .
here examples on how d3.nest() works.
function init(){ var data = [ { "label":"internal", "values":[ {"week":1,"val":37}, {"week":2,"val":38}, {"week":3,"val":33}, {"week":4,"val":32}, {"week":5,"val":40}, {"week":6,"val":27}, {"week":7,"val":30}, {"week":8,"val":37}, {"week":9,"val":42}, {"week":10,"val":36}, {"week":11,"val":35}, {"week":12,"val":37}, {"week":13,"val":33} ] }, { "label": "high", "values": [ {"week":1,"val":41}, {"week":2,"val":41}, {"week":3,"val":41}, {"week":4,"val":39}, {"week":5,"val":41}, {"week":6,"val":49}, {"week":7,"val":38}, {"week":8,"val":42}, {"week":9,"val":51}, {"week":10,"val":38}, {"week":11,"val":48}, {"week":12,"val":50}, {"week":13,"val":40}, ] }, { "label": "low", "values":[ {"week":1,"val":16}, {"week":2,"val":17}, {"week":3,"val":14}, {"week":4,"val":15}, {"week":5,"val":18}, {"week":6,"val":20}, {"week":7,"val":18}, {"week":8,"val":14}, {"week":9,"val":14}, {"week":10,"val":19}, {"week":11,"val":21}, {"week":12,"val":16}, {"week":13,"val":17}, ], }, { "label":"average", "values":[ {"week":1,"val":28.5}, {"week":2,"val":29}, {"week":3,"val":27.5}, {"week":4,"val":27}, {"week":5,"val":29.5}, {"week":6,"val":34.5}, {"week":7,"val":28}, {"week":8,"val":28}, {"week":9,"val":32.5}, {"week":10,"val":28.5}, {"week":11,"val":34.5}, {"week":12,"val":33}, {"week":13,"val":28.5} ] } ] var margin = { top: 20, right: 80, bottom: 60, left: 50 }, width = 895 - margin.left - margin.right, height = 355 - margin.top - margin.bottom; var x = d3.scale.ordinal(); var y = d3.scale.linear() .range([height, 0]); var color = d3.scale.category20(); var xaxis = d3.svg.axis() .scale(x) .orient("bottom") .ticks(6) .ticksize(0); var yaxis = d3.svg.axis() .scale(y) .orient("left") .ticksize(0); var line = d3.svg.line() .x(function (d) {return x(d.week);}) .y(function (d) {return y(d.val);}) .interpolate("linear"); // define 'div' tooltips var div = d3.select('#multiline').append("div") // declare properties div used tooltips .attr("class", "tooltip") // apply 'tooltip' class .style("opacity", 0); // var svg = d3.select('#multiline').append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); color.domain(data.map(function (d) { return d.label; })); data.foreach(function (kv) { var labelname = kv.label; kv.values.foreach(function (d) { d.val = +d.val; d.label = labelname; }); }); var datanest = d3.nest() .key(function(d) {return d.label;}) .entries(data); function make_y_axis() { // function y grid lines return d3.svg.axis() .scale(y) .orient("left") .ticks(10) } var miny = d3.min(data, function (kv) { return d3.min(kv.values, function (d) { return d.val; }) }); var maxy = d3.max(data, function (kv) { return d3.max(kv.values, function (d) { return d.val + 5; }) }); var padding = width/(data[0].values.length + 1)/2; x.domain(data[0].values.map(function (d) { return d.week; })) .rangepoints([padding, width-padding]); y.domain([0, 1.3*(maxy)]); svg.append("svg:rect") // grid lines bakcground .attr("x", 0) .attr("y", 0) .attr("height", height) .attr("width", width) .attr("fill", "#e6e6e6") .style("opacity", "0.3"); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xaxis); 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"); svg.append("g") // draw y grid lines .attr("class", "grid") .call(make_y_axis() .ticksize(-width, 0, 0) .tickformat("") ); var city = svg.selectall(".branch") .data(data) .enter().append("g") .attr("class", "branch"); city.append("path") .attr("class", "line") .attr("d", function (d) { return line(d.values); }) .style("stroke", function (d) { return color(d.label); }) .style("fill", "none") .style("stroke-width", 3); svg.selectall("g.dot") .data(data) .enter().append("g") .attr("class", "dot") .selectall("circle") .data(function(d) { return d.values; }) .enter().append("circle") .attr("r", 2) .attr("cx", function(d,i) { return x(d.week); }) .attr("cy", function(d,i) { return y(d.val); }) .style("stroke", function (d) { return color(d.label); }) .style("fill", "none") .style("stroke-width", 3) // tooltip stuff after .on("mouseover", function(d) { // when mouse goes on circle, following div.transition() // declare transition properties bring fade-in div .duration(200) // shall take 200ms .style("opacity", .9); // , go way opacity of .9 div .html(d.label + "<br/>" + d.week + "<br/>" + d.val) // add text of tooltip html .style("left", (d3.event.pagex) + "px") // move in x direction .style("top", (d3.event.pagey - 28) + "px"); // move in y direction }) // .on("mouseout", function(d) { // when mouse leaves circle, following div.transition() // declare transition properties fade-out div .duration(500) // shall take 500ms .style("opacity", 0); // , go way opacity of nil }); legendspace = width/datanest.length; // spacing legend // loop through each symbol / key datanest.foreach(function(d,i) { svg.append("path") .attr("class", "line") .attr("d", line(d.values[0].values)) .attr("id", 'tag'+d.key.replace(/\s+/g, '')) .style("stroke", color(d.label)) .style("fill", "none") .style("stroke-width", 3); // add legend svg.append("text") .attr("x", (legendspace/2)+i*legendspace) // space legend .attr("y", height + (margin.bottom/2)+ 20) .attr("class", "legend") // style legend .style("fill", function() { // add colours dynamically return d.color = color(d.key); }) .on("click", function(){ // determine if current line visible var active = d.active ? false : true, newopacity = active ? 0 : 1; // hide or show elements based on id d3.select("#tag"+d.key.replace(/\s+/g, '')) .transition().duration(100) .style("opacity", newopacity); // update whether or not elements active d.active = active; }) .text(d.key); }); } init(); .axis path, .axis line { fill: none; shape-rendering: crispedges; stroke: none; } .axis line{ fill:none; shape-rendering: crispedges; stroke:grey; } .grid .tick { stroke: grey; opacity: 0.5 !important; } .bar rect { fill: #ed1e79; } .bar text.value { fill: black; } circle { fill: blue; stroke: blue; stroke-width: 2; } .tooltip { background: none repeat scroll 0 0 #ed1e79; border: 0 solid #ffffff; border-radius: 8px; color: #ffffff; font: 12px sans-serif; height: 38px; padding: 2px; pointer-events: none; position: absolute; text-align: center; width: 90px; } <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <div id="multiline"></div>
Comments
Post a Comment