如何在Canvas上实现示例中的矩形柱状图?
实现示例阶梯式矩形图表的思路与方案
你提供的图表是阶梯式条形图(也可看作瀑布图的变种),核心是把每个数据项的sum映射为矩形高度,day映射为矩形的横轴位置(或宽度),以下是具体实现提示:
1. 数据预处理
先明确数据的可视化逻辑:
- 如果要每个矩形宽度固定,直接按
day的顺序排列即可 - 如果要根据
day的间隔设置宽度(比如day4到day7间隔3,矩形宽度对应放大3倍),需先计算相邻day的差值:
const rawData = [/* 你的原始数据 */]; // 计算每个矩形的宽度(基于日期间隔) const processedData = rawData.map((item, index) => { const nextDay = rawData[index + 1]?.day || item.day + 1; return { ...item, width: nextDay - item.day }; });
2. 工具选择与实现示例
方案一:用ECharts快速实现(适合快速落地)
ECharts的条形图可直接适配需求,配置如下:
<div id="main" style="width: 800px; height: 500px;"></div> <script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script> <script> const rawData = [ { day: 2, sum: 7799857 }, { day: 3, sum: 6986099 }, { day: 4, sum: 6471975 }, { day: 7, sum: 5895399 }, { day: 8, sum: 5194120 }, { day: 9, sum: 4851008 }, { day: 10, sum: 4483119 }, { day: 11, sum: 3492771 }, { day: 14, sum: 2717263 }, { day: 15, sum: 1763884 }, { day: 16, sum: 1111772 }, { day: 17, sum: 148788 } ]; // 转换为ECharts需要的类目数据 const xData = rawData.map(item => `Day ${item.day}`); const yData = rawData.map(item => item.sum); const option = { xAxis: { type: 'category', data: xData, axisLabel: { rotate: 45 } }, yAxis: { type: 'value', title: { text: 'Sum' } }, series: [{ type: 'bar', data: yData, barWidth: '80%', // 调整柱子宽度匹配示例样式 itemStyle: { color: '#409EFF' } // 自定义颜色 }] }; const myChart = echarts.init(document.getElementById('main')); myChart.setOption(option); </script>
方案二:用D3.js手动绘制(适合高度自定义)
如果需要更灵活的样式控制,D3.js的核心实现逻辑:
const rawData = [/* 你的原始数据 */]; const svg = d3.select("svg").attr("width", 800).attr("height", 500); // 定义比例尺 const xScale = d3.scaleBand() .domain(rawData.map(d => d.day)) .range([50, 750]) .padding(0.1); const yScale = d3.scaleLinear() .domain([0, d3.max(rawData, d => d.sum)]) .range([450, 50]); // 绘制矩形 svg.selectAll("rect") .data(rawData) .enter() .append("rect") .attr("x", d => xScale(d.day)) .attr("y", d => yScale(d.sum)) .attr("width", xScale.bandwidth()) .attr("height", d => 450 - yScale(d.sum)) .attr("fill", "#409EFF"); // 添加坐标轴 svg.append("g") .attr("transform", "translate(0,450)") .call(d3.axisBottom(xScale)); svg.append("g") .attr("transform", "translate(50,0)") .call(d3.axisLeft(yScale));
关键映射逻辑
- 矩形高度:直接对应数据中的
sum值,通过比例尺映射到画布的像素高度 - 矩形横轴位置:对应数据中的
day,可以用类目轴或线性轴定位 - 矩形宽度:可选固定宽度,或根据
day的间隔动态计算
内容的提问来源于stack exchange,提问作者Karen
相关产品推荐
相关产品推荐

