Well, I want to color my scatter using a vector with values. Actually, I want to use other dimension than the one used for creating the scatter.
Using these lines it gives a color to my scatter using the values given by the dimension that scatter is built on.
.colorAccessor(function(d) {return d.key[1]})
.colors(d3.scaleSequential(d3.interpolateOranges))
.colorDomain(y_range)
y_range = [y_min, y_max]
I tried to include the column for color in the dimension of the scatter, but it slows down the process of filtering. Something like this:
scatterDim = crossFilter.dimension(function(d) { return [d[it.variable[0]], d[it.variable[1]], d[it.color]]})
.colorAccessor(function(d) {return d.key[2]})
.colors(d3.scaleSequential(d3.interpolatePlasma))
.colorDomain([colorUnits[0], colorUnits[colorUnits.length - 1]]),
I want to have a different dimension for color:
colorDimension = crossFilter.dimension(function (d) { return d[it.color] }),
colorGroup = colorDimension.group().reduceCount(),
colorAll = colorGroup.all(),
colorUnits = [],
count = 0;
for(var color in colorAll)
{
colorUnits[count] = colorAll[color].key;
count++;
}
.colorAccessor(//some different code for my vector colorUnits or even for dimension?!//)
.colors(d3.scaleSequential(d3.interpolatePlasma))
.colorDomain([colorUnits[0], colorUnits[colorUnits.length - 1]]),
I would also like to know how to use scaleOrdinal for color. In case that the vector colorUnits contains strings.
The name "dimension" is a little confusing in crossfilter and dc.js. It isn't used to describe the "Y" (aggregated) values, or the color.
It really means, "I want to bin my data by this key, and filter on it."
The reason you will find color as a third element in dimension keys in many examples is that it's expedient. It's easier to change the keys than the aggregated values. But it doesn't really make sense.
The fact that your chart got slower when you added color to your dimension key tells me that you don't have a unique color for each X/Y pair. Instead of drawing a dot for each X/Y pair, you end up with a dot for each X/Y/color triplet.
You also don't need to create a separate color dimension unless you want to bin, aggregate, or filter on color.
Assuming you only want one dot per X/Y pair, you need to decide which color to use. Then you can change the reduction, instead of the key, to add this data:
scatterDim = crossFilter.dimension(function(d) {
return [d[it.variable[0]], d[it.variable[1]]];
}),
scatterGroup = scatterDim.group().reduce(
function(p, v) { // add
p.count++; // reduceCount equivalent
p.color = combine_colors(p.color, v[it.color]);
return p;
},
function(p, v) { // remove
p.count--;
// maybe adjust p.color
return p;
},
function() { // init
return {count: 0, color: null};
}
);
If you don't care which of the colors is used, you don't need combine_colors
; just use v[it.color]
. Otherwise, that's something you need to decide based on your application.
Now the scatter group has objects as its values, and you can change the scatter plot to take advantage of them:
scatterPlot
.existenceAccessor(d => d.value.count) // don't draw dot when it is zero
.colorAccessor(d => d.value.color)
If in fact you do want to draw all the dots with different colors, for example using opacity to allow overplotting, you probably need a canvas implementation of a scatter plot, because SVG is only good up to thousands of points. There is one in the works for dc.js but it needs to be ported to the latest APIs.
I would also like to know how to use scaleOrdinal for color. In case that the vector colorUnits contains strings.
Not sure what you mean here. scaleOrdinal
takes strings as its domain, so
.colors(d3.scaleOrdinal(colorUnits, output_colors))
should work?
Since I'm failing to communicate something or another, here is an example. The color strings come from an array since I don't have an example of your data or code:
const names = ["Zero", "One", "Two", "Three", "Four", "Five"];
speedSumGroup = runDimension.group()
.reduce(
function(p, v) { // add
p.count++; // reduceCount equivalent
p.color = names[+v.Expt];
return p;
},
// ... as before
);
chart
.colorAccessor(d => d.value.color)
.colors(d3.scaleOrdinal(names, d3.schemeCategory10))
Once again, if the method isn't working for you, the best way to figure it out is to log speedSumGroup.all()
. I get:
[
{
"key": [
1,
850
],
"value": {
"count": 1,
"color": "One"
}
},
{
"key": [
1,
880
],
"value": {
"count": 1,
"color": "Three"
}
},
{
"key": [
1,
890
],
"value": {
"count": 2,
"color": "Five"
}
},
// ...
]