I am new to D3.js (version 5) but I have been able to create basic bar chart using JSON data. The Y axis labels grade percentage, and the X axis labels dates. At the moment it displays the grades per month. How can add a line marker that labels the targeted grade for each month? Additionally, how can I add the horizontal lines that move across the chart from each Y axis tick and a legend?
My bar chart: (https://i.stack.imgur.com/lQ4uq.png)
Desired bar chart: (https://i.stack.imgur.com/T9gJ7.png)
Code:
<div style="text-align: center;">
<h1>Grade %</h1>
<div id="GradeChart"></div>
</div>
<script>
// Data Example
data = {
'month': date, 'grade': 90, 'target': 85,
'month': date, 'grade': 89, 'target': 85,
'month': date, 'grade': 78, 'target': 85,
'month': date, 'grade': 99, 'target': 100,
'month': date, 'grade': 50, 'target': 85,
'month': date, 'grade': 60, 'target': 90,
'month': date, 'grade': 65, 'target': 85,
'month': date, 'grade': 75, 'target': 85,
'month': date, 'grade': 86, 'target': 80,
'month': date, 'grade': 100, 'target': 85,
'month': date, 'grade': 1, 'target': 85,
'month': date, 'grade': 27, 'target': 85,
};
const width = 1200;
const height = 600;
const margin = { top: 50, bottom: 150, left: 50, right: 50 };
const svg = d3.select('#GradeChart')
.append('svg')
.attr('width', width - margin.left - margin.right)
.attr('height', height - margin.top - margin.bottom)
.attr("viewBox", [0, 0, width, height]);
const x = d3.scaleBand()
.domain(d3.range(data.length))
.range([margin.left, width - margin.right])
.padding(0.1)
const y= d3.scaleLinear()
.domain([0, 100])
.range([height - margin.bottom, margin.top])
svg
.append("g")
.attr("fill", 'royalblue')
.selectAll("rect")
.data(data)
.join("rect")
.attr("x", (d, i) => x(i))
.attr("y", d => y(d.percent))
.attr('title', (d) => d.percent)
.attr("class", "rect")
.attr("height", d => y(0) - y(d.percent))
.attr("width", x.bandwidth());
function yAxis(g) {
g.attr("transform", `translate(${margin.left}, 0)`)
.call(d3.axisLeft(y).ticks(null, data.format))
.attr("font-size", '20px')
}
function xAxis(g) {
g.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).tickFormat(i => data[i].month))
.attr("font-size", '20px')
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", "rotate(-65)")
}
svg.append("g").call(xAxis);
svg.append("g").call(yAxis);
svg.node();
</script>
I tried to append target data as another bar to create a grouped bar chart, but the bars overlapped instead of being side by side. The bar underneath would not be visible if its value was less than the one on top.
svg
.append("g")
.attr("fill", 'green')
.selectAll("rect")
.data(data)
.join("rect")
.attr("x", (d, i) => x(i))
.attr("y", d => y(d.target))
.attr('title', (d) => d.target)
.attr("class", "rect")
.attr("height", d => y(0) - y(d.target))
.attr("width", x.bandwidth());
Via Active questions tagged javascript - Stack Overflow https://ift.tt/xQufPbK
Comments
Post a Comment