Mapping In D3 Ordinal Scales
Solution 1:
The domain isn't quite right:
> color.domain()
[0, 6, 1, 0.5]
For each value in an ordinal scale's range, there should to be a matching value in the domain.
Instead of setting the domain to [0,6]
, it should be [0, 1, 2, 3, 4, 5, 6]
:
color = d3.scale.ordinal()
.range(["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd", "#8c564b", "#e377c2"])
.domain(d3.range(0,7));
Checking to make sure everything works after updating color:
> d3.range(0,7).forEach(function(d){ console.log(color(d)); })
#1f77b4#ff7f0e#2ca02c#d62728#9467bd#8c564b#e377c2
Solution 2:
This is expected as there are only 2 explicitly defined values in your domain. So the first value of 0 is assigned to the first color of #1f77b4
, the second value of 6 is assigned to the second color,#ff7f0e
, and the remainders are inferred after they are sorted internally as strings. You need to define the domain explicitly for predictable behavior. For example,
color = d3.scale.ordinal()
.range(["#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd", "#8c564b", "#e377c2"])
.domain([0,1,2,3,4,5,6]);
console.log(color(0),color(1),color(2),color(3),color(4),color(5),color(6));
As the documentation states
Setting the domain on an ordinal scale is optional. If no domain is set, each unique value that is passed to the scale function will be assigned a new value from the output range; in other words, the domain will be inferred implicitly from usage. However, it is a good idea to assign the ordinal scale's domain to ensure deterministic behavior, as inferring the domain from usage will be dependent on ordering.
Post a Comment for "Mapping In D3 Ordinal Scales"