Combining Chart by Region and Scavenging in D3

I'm struggling to take the area-broken chart in D3 and add clean up functions. I managed to create both large (focus) and small (context) axes, and the plot looks great to get started. My problems are that the cleaning functions do not work at all. Iโ€™ve been knocking on this head for several seconds, to no avail, and I canโ€™t understand where the problem is. Any help would be greatly appreciated!

Click here to see the current state of the chart. Here is the code:

<!-- language: lang-js --> <!DOCTYPE html> <meta charset="utf-8"> <style> body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .tag text { text-anchor: end; } </style> <body onLoad="updateData()"> <div id="option" style="font-size:14px;"> <form> Number of tags:<input value="5" id="nTags_select"></input> <input name="updateButton" type="button" value="Update" onclick="updateData()" /> </form> </div> <script src="http://d3js.org/d3.v3.js"></script> <script> var margin = {top: 10, right: 10, bottom: 100, left: 40}, margin2 = {top: 430, right: 10, bottom: 20, left: 40}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom, height2 = 500 - margin2.top - margin2.bottom; var parseDate = d3.time.format("%Y-%m-%d").parse; var x = d3.time.scale().range([0, width]), x2 = d3.time.scale().range([0, width]), y = d3.scale.linear().range([height, 0]), y2 = d3.scale.linear().range([height2, 0]); var color = d3.scale.category20(); var xAxis = d3.svg.axis().scale(x).orient("bottom"), xAxis2 = d3.svg.axis().scale(x2).orient("bottom"), yAxis = d3.svg.axis().scale(y).orient("left"); var brush = d3.svg.brush() .x(x2) .on("brush", brushed); var area = d3.svg.area() .interpolate("basis") .x(function(d) { return x(d.date); }) .y0(function(d) { return y(d.y0); }) .y1(function(d) { return y(d.y0 + dy); }); var area2 = d3.svg.area() .interpolate("basis") .x(function(d) { return x2(d.date); }) .y0(function(d) { return y2(d.y0); }) .y1(function(d) { return y2(d.y0 + dy); }); var stack = d3.layout.stack() .values(function(d) { return d.values; }); var oRequest = new XMLHttpRequest(); var sURL = "data100.tsv"; oRequest.open("GET",sURL,false); oRequest.setRequestHeader("User-Agent",navigator.userAgent); oRequest.send(null) var data = oRequest.responseText; var data = d3.tsv.parse(data); data.forEach(function(d) { d.date = parseDate(d.date); }); color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; })); var allTags = stack(color.domain().map(function(name) { return { name: name, values: data.map(function(d) { return {date: d.date, y: +d[name]}; }) }; })); function updateData(){ var nTags = document.getElementById('nTags_select').value; tags=allTags.slice(0,nTags); x.domain(d3.extent(data, function(d) { return d.date; })); y.domain([0,d3.max(tags, function(d) { return d3.max(d.values, function (d) { return dy + d.y0; }); })]); x2.domain(x.domain()); y2.domain(y.domain()); d3.select("svg").remove(); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) svg.append("defs").append("clipPath") .attr("id", "clip") .append("rect") .attr("width", width) .attr("height", height); var focus = svg.append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var context = svg.append("g") .attr("transform", "translate(" + margin2.left + "," + margin2.top + ")"); focus.selectAll('path') .data(tags) .enter() .append('path') .attr('clip-path','url(#clip)') .attr("d", function(d) { return area(d.values); }) .attr('class','focus') .style("fill", function(d) { return color(d.name); }); focus.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); focus.append("g") .attr("class", "y axis") .call(yAxis); context.selectAll('path') .data(tags) .enter() .append('path') .attr('class','context') .attr("d", function(d) { return area2(d.values); }) .style("fill", function(d) { return color(d.name); }); context.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height2 + ")") .call(xAxis2); context.append("g") .attr("class", "x brush") .call(brush) .selectAll("rect") .attr("y", -6) .attr("height", height2 + 7); focus.append("text") .datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; }) .attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.y0 + d.value.y / 2) + ")"; }) .attr("x", -6) .attr("dy", "-.35em") .text(function(d) { return d.name; }); }; function brushed() { x.domain(brush.empty() ? x2.domain() : brush.extent()); focus.selectAll("path.focus").attr("d", area); focus.select(".x.axis").call(xAxis); } </script> 
+4
source share
1 answer

In the original Mike code, he chose the name focus for his svg element, which is unhappy - it already exists in the dom and can be confusing questions.

In any case, the problem here primarily relates to the scope.

Mike defines focus outside the scope of the data acquisition, thereby placing it in the global scope. Therefore, it is available for the brushed() function.

The first step I would take would be to move the focus var definition outside of the updateData () function.

However, there are a few more problems:

  • You must use d3.tsv with an anonymous function to get the data. This will simplify the situation.
  • In a matte function, you need to use an anonymous function and pass the function to the d.values โ€‹โ€‹area, not just d. You did this in the updateData function, but not in the brush. those.:

     function brushed() { x.domain(brush.empty() ? x2.domain() : brush.extent()); focus.selectAll("path.focus").attr("d", function(d){return area(d.values)}); focus.select(".x.axis").call(xAxis); } 

I have a rough version of your diagram with a brush working here: http://jsfiddle.net/zQ2EF/ , but I would carefully consider Mikeโ€™s example where things are defined and in what area they are - this will help you understand what the problem is !

+3
source

All Articles