2013-02-08 4 views
6

Ich bin seit ein paar Wochen dabei und kann nicht herausfinden, wie man das untere Diagramm mit mehreren Pfaden zeichnet. Focus+Context via Brushing chartProbleme beim Zeichnen von d3.js Focus + Context über das Brushing-Diagramm mit mehreren Pfaden

Ich habe versucht, eine jsfiddle zu erstellen, aber war nicht in der Lage, den Bildschirm zu replizieren, den ich bekomme. An diesem Punkt ist das, was ich habe, ähnlich dem ursprünglichen Diagramm nur mit einem Pfad statt Fläche und das Bürsten funktioniert. Grundsätzlich versuchen, das Fokusdiagramm und Multi-Series Liniendiagramm Multiseries chart zu kombinieren.

Wenn ich jedoch versuche, einen anderen Pfad hinzuzufügen, funktioniert nichts. Bitte schlagen Sie Ideen oder Änderungen vor, die ich treffen muss, damit es funktioniert. Außerdem gibt es noch andere ähnliche Diagramme (oder Chart-Beispiele), die ich betrachten kann. Die Daten könnten in irgendeiner Art und Weise neu angeordnet werden, damit dies funktioniert.

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

I 3 Bereiche zeichnen konnte drei Datensätze zu replizieren übereinander, aber nicht in der Lage, alle drei zu "bürsten". Es funktioniert nur mit einem Bereich. Kann "putzen" an drei Bereichen gleichzeitig arbeiten? Wie kann das codiert werden? –

Antwort

10

Wie pro Ihren Kommentar, waren Sie die drei Bereiche zeichnen können, hatte aber Schwierigkeiten in sie bürsten. Ich habe ein Arbeitsbeispiel hier: http://jsfiddle.net/BVzyq/1/ wobei ich drei <path> Elemente entsprechend den drei Farben in den Daten hinzugefügt habe: ['red', 'yellow', 'green'].

ich die Funktionen abstrahiert aus, die in einer Farbe nehmen und geben die entsprechenden d Wert:

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

Sie können weiter abstrahiert werden, aber diese sind am nächsten zu dem Code, den Sie geschrieben haben. Diese Funktionen verwendet werden, während die Pfade zu schaffen:

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

Die CSS-Klassen diese Form vorzuschlagen schien Daten beizutreten. Ich fügte auch eine weitere Klasse data zu den Pfaden hinzu, die den Zeitreihendiagrammen entsprechen. Dies macht es einfach, diese <path> s von denen zu unterscheiden, die für die Achse vorgesehen sind.

schließlich in der Bürstenfunktion, neu berechnen die d Attribut für alle path.data Elemente:

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

Bitte beachte, dass ich einige der Werte in data verändert alle drei Farben sichtbar zu machen.

+2

Awesome, du verdienst eine Medaille Kumpel. – Melki

2

Große Lösung musikalisch_ut, für andere mit einem ähnlichen Problem. Ich konnte zusätzliche csvs laden, wie das Beispiel in diesem Link - Focus+Context via Brushing, aber ich war wirklich damit beschäftigt, alle Linien zusammen zu bürsten, obwohl beide richtig im Bereich und Bereich2 gerendert wurden.

Es stellte sich heraus, Ihren Code sah, alles, was ich tun musste, war Fokus zu ändern.Wählen Sie Fokus.Wählen Sie wie Sie haben. Vielen Dank!

Und für jedermann mit dem ursprünglichen Tutorial Code arbeiten, können Sie alternative csv nur hinzufügen, sind durch Kopieren Sie den folgenden Code und die auf Ihre neue 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); 
    });