Interaktive Graphen mit d3.js

Im Beispiel verwenden wir ein kleines php Skript um für eine gewählte Zeitspanne zufällige Werte mittels Ajax zu senden.

Die X-Achse wird mit der Zeitspanne belegt und die Y Achse mit den zufällig erstellten Werten.

  • d3.js 3.5.3

up
vorher
nachher
var url = '/fileadmin/getData.php'; var margin = {top: 30, right: 30, bottom: 60, left: 50} // Wir verwende JQuery um die breite des divs und somit des Graphen zu ermitteln var width = $('#graph').width() - margin.left - margin.right; // Die haelfte von der Gesamthoehe des Bildschirms verwenden wir fuer die hoehe var height = ($( document ).height() /2) - margin.top - margin.bottom; // Wir verraten D3.js Das verwendete Datumformat var format = d3.time.format("%d.%m.%Y"); // fuer die X - Achse verwenden wir eine verkuerzte form var axisformat = d3.time.format("%d.%m"); // eine Funktion um den Wert aus unser Dataset zu holen var valueFn = function(d) { return d.value } // und eine Funktion um das Datum zu parsen var dateFn = function(d) { return format.parse(d.date) } // var x = d3.time.scale().range([0, width]); // Eine D3 scale funktion, damit unsere Werte relative Pixelangaben werden // Beachte, dass wir Scale hier verwenden um unsere Y Werte umzudrehen // Im SVG Element ist Y=0 oben und waechst nach unten, damit wir Y=0 unten bekommen, drehen wir unseren Scale um var y = d3.scale.linear().range([height, 0]); // var z = d3.scale.category10(); // Die Definition der Achsen // Hier ist zu beachten, das ticks(10) bloss als Empfehlung gewertet wird von D3.js var xAxis = d3.svg.axis().scale(x).tickFormat(axisformat).orient("bottom").ticks(7); var yAxis = d3.svg.axis().scale(y).orient("left"); // Wir erstellen nun unser SVG Element und geben es eine id #chart // Dann ein Gruppen Element g mit id #innerchart und schieben dieses zurecht mit unseren Margins var chart = d3.select('#graph').append('svg') .style('width', (width + margin.left + margin.right) + 'px') .style('height', height + margin.top + margin.bottom + 'px') .attr('id','chart') .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")") .attr('id','innerchart'); // Fuegen die X Achse ein und drehen unsere Datum Angaben damit diese schoen passen chart.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis) .selectAll("text") .style("text-anchor", "end") .attr("dx", "-.8em") .attr("dy", ".15em") .attr("transform", function(d) { return "rotate(-65)" });; // Fuegen die Y Achse ein chart.append("g") .attr("class", "y axis") .call(yAxis); // die Funktion fuer unser "linie" var line = d3.svg.line() .interpolate("basis") .x(function(d) { return x(dateFn(d)); }) .y(function(d) { return y(valueFn(d)); }) function updateChart(data){ // Zuerst bestimmen wir die Domain des Datensets // Wir koennen hier stattdessen auch extent verwenden aber zur verdeutlichung verwenden wir min und max var date_min = d3.min(data, function(d) { return dateFn(d) }); var date_max = d3.max(data, function(d) { return dateFn(d) }); var value_max = d3.max(data, function(d){ return valueFn(d) }); var value_min = d3.min(data, function(d){ return valueFn(d) }); // nun verwenden wir unsere minimum und maximum Werte und legen unsere Domains fest x.domain([date_min, date_max]); y.domain([value_min, value_max]); // Generelle update Strategie von d3.js var path = chart.selectAll("path.linegraph") .data( [data]); // Neue Daten hinzufuegen path.enter() .append("path") .attr("class","linegraph") .attr("d", function(d) {return line(d);}) .style("stroke", function(d,i) { return z(i); }); // vorhandene Daten aktualisieren path .transition() .duration(500) .attr("d", function(d) { return line(d);}); //unbenoetigte Daten (die nicht mehr im Dataset sind) entfernen path.exit() .transition() .duration(200) .style("stroke-opacity", 1e-6) .remove(); // Achsen aktualisieren var svg = d3.select('#innerchart').transition(); svg.select(".y.axis") .duration(500) .call(yAxis); svg.select(".x.axis") .duration(500) .call(xAxis); }

Ein Beispielhafter Ausschnitt vom Dataset

[{"date":"19.12.2021","value":93},{"date":"20.12.2021","value":89},{"date":"21.12.2021","value":4},{"date":"22.12.2021","value":39},{"date":"23.12.2021","value":100},{"date":"24.12.2021","value":55},{"date":"25.12.2021","value":80},{"date":"26.12.2021","value":49},{"date":"27.12.2021","value":33},{"date":"28.12.2021","value":51},{"date":"29.12.2021","value":77},{"date":"30.12.2021","value":17},{"date":"31.12.2021","value":83},{"date":"01.01.2022","value":2},{"date":"02.01.2022","value":87},{"date":"03.01.2022","value":61},{"date":"04.01.2022","value":50},{"date":"05.01.2022","value":90},{"date":"06.01.2022","value":23},{"date":"07.01.2022","value":75},{"date":"08.01.2022","value":29},{"date":"09.01.2022","value":36},{"date":"10.01.2022","value":35},{"date":"11.01.2022","value":61},{"date":"12.01.2022","value":47},{"date":"13.01.2022","value":33},{"date":"14.01.2022","value":54},{"date":"15.01.2022","value":47},{"date":"16.01.2022","value":55},{"date":"17.01.2022","value":48},{"date":"18.01.2022","value":21},{"date":"19.01.2022","value":48}]