Reputation: 33
I am trying to assign different color to three bars in the bar chart based on dummy data's id. But i failed for some reason even though i created colorArray trying to make it as an attribute and attach with chart. It should be relatively easy but not sure what went wrong. Please help me!
const DUMMY_DATA = [
{ id: 'd1', level: 'High Happiness', value: 6.67 },
{ id: 'd2', level: 'Middle Happiness', value: 5.47 },
{ id: 'd3', level: 'Low Happiness', value: 4.35 },
//{ id: 'd4', level: 'Germany', value: 6 },
];
const MARGINS = {top: 20, bottom: 10};
const CHART_WIDTH = 600;
const CHART_HEIGHT = 400 - MARGINS.bottom - MARGINS.top;
let selectedData = DUMMY_DATA;
const x = d3.scaleBand().rangeRound([0,CHART_WIDTH]).padding(0.1);
const y = d3.scaleLinear().range([CHART_HEIGHT, 0]);
const colorArray = d3.scaleOrdinal().domain(["d1","d2","d3"]).range(["orange", "purple", "steelblue"]);
const chartContainer = d3.select("svg")
.attr("width", CHART_WIDTH)
.attr("height", CHART_HEIGHT + MARGINS.bottom + MARGINS.top);
x.domain(DUMMY_DATA.map((d) => d.level));
y.domain([0, d3.max(DUMMY_DATA, (d) => d.value) + 3] );
const chart = chartContainer.append("g");
chart.append("g")
.call(d3.axisBottom(x).tickSizeOuter(0))
.attr("transform", `translate(0, ${CHART_HEIGHT+10})`)
.attr("color", "lighgray");
function renderChart(){
chart
.selectAll(".bar")
.data(selectedData, data => data.id)
.enter()
.append("rect")
.classed("bar", true)
.attr("width", x.bandwidth())
.attr("height", (data) => CHART_HEIGHT - y(data.value))
.attr("x", (data) => x(data.level))
.attr("y", (data) => y(data.value));
chart.selectAll(".bar").data(selectedData, data => data.id).exit().remove();
chart
.selectAll(".label")
.data(selectedData, data => data.id)
.enter()
.append("text")
.text(data => data.value)
.attr("x", data => x(data.level) + x.bandwidth()/2)
.attr("y", data => y(data.value) - 20)
.attr("text-anchor", "middle")
.classed("label", true);
chart.selectAll(".label").data(selectedData, data => data.id).exit().remove();
}
renderChart();
let unselectedIds = [];
const listItems =d3.select("#data")
.select("ul")
.selectAll("li")
.data(DUMMY_DATA)
.enter()
.append("li");
Upvotes: 0
Views: 397
Reputation: 6735
You need to pass data values to your colorArray
function and apply them using a fill
:
chart.attr("fill", (data) => colorArray(data.id));
Working example using your code:
const DUMMY_DATA = [
{ id: 'd1', level: 'High Happiness', value: 6.67 },
{ id: 'd2', level: 'Middle Happiness', value: 5.47 },
{ id: 'd3', level: 'Low Happiness', value: 4.35 },
];
const MARGINS = {top: 20, bottom: 10};
const CHART_WIDTH = 600;
const CHART_HEIGHT = 400 - MARGINS.bottom - MARGINS.top;
let selectedData = DUMMY_DATA;
const x = d3.scaleBand().rangeRound([0,CHART_WIDTH]).padding(0.1);
const y = d3.scaleLinear().range([CHART_HEIGHT, 0]);
const colorArray = d3.scaleOrdinal().domain(["d1","d2","d3"]).range(["orange", "purple", "steelblue"]);
const chartContainer = d3.select("svg")
.attr("width", CHART_WIDTH)
.attr("height", CHART_HEIGHT + MARGINS.bottom + MARGINS.top);
x.domain(DUMMY_DATA.map((d) => d.level));
y.domain([0, d3.max(DUMMY_DATA, (d) => d.value) + 3] );
const chart = chartContainer.append("g");
chart.append("g")
.call(d3.axisBottom(x).tickSizeOuter(0))
.attr("transform", `translate(0, ${CHART_HEIGHT+10})`)
.attr("color", "lighgray");
function renderChart(){
chart
.selectAll(".bar")
.data(selectedData, data => data.id)
.enter()
.append("rect")
.classed("bar", true)
.attr("width", x.bandwidth())
.attr("height", (data) => CHART_HEIGHT - y(data.value))
.attr("x", (data) => x(data.level))
.attr("y", (data) => y(data.value))
// *********** Apply colors below ***********
.attr("fill", (data) => colorArray(data.id));
chart.selectAll(".bar").data(selectedData, data => data.id).exit().remove();
chart
.selectAll(".label")
.data(selectedData, data => data.id)
.enter()
.append("text")
.text(data => data.value)
.attr("x", data => x(data.level) + x.bandwidth()/2)
.attr("y", data => y(data.value) - 20)
.attr("text-anchor", "middle")
.classed("label", true)
chart.selectAll(".label").data(selectedData, data => data.id).exit().remove();
}
renderChart();
let unselectedIds = [];
const listItems =d3.select("#data")
.select("ul")
.selectAll("li")
.data(DUMMY_DATA)
.enter()
.append("li");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>
Upvotes: 1