我是D3.js的新手(版本5),但我已经能够使用JSON数据创建基本的条形图。Y轴标记成绩百分比,X轴标记日期。目前它显示每月的成绩。如何添加标记每月目标成绩的线标记?另外,如何添加从每个Y轴刻度开始在图表中移动的水平线和图例?
- 我的条形图:**(https://i.stack.imgur.com/lQ4uq.png)
- 所需条形图:**(https://i.stack.imgur.com/T9gJ7.png)
- 代码**:
<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>
我尝试将目标数据追加为另一个条形以创建分组条形图,但条形重叠而不是并排。如果下面的条形的值小于上面的条形,则下面的条形不可见。
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());
1条答案
按热度按时间7tofc5zh1#
不要把d3.js看作是一个绘制图表的库,而是一个用SVG和HTML可视化数据的工具箱(因此得名 * Data-Driven Documents *)。这更加抽象和乏味。但它让您完全控制如何可视化数据。
您可以通过向svg添加另一组
line
元素来绘制目标成绩的图形。对于
data
数组中的每个月,此代码绘制一条从上个月(线的起点-x1
/y1
)到当前月(线的终点-x2
/y2
)的绿线。请注意,我们考虑了没有上个月的第一个月。在本例中,代码创建一条起点和终点相同的线。使用
tickSize()
创建覆盖图表整个宽度的刻度线。要在刻度线上方绘制图表内容(条形图和目标等级),请将y轴添加到在所有其他内容之前创建的组中。
如上所述,你必须自己构造图例的可视化,没有神奇的d3
legend
函数。所有这些都产生了以下结果: