简体   繁体   中英

D3 Bar Chart Bars Color Scaling

I have a bar chart that has dynamic bar coloring. I want to make sure with each initialization of the bar chart that each value stays consistently the same color.

For my color scaling I am using:

const color = d3.scaleOrdinal()
                .domain(arr.map(d => d.key))
                .range(d3.schemeSet2);

        let bars = plot.selectAll("rect")
                      .data(arr)

        bars.enter() 
            .append('rect')
            .merge(bars)
                .attr("x", d => xScale(d.key))
                .attr('y', d => yScale(d.value))
                .attr("width", xScale.bandwidth())
                .attr('height',  d => height - (margin.top + margin.bottom) - yScale(d.value))
                .style("fill", d => color(d.key))

My data is as follows:

let arr = [{key: "Software Engineering", value: 68,
{key: "Biomedical Engineering", value: 63},
{key: "Mechanical Engineering", value: 52},
{key: "Other Engineering", value: 46}]

The data is dynamically appended to this array. If the data is appended in the same order, the colors of the bars remain the same throughout different components of this project. However, if the data is appended differently, the colors of the bars change. For example:

let arr = [{key: "Software Engineering", value: 68,
{key: "Mechanical Engineering", value: 52},
{key: "Biomedical Engineering", value: 63},
{key: "Other Engineering", value: 46}]

I cannot hardcode the coloring to "Software Engineering" etc because the values can change. However, I want the same color for "Software Engineering" independent of when it was appended to the array.

Another example of when colors change is if a value is removed from the array, an example would be:

let arr = [{key: "Software Engineering", value: 68,
{key: "Mechanical Engineering", value: 52},
{key: "Other Engineering", value: 46}]

Any suggestions?

when you define your chart, create a color domain with keys that can be only added, never removed. For example, you can use a Set.

Example:

I - fixed part

colorDomain = new Set();
...

II - dynamic part

Every time the array changes, execute this

...
let arr = [{key: "Software Engineering", value: 68,
           {key: "Mechanical Engineering", value: 52},
           {key: "Biomedical Engineering", value: 63},
           {key: "Other Engineering", value: 46}];

arr.map(item => colorDomain.add(item.key));

colors.domain(Array.from(colorDomain));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM