Reputation: 316
I'm pretty new to D3 and I'm stuck right now in a particular subject that I suppose it's very basic. I've been researching the whole day for something that could help me but everything I've found ended up not being exactly what I need, anyway I apologize from now if it has already been asked.
Basically, I've been creating scatterplots using arrays so far, like:
var dataset = [[100,220],[130,350],[70,60],[100,140],[520,300],[120,280],[390,170]];
And then:
var chart = d3.select("body")
.append("svg")
.attr("width",w)
.attr("height",h);
var plot = chart
.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx",function(d){return d[0];})
.attr("cy",function(d){return d[1];})
.attr("r",function(d,i){return i*4});
If now I want to work with a dataset made of objects instead of arrays it does still work fine with a few adjustments:
var dataset = [
{x:100,y:220},
{x:130,y:350},
{x:70,y:60},
{x:100,y:140},
{x:520,y:300},
{x:120,y:280},
{x:390,y:170}
];
The updated code:
var chart = d3.select("body")
.append("svg")
.attr("width",w)
.attr("height",h);
var plot = chart
.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx",function(d){return d.x;})
.attr("cy",function(d){return d.y;})
.attr("r",function(d,i){return i*4});
Then I took a step further and created multiple objects with more than a single x and y coordinate (I'm interested in that particular case because my future working dataset [the real one] is made of a series of wind turbines each one with thousands of x-y points).
var dataset = [ {Turbine: "01", x:[100,130,70,100],y:[220,350,60,140]},
{Turbine "02", x:[520,120,390,500], y:[300,280,170,400]};
I've got no clue so far of what improvement should be made in the code above in order to work. I realized that d.x and d.y now do not deliver a single x and a single y point, they deliver arrays, that's why the previous code is now useless as attributes cx and cy expect only one coordinate per iteration. I'm trying to find a way to somehow be able to use a new index inside the subselection (for each i in d, the code should then use a ii to get just one point from the subselection d[i].x[ii]).
Any ideas? Thank you for your time in advance!
Upvotes: 0
Views: 160
Reputation: 19183
You need to think about how to translate your real data into a scatter plot. What I'm suggesting, is flatten all your data into individual dots, and differentiate the two Turbines by a different color.
var colors = ['orange', 'green'];
function convertData(dataset) {
var data = [];
dataset.forEach(function(oneDataset, datasetIndex) {
// Split the x and y arrays into pairs
// (that's assuming oneDataset.x and oneDataset.y are the same length!)
for (var i=0; i<oneDataset.x.length; i++) {
data.push({
x: oneDataset.x[i],
y: oneDataset.y[i],
color: colors[datasetIndex]
});
}
});
}
var rawDataset = [ {Turbine: "01", x:[100,130,70,100], y:[220,350,60, 140]},
{Turbine: "02", x:[520,120,390,500], y:[300,280,170,400]};
var dataset = convertData(rawDataset);
Now reuse your "solution 2" code, but with that new color improvement:
var plot = chart
.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", function(d) {return d.x;})
.attr("cy", function(d) {return d.y;})
.attr("r", function(d,i) {return i*4})
.attr("fill", function(d) {return c.color});
This is just one solution. But you will probably need in all cases to "flatten" your long arrays into pairs of coordinates in order to render a scatter.
Upvotes: 2