如果您熟悉 d3js,则可以轻松实现。我会考虑这样做的方式是这样的。
- x 比例取决于值
- y 比例取决于总体分类值。假设您的条形高度为 20(根据您的设计更改值)
对于每个数据点,
- 在 y(label) -10 处为组件绘制矩形,高度为 8(根据您的设计更改值)
- 在 y(label)+2 处为总部分绘制一个总矩形,高度为 8
数据最好采用这种形式,这样操作更容易
const data = [{key: "First", a:300,b:900},{key:"Second", a:100,b:100},{key:"Third", a:100,b:200}];
// Select svg
const svg = d3.select("svg");
// Add a group - Generally to keep your svg code cleaner
const g = svg.append("g");
// Create your scales & axis. You'll get two functions x & y
// Set width and height, margins for your chart
const y = scalePoint().domain(d=>d[key]).range([marginTop, marginTop+height]);
// Scale based on total (a+b)
const x = scaleLinear()
.domain(extent(data, d=> d.a + d.b))
.range([marginLeft, marginLeft+width]);
// Please pick any notebook
// https://observablehq.com/@d3/gallery
const dataPointG = g
.selectAll(".dataPoint")
.data(data)
.enter()
.append("g")
.attr("class","dataPoint");
// A Rect for all "a" component
dataPointG
.append("rect")
.attr("x",0)
.attr("y",d => y(d[key]) - 10)
.attr("width", d=> x(d.a))
.attr("height", 8)
.attr("fill", "#1414BF");
// b
dataPointG
.append("rect")
.attr("x",0)
.attr("y",d => y(d[key]) - 10)
.attr("width", d=> x(d.b))
.attr("height", 8)
.attr("fill", "#1414BF");
// Totals
dataPointG
.append("rect")
.attr("x",0)
.attr("y",d => y(d[key]) + 2)
.attr("width", d=> x(d.b))
.attr("height", 8)
.attr("fill", "#1414BF");
我是根据对您的要求的理解写的。您可能需要根据您的要求进一步自定义上述内容。
在此处查看 jsfiddle。
https://jsfiddle.net/h0uctw85/101/