javascript - Keep legend constant and only update chart in D3 -


my coding plot x axis location, y axis (value1,value2 or value3) , legend types(high, medium,low). i'm trying add menu value1,2,3 , add legend different types if change either menu or click on legend, plot got updated selected data. however, code below able create legend set default type or clicked not able include types. there way include types in legends no matter type clicked , update chart accordingly? thank you,

<script> var margin = {top: 20, right: 20, bottom: 30, left: 40},     width = 960- margin.left - margin.right,     height = 900 - margin.top - margin.bottom,     radius = 3.5,     padding = 1,     xvar = "location",     cvar= " type";     default = "high";   // add tooltip area webpage var tooltip = d3.select("body").append("div")                 .attr("class", "tooltip")                 .style("opacity", 0);   // force data update when menu changed     var menu = d3.select("#menu select")     .on("change", change);  // load data d3.csv("sample.csv", function(error, data) {   formatted = data;    draw(); });   // set terms of transition take place // when new indicator menu or legend chosen    function change() {   //remove old plot , data   var svg = d3.select("svg");       svg.transition().duration(100).remove();    //redraw new plot new data   d3.transition()       .duration(750)       .each(draw) }   function draw() {  // add graph canvas body of webpage  var svg = d3.select("body").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 + ")")     // setup x    var xvalue = function(d) { return d[xvar];}, // data -> value       xscale = d3.scale.ordinal()                        .rangeroundbands([0,width],1),  //value -> display       xmap = function(d) { return (xscale(xvalue(d)) + math.random()*10);},  // data -> display       xaxis = d3.svg.axis().scale(xscale).orient("bottom");    // setup y   var yvar = menu.property("value"),        yvalue = function(d) { return d[yvar];}, // data -> value       yscale = d3.scale.linear().range([height, 0]), // value -> display       ymap = function(d) { return yscale(yvalue(d));}, // data -> display       yaxis = d3.svg.axis().scale(yscale).orient("left");     // setup fill color   var cvalue = function(d) { return d[cvar];},       color  = d3.scale.category10();       // filter unwanted data , plot chosen dataset.  data = formatted.filter(function(d, i)    {            if (d[cvar] == default)            {                return d;            }    });   data = formatted;     // change string (from csv) number format   data.foreach(function(d) {     d[xvar] = d[xvar];     d[yvar] = +d[yvar];   });     xscale.domain(data.sort(function(a, b) { return d3.ascending(a[xvar], b[xvar])})                     .map(xvalue) );   // don't want dots overlapping axis, add in buffer data domain   yscale.domain([d3.min(data, yvalue)-1, d3.max(data, yvalue)+1]);     // x-axis    svg.append("g")       .attr("class", "x axis")       .attr("transform", "translate(0," + height + ")")       .call(xaxis)     .append("text")       .attr("class", "label")       .attr("x", width)       .attr("y", -6)       .style("text-anchor", "end")       .text(xvar);     // y-axis    svg.append("g")       .attr("class", "y axis")       .call(yaxis)     .append("text")       .attr("class", "label")       .attr("transform", "rotate(-90)")       .attr("y", 6)       .attr("dy", ".71em")       .style("text-anchor", "end")       .text(yvar);    // draw dots   var dot = svg.selectall(".dot")       .data(data)       .enter()       .append("circle")       .attr("class", "dot")       .attr("r", radius)       .attr("cx", xmap)       .attr("cy", ymap)       .style("fill", function(d) { return color(cvalue(d));})        .on("mouseover", function(d) {           tooltip.transition()                .duration(200)                .style("opacity", .9);           tooltip.html(d[sn] + "<br/> (" + xvalue(d)            + ", " + yvalue(d) + ")")                .style("left", (d3.event.pagex + 5) + "px")                .style("top", (d3.event.pagey - 28) + "px");       })       .on("mouseout", function(d) {           tooltip.transition()                .duration(500)                .style("opacity", 0);       });    // draw legend    var legend = svg.selectall(".legend")       .data(color.domain().slice())       .enter().append("g")       .attr("class", "legend")       .attr("transform", function(d, i) { return "translate(0," + * 20 + ")"; });    // draw legend colored rectangles   legend.append("rect")       .attr("x", width - 18)       .attr("width", 18)       .attr("height", 18)       .style("fill", color)        .on("click", function (d){         default = d;         return change();       });    // draw legend text   legend.append("text")       .attr("x", width - 24)       .attr("y", 9)       .attr("dy", ".35em")       .style("text-anchor", "end")       .text(function(d) { return d;})       .on("click", function (d) {         default = d;         return change();       });  };  </script> </body> 

sample.csv

 location type value1   value2   value3         high    1      -2        -5  b        medium  2       3         4  c        low     4       1         2  c        medium  6       3         4         high    4       5         6  d        low     -1      3         2 

i found way include types in legend. first, extract unique types column "type" , save them in "legend_keys" array. second, instead of pre-define "default", set first type in "legend_keys" default. next default set event on click out of legend.

d3.csv("sample.csv", function(error, data) {   formatted = data;   var nest = d3.nest()     .key(function(d) { return d[cvar]; })     .entries(formatted);    console.log(nest);    legend_keys = nest.map(function(o){return o.key});   default = legend_keys[0];   //console.log(legend_keys[0]);   draw(); }); 

finally, when define legend, read "legend_keys" data below. doing this, can keep types in legend.

 var legend = svg.selectall(".legend")       .data(legend_keys)       .enter().append("g")       .attr("class", "legend")       .attr("transform", function(d, i) { return "translate(0," + * 20 + ")"; })       .on("click", function (d){         default = d;         console.log(default);         return change();       }); 

Comments

Popular posts from this blog

php - How to display all orders for a single product showing the most recent first? Woocommerce -

asp.net - How to correctly use QUERY_STRING in ISAPI rewrite? -

angularjs - How restrict admin panel using in backend laravel and admin panel on angular? -