无法通过具有多个路径的刷新图表绘制d3.js Focus + Context

我已经使用了几个星期,似乎无法弄清楚如何用多条路径绘制下面的图表。 通过刷新图表聚焦+上下文

我试图创建一个jsfiddle,但无法复制我得到的屏幕。 此时我所拥有的与原始图表类似,只有一条路径而不是区域和刷子工作。 基本上尝试结合Focus图表和Multi-Series折线图Multiseries图表 。

但是当我尝试添加另一条路径时,没有任何作用。 请提出我需要做的任何想法或更改才能使其发挥作用。 还有我可以看到的任何其他类似的图表(或图表exaples)。 可以以任何方式或forms重新排列数据以使其工作。

的jsfiddle


 path { fill:none; stroke:white; stroke-width:2px; } .axis path, .axis line { fill: none; stroke: #CCC; shape-rendering: crispEdges; } .brush .extent { stroke: #fff; fill-opacity: .125; shape-rendering: crispEdges; } .path_green { stroke:green; } .path_red { stroke:red; } .path_yellow { stroke:yellow; } 

 function drawChart() { var margin = { top: 5, right: 10, bottom: 100, left: 50 }, margin2 = { top: 200, right: 10, bottom: 20, left: 50 }, width = 1075 - margin.left - margin.right, height = 280 - margin.top - margin.bottom, height2 = 280 - 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 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", brush); var area = d3.svg.area() .interpolate("monotone") .x(function (d) { return x(d.date); }) .y0(height) .y1(function (d) { return y(d.red); }); var area2 = d3.svg.area() .interpolate("monotone") .x(function (d) { return x2(d.date); }) .y0(height2) .y1(function (d) { return y2(d.red); }); var svg = d3.select("#dashboardChart #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 + ")"); var data = [{ "date": "2013-02-08T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 1 }, { "date": "2013-02-07T05:00:00.000Z", "data": null, "red": 485, "yellow": 0, "green": 491 }, { "date": "2013-02-06T05:00:00.000Z", "data": null, "red": 2884, "yellow": 0, "green": 2881 }, { "date": "2013-02-05T05:00:00.000Z", "data": null, "red": 3191, "yellow": 0, "green": 3188 }, { "date": "2013-02-04T05:00:00.000Z", "data": null, "red": 180, "yellow": 0, "green": 184 }, { "date": "2013-02-03T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 0 }, { "date": "2013-02-02T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 0 }, { "date": "2013-02-01T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 0 }, { "date": "2013-01-31T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 0 }, { "date": "2013-01-30T05:00:00.000Z", "data": null, "red": 1, "yellow": 0, "green": 0 }, { "date": "2013-01-29T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 2 }, { "date": "2013-01-28T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 0 }, { "date": "2013-01-27T05:00:00.000Z", "data": null, "red": 1, "yellow": 1, "green": 1 }, { "date": "2013-01-26T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 1 }, { "date": "2013-01-25T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 0 }, { "date": "2013-01-24T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 0 }, { "date": "2013-01-23T05:00:00.000Z", "data": null, "red": 49, "yellow": 0, "green": 45 }, { "date": "2013-01-22T05:00:00.000Z", "data": null, "red": 59, "yellow": 0, "green": 64 }, { "date": "2013-01-21T05:00:00.000Z", "data": null, "red": 119, "yellow": 1, "green": 125 }, { "date": "2013-01-20T05:00:00.000Z", "data": null, "red": 0, "yellow": 1, "green": 0 }, { "date": "2013-01-19T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 0 }, { "date": "2013-01-18T05:00:00.000Z", "data": null, "red": 84, "yellow": 0, "green": 81 }, { "date": "2013-01-17T05:00:00.000Z", "data": null, "red": 76, "yellow": 1, "green": 77 }, { "date": "2013-01-16T05:00:00.000Z", "data": null, "red": 0, "yellow": 1, "green": 0 }, { "date": "2013-01-15T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 0 }, { "date": "2013-01-14T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 0 }, { "date": "2013-01-13T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 0 }, { "date": "2013-01-12T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 0 }, { "date": "2013-01-11T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 0 }, { "date": "2013-01-10T05:00:00.000Z", "data": null, "red": 0, "yellow": 0, "green": 0 }]; x.domain(d3.extent(data.map(function (d) { return d.date; }))); y.domain([0, d3.max(data.map(function (d) { return d.red; }))]); x2.domain(x.domain()); y2.domain(y.domain()); focus.append("path") .datum(data) .attr("clip-path", "url(#clip)") .attr("d", area) .attr("class", "path_red"); focus.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis); focus.append("g") .attr("class", "y axis") .call(yAxis); context.append("path") .datum(data) .attr("d", area2) .attr("class", "path_red"); 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); function brush() { x.domain(brush.empty() ? x2.domain() : brush.extent()); focus.select("path").attr("d", area); focus.select(".x.axis").call(xAxis); } } drawChart(); 

根据你的评论,你能够绘制三个区域,但很难它们。 我在这里有一个工作示例: http : //jsfiddle.net/BVzyq/1/其中,我添加了三个元素对应于数据中的三种颜色['red', 'yellow', 'green']

我抽象出了可以采用颜色并返回适当d值的函数:

 var area = function (color) { return d3.svg.area() .interpolate("monotone") .x(function (d) { return x(d.date); }) .y0(height) .y1(function (d) { return y(d[color]); }); }; var area2 = function (color) { return d3.svg.area() .interpolate("monotone") .x(function (d) { return x2(d.date); }) .y0(height2) .y1(function (d) { return y2(d[color]); }); }; 

它们可以进一步抽象,但这些最接近您编写的代码。 创建路径时使用这些函数:

 focus.selectAll('path') .data(['red', 'yellow', 'green']) .enter() .append('path') .attr('clip-path', 'url(#clip)') .attr('d', function (col) { return area(col)(data); }) .attr('class', function (col) { return "path_" + col + " data"; }); // ... context.selectAll('path') .data(['red', 'yellow', 'green']) .enter() .append('path') .attr('d', function (col) { return area2(col)(data); }) .attr('class', function (col) { return "path_" + col; }); 

CSS类似乎暗示了这种forms的数据连接。 我还在路径中添加了另一个类data ,这些data对应于时间序列图。 这使得很容易将这些与那些用于轴的区分开来。

最后,在brush函数中,重新计算所有path.data元素的d属性:

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

请注意,我更改了data一些值,以使所有三种颜色可见。

很好的解决方案musically_ut,对于其他有类似问题的人。 我能够加载额外的csv,就像在这个链接中找到的例子 – 通过刷子聚焦+上下文但是真的挂了如何将所有线条刷在一起,即使它们都在区域和区域2中正确渲染。

事实certificate,看看你的代码,我所要做的就是改变focus.select to focus.select就像你一样。 谢谢!

对于使用原始教程代码的任何人,只需复制以下代码并指向新的csv即可添加备用csv:

 d3.csv("sp501.csv", function(error, data) { data.forEach(function(d) { d.date = parseDate(d.date); d.price = +d.price; }); x.domain(d3.extent(data.map(function(d) { return d.date; }))); y.domain([0, d3.max(data.map(function(d) { return d.price; }))]); x2.domain(x.domain()); y2.domain(y.domain()); focus.append("path") .datum(data) .attr("clip-path", "url(#clip)") .attr("d", area) .attr("class", "timeLine2"); context.append("path") .datum(data) .attr("class", "timeLine2") .attr("d", area2); context.append("g") .attr("class", "x axis2") .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); });