I am working with D3js and I have this project where I have to sort some data with data chart and stuff. What I want to do is colorize the charts background based on their data value. For example, the more points a student has, the darker his chart will be. Here is what I want to do and here is what I have.
Lets say my data array is:
var students =
{"name":"John","value":"9"},
{"name":"Jack" ,"value":"10"},
{"name":"Peter","value":"3"}];
And this is my script.js class which I use to draw my charts:
var x = d3.scale.linear()
.range([0, width])
.domain([0, d3.max(students, function (d) {
return d.value;
})]);
var y = d3.scale.ordinal()
.rangeRoundBands([height, 0], .1)
.domain(students.map(function (d) {
return d.name;
}));
//make y axis to show bar names
var yAxis = d3.svg.axis()
.scale(y)
//no tick marks
.tickSize(0)
.orient("left");
var gy = svg.append("g")
.attr("class", "y axis")
.call(yAxis)
var bars = svg.selectAll(".bar")
.data(students)
.enter()
.append("g")
//append rects
bars.append("rect")
.attr("class", "bar")
.attr("y", function (d) {
return y(d.name);
})
.attr("height", y.rangeBand())
.attr("x", 0)
.attr("width", function (d) {
return x(d.value);
});
Is there anyway I can do this, maybe by "if(students.value<=10) bar.style.backgroundcolor("red") else if(students.value <=5)bar.style.backgroundcolor("pink")
CodePudding user response:
You can create a color scale and use it to set the fill attribute for the rectangles. In the example below, I use a sequential scale for this.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://d3js.org/d3.v7.js"></script>
</head>
<body>
<div id="chart"></div>
<script>
// chart data
const data = [
{name: 'John', value: 80},
{name: 'Jane', value: 85},
{name: 'Albert', value: 56},
{name: 'Ramson', value: 90},
{name: 'Rick', value: 70},
{name: 'Karen', value: 30},
{name: 'Jaden', value: 40},
{name: 'Gustav', value: 15},
{name: 'Nathan', value: 95},
].sort((a, b) => d3.descending(a.value, b.value));
// dimensions and margins
const margin = { top: 10, bottom: 30, left: 30, right: 10};
const width = 500 - margin.left - margin.right;
const height = 200 - margin.top - margin.bottom;
const svg = d3.select('#chart')
.append('svg')
.attr('width', width margin.left margin.right)
.attr('height', height margin.top margin.bottom);
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
// scales
const x = d3.scaleBand()
.domain(data.map(d => d.name))
.range([0, width])
.padding(0.15);
const y = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)])
.range([height, 0]);
const color = d3.scaleSequential()
.domain([0, d3.max(data, d => d.value)])
.interpolator(d3.interpolateBlues);
// axis generators
const xAxis = d3.axisBottom(x);
const yAxis = d3.axisLeft(y);
// draw bars
g.append('g')
.selectAll('rect')
.data(data)
.join('rect')
.attr('x', d => x(d.name))
.attr('width', x.bandwidth())
.attr('y', d => y(d.value))
.attr('height', d => height - y(d.value))
.attr('fill', d => color(d.value));
// draw axes
g.append('g')
.attr('transform', `translate(0,${height})`)
.call(xAxis);
g.append('g')
.call(yAxis);
</script>
</body>
</html>