d3绘制瀑布图源码
由于瀑布图的实现方式有很多种,这里提供一种基于d3.js的实现方法。
HTML代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Waterfall Chart with D3.js</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
<style>
.chart {
width: 800px;
height: 500px;
margin: 20px auto;
}
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.bar.total {
fill: #ccc;
}
.bar.negative {
fill: #d62728;
}
.label {
font-size: 12px;
text-anchor: middle;
}
</style>
</head>
<body>
<div class="chart"></div>
<script src="waterfall.js"></script>
</body>
</html>
JavaScript代码:
// 数据
var data = [
{name: 'Sales', value: 1000},
{name: 'Cost of goods sold', value: -400},
{name: 'Gross profit', value: 600},
{name: 'Salary', value: -300},
{name: 'Rent', value: -200},
{name: 'Net profit', value: 100}
];
// 定义画布大小和边距
var margin = {top: 20, right: 20, bottom: 50, left: 50},
width = 800 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// 创建SVG元素
var svg = d3.select('.chart')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// 计算总数
var total = d3.sum(data, function(d) { return d.value; });
// 定义比例尺
var x = d3.scaleBand()
.domain(data.map(function(d) { return d.name; }))
.range([0, width])
.padding(0.1);
var y = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return d.value; })])
.range([height, 0]);
// 绘制x轴
var xAxis = d3.axisBottom()
.scale(x);
svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
// 绘制y轴
var yAxis = d3.axisLeft()
.scale(y);
svg.append('g')
.attr('class', 'y axis')
.call(yAxis);
// 绘制瀑布图
var bar = svg.selectAll('.bar')
.data(data)
.enter().append('rect')
.attr('class', function(d) { return 'bar ' + (d.value < 0 ? 'negative' : ''); })
.attr('x', function(d) { return x(d.name); })
.attr('y', function(d) { return y(Math.max(0, d.value)); })
.attr('width', x.bandwidth())
.attr('height', function(d) { return Math.abs(y(d.value) - y(0)); });
// 绘制总数
svg.append('rect')
.attr('class', 'bar total')
.attr('x', 0)
.attr('y', y(total))
.attr('width', width)
.attr('height', 1);
svg.append('text')
.attr('class', 'label')
.attr('x', width / 2)
.attr('y', y(total) - 10)
.text('Total');
// 绘制数值标签
svg.selectAll('.label')
.data(data)
.enter().append('text')
.attr('class', 'label')
.attr('x', function(d) { return x(d.name) + x.bandwidth() / 2; })
.attr('y', function(d) { return y(d.value) + (d.value < 0 ? 20 : -5); })
.text(function(d) { return d.value; });
注释:
- 首先定义数据,每个元素包含一个名称和一个值;
- 然后定义画布大小和边距;
- 创建SVG元素,并设置大小和边距;
- 计算总数,用于绘制总数水平线;
- 定义x轴和y轴的比例尺;
- 绘制x轴和y轴;
- 绘制瀑布图,包括正值和负值;
- 绘制总数水平线和总数标签;
- 绘制数值标签,包括正值和负值。
原文地址: https://www.cveoy.top/t/topic/LSC 著作权归作者所有。请勿转载和采集!