Reputation: 193
Is there a way to get a linear color-output for and array of elements?
Right now I'm using the following, which isn't pretty and the risk is also that I might have more elements in my array than I have colors here so then I'll just have to add more colors here.
I'm right now filtering out a number of elements and the "theExports" array does basically look like ["element1", "element2", "element3", ...] and is an array of strings.
var color = d3.scaleOrdinal()
.domain([theExports])
.range(["#e69a61", "#9817ff", "#18c61a", "#33b4ff", "#c9167e", "#297853", "#d7011b", "#7456c7", "#7e6276", "#afb113", "#fd879c", "#fb78fa", "#24c373", "#45bbc5", "#766b21", "#abad93", "#c19ce3", "#fd8f11", "#2f56ff", "#307a11", "#b3483c", "#0d7396", "#94b665", "#9d4d91", "#b807c8", "#086cbf", "#a2abc5", "#a35702", "#d3084b", "#8c6148", "#fa82ce", "#71be42", "#2bc0a0", "#b64064", "#d09fa2"]);
Either way it isn't really pretty or very functional, especially if I'd like to adjust the colors. Right now I think it would be ideal if I managed to either plot it vs a linear color scale, or even better stepping it between say 3 or four colors like ["yellow", "red", "green", "blue"].
Using linear instead of ordinal didn't function, or then I did something wrong.
If someone has another solution, even if it isn't exactly what I'm asking for, then I'm also grateful as my current solution doesn't look too good.
Upvotes: 1
Views: 1039
Reputation: 102219
Since your data is an array of strings (clearly an categorical variable), the best option is using an ordinal scale, as you're doing right now.
However, it is possible to use a linear scale with a data like yours. For it to work, you'll pass the index of each element, not the element itself, to the scale (so, you have to mind the order of the elements in the array).
Something like this:
var scale = d3.scaleLinear()
.domain([0, theExports.length - 1])
.range(["yellow", "green"]);
Here is a demo, the data is this array:
["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
Based on the indices of the elements, we get a different colour:
var data = "abcdefghij".split("");
var scale = d3.scaleLinear()
.domain([0, data.length - 1])
.range(["yellow", "green"]);
var divs = d3.select("body").selectAll(null)
.data(data)
.enter()
.append("div")
.style("background-color", function(d) {
return scale(data.indexOf(d))
})
div {
width: 20px;
height: 20px;
margin: 2px;
display: inline-block;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
Increasing the array...
["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s"]
... won't break the scale:
var data = "abcdefghijklmnopqrs".split("");
var scale = d3.scaleLinear()
.domain([0, data.length - 1])
.range(["yellow", "green"]);
var divs = d3.select("body").selectAll(null)
.data(data)
.enter()
.append("div")
.style("background-color", function(d) {
return scale(data.indexOf(d))
})
div {
width: 20px;
height: 20px;
margin: 2px;
display: inline-block;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
Finally, you can set midpoints:
var scale = d3.scaleLinear()
.domain([0, (data.length - 1)/2, data.length - 1])
.range(["yellow", "blue", "green"]);
var data = "abcdefghijklmnopqrs".split("");
var scale = d3.scaleLinear()
.domain([0, (data.length - 1)/2, data.length - 1])
.range(["yellow", "blue", "green"]);
var divs = d3.select("body").selectAll(null)
.data(data)
.enter()
.append("div")
.style("background-color", function(d) {
return scale(data.indexOf(d))
})
div {
width: 20px;
height: 20px;
margin: 2px;
display: inline-block;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
Upvotes: 2