【问题标题】:is there a method to represent a custom barchart?有没有一种方法来表示自定义条形图?
【发布时间】:2026-01-22 12:25:02
【问题描述】:

我有类似的数据

 total= [1200,200,300]
 A = [300,100,100]
 B = [900,100,200]

所以总计 = A+B

我想通过堆积条形图来表示这一点,以查看灰色的总数以及蓝色 A 和绿色 B 的比例,但在同一张图表上

var chart_current=c3.generate({
       "bindto": "#distrib_chart",
        padding: {
                top: 10,
                right: 100,
                left: 130,
                bottom:0
            },
        data: {
            type: 'bar',
            groups: [['A','B','Total']],
            columns:  data_test, colors:  current_palette,
        },
        size: {
            height: 400,
            width: 300
        },
      })

使用此代码,它工作得很好,但 x 轴不好,我如何编辑它以在 x 轴上有一个好的值

【问题讨论】:

    标签: javascript bar-chart c3.js


    【解决方案1】:

    如果您熟悉 d3js,则可以轻松实现。我会考虑这样做的方式是这样的。

    1. x 比例取决于值
    2. y 比例取决于总体分类值。假设您的条形高度为 20(根据您的设计更改值)

    对于每个数据点,

    1. 在 y(label) -10 处为组件绘制矩形,高度为 8(根据您的设计更改值)
    2. 在 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/

    【讨论】:

    • 感谢您的回复,但我对 d3 不熟悉
    • 很公平。它是写c3的图形原语库。
    • 你能给我发一个关于jsfiddle的例子吗?
    • 用小提琴编辑了我原来的答案。
    • 这就是你想要的互动吗?
    最近更新 更多