J'ai tenté de placer des points (éventuellement avec des infobulles de survol) à chaque point de données d'un graphique chronologique. La partie multiligne est basée sur this example et crée une fonction appelée draw() qui dessine le graphique en utilisant des générateurs externes d3.line()
. J'essaie de créer des points de dispersion sur les points de données où les données de température et le temps se croisent - ce qui fonctionne sur les lignes mais pas sur mes ellipses, et je ne suis pas sûr de ce que je fais mal.Diagramme de dispersion D3 sur le graphique linéaire multi-lignes de série temporelle
The failing scatterplot attempt is here.
Quelle est la meilleure façon de faire les cercles se chevauchent les points de données? L'erreur que je reçois dans le débogueur JavaScript est
d3.v4.js:1381 Error: <circle> attribute cx: Expected length, "NaN".
d3.v4.js:1381 Error: <circle> attribute cy: Expected length, "NaN".
L'analyse des données semble fonctionner correctement avec les intersections de la ligne, mais pas le cx et les coordonnées cy.
JavaScript pour ne pas avoir tentative ci-dessous:
// set the dimensions and margins of the graph
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// parse the date/time
var parseDate = d3.timeParse("%Y-%m-%d %H:%M:%S");
var formatTime = d3.timeFormat("%e %B");
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
// define the div for the tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
var tempprobe_line = d3.line()
.x(function(d) { return x(d.timestamp); })
.y(function(d) { return y(d.tempprobe); });
var high_threshold_line = d3.line()
.x(function(d){ return x(d.timestamp); })
.y(function(d){ return y(d.threshold_high); });
var low_threshold_line = d3.line()
.x(function(d){
return x(d.timestamp);
})
.y(function(d){
return y(d.threshold_low);
})
var ambient_line = d3.line()
.x(function(d)
{ return x(d.timestamp);}
)
.y(function(d) {
return y(d.ambient);
});
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
function draw(data, tempdata) {
var data = data[tempdata];
data.forEach(function(d, i) {
d.timestamp = parseDate(d.timestamp);
d.tempprobe = +d.tempprobe;
d.ambient = +d.ambient;
});
data.sort(function(a, b){
return a["timestamp"]-b["timestamp"];
});
// scale the range of data
x.domain(d3.extent(data, function(d){
return d.timestamp;
}));
y.domain([0, d3.max(data, function(d){
return Math.max(d.tempprobe, d.ambient);
})]);
// Add the tempprobe path.
svg.append("path")
.data([data])
.attr("class", "line temp-probe temperature")
.attr("d", tempprobe_line);
// Add the ambient path
svg.append("path")
.data([data])
.attr("class", "line ambient temperature")
.attr("d", ambient_line);
svg.append("path")
.data([data])
.attr("class", "line high-threshold")
.attr("d", high_threshold_line)
svg.append("path")
.data([data])
.attr("class", "line low-threshold")
.attr("d", low_threshold_line)
// add the X Axis
svg.append("g")
.attr("transform", "translate(0,"+ height + ")")
.call(d3.axisBottom(x));
// add the Y Axis
svg.append("g")
.call(d3.axisLeft(y));
}
d3.json("temp_data.json",
function(error, data){
if (error){
throw error;
}
draw(data[0], "tempdata");
// Add the scatterplot -- the failing part
svg.selectAll("dot")
.data(data)
.enter().append("circle")
.attr("r", 3.5)
.attr("cx", function(d) { return x(d.timestamp); })
.attr("cy", function(d) { return y(d.tempprobe); });
});
Quelqu'un peut-il expliquer ce que le modèle utilisé pour générer des lignes est un.) Appelé? et b.) comment je peux reproduire cette méthodologie pour générer des cercles (points) comme le nuage de points? Si j'ai besoin d'ouvrir une nouvelle question, j'en suis ravi, mais j'aimerais au moins utiliser le bon nom de modèle. – Smittles
Je ne suis pas entièrement sûr. Il semble que vous définissiez la logique de dessin au trait dans une fonction, puis appelez cela avec vos données. Je pense que l'important est de comprendre quel objet de données chaque appel à '.data' devrait prendre. Si cela peut vous aider, je trouve que l'utilisation de Chrome Devtools et l'établissement de points de rupture pour inspecter les variables à divers points peuvent être très instructifs. –