Avoir des difficultés à dessiner d3.js Focus + Contexte via le tableau de brossage avec plusieurs chemins

Je l'ai été pendant quelques semaines et je ne peux pas comprendre comment dessiner le graphique ci-dessous avec de multiples chemins. Focus + Contexte via le tableau de brossage

J'ai essayé de créer un jsfiddle mais je n'ai pas réussi à reproduire l'écran que je reçois. À ce stade, ce que j'ai est semblable au tableau d'origine simplement avec un chemin au lieu de la zone et les travaux de brossage. En essayant fondamentalement de combiner le diagramme Focus et le diagramme Multiseries Multi-Series Line Chart.

Cependant, lorsque j'essaie d'ajouter un autre chemin, rien ne fonctionne. Veuillez suggérer des idées ou des modifications que je dois faire pour que cela fonctionne. Existe-t-il également d'autres graphiques similaires (ou exemples de graphiques) que je peux regarder. Les données pourraient être réarrangées de quelque manière que ce soit ou pour qu'elles fonctionnent.

Jsfiddle

<div id='dashboardChart'> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="svg"> </div> 

 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(); 

Selon votre commentaire, vous avez pu tracer les trois zones, mais ont eu du mal à les brosser . J'ai un exemple de travail ici: http://jsfiddle.net/BVzyq/1/ où, j'ai ajouté trois éléments <path> correspondant aux trois couleurs des données: ['red', 'yellow', 'green'] .

J'ai supprimé les fonctions qui pourraient prendre une couleur et renvoyer la valeur d appropriée:

 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]); }); }; 

Ils peuvent être abstraits davantage, mais ceux-ci sont les plus proches du code que vous avez écrit. Ces fonctions sont utilisées lors de la création des chemins:

 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; }); 

Les classes CSS semblent suggérer cette forme de données-join. J'ai également ajouté une autre data classe aux chemins qui correspondent aux parcelles de séries temporelles. Cela permet de distinguer facilement ces <path> s de ceux destinés à l'axe.

Enfin, dans la fonction brush, recalculer l'attribut d pour tous les éléments path.data :

 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); } 

Notez que j'ai changé certaines des valeurs dans les data pour rendre visibles toutes les trois couleurs.

Une grande solution musicalement, mais d'autres ont un problème similaire. J'ai pu charger des csv supplémentaires, comme l'exemple trouvé dans ce lien – Focus + Context via Brushing, mais a été vraiment accroché à la façon de brosser toutes les lignes ensemble, même si elles étaient toutes deux en cours de rendu dans la zone et la zone2.

S'arrête, en regardant votre code, tout ce que j'ai dû faire était de changer focus.select pour focus.selectAll like you have. Merci!

Et pour toute personne qui travaille avec le code de tutoriel d'origine, vous pouvez ajouter d'autres csv simplement en copiant le code suivant et en indiquant votre nouveau 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); });