如何在d3中制作多系列条形图?

C. *_*ort 0 bar-chart d3.js vue.js

我有两个显示相同数据的条形图。每个 x 轴标签显示一个条形,它是输出集和输入集的总和。我的另一个需要将每个 x 轴标签的输入和输出数据分成两个相邻的条形。

我想要它的外观: 在此输入图像描述

从我在其他示例中看到的数据被合并到一个数组中,然后成对绘制。我尝试将两组合并为一组,但无法使其工作。

这是我绘制条形的方法:

svg.selectAll(".bar")
                .data(options.series[i].data)
                .enter().append("rect")
                .attr("class", "bar")
                .attr("class", function(d) {
                    if (d < 0) {
                        return "bar positive";
                    } else {
                        return "bar negative";
                    }
                })
                .attr("height", function(d) {
                    return Math.abs(yScale(d) - yScale(0));
                })
                .attr("y", function(d) {
                    if (d > 0) {
                        return yScale(d);
                    } else {
                        return yScale(0);
                    }
                    // return yScale(d)
                })
                .attr("width", (xScale.bandwidth()))
                .attr("x", function(d, j) {
                    return xScale(options.labels[j])
                })
                .on('mouseover', function(d, j){
                    d3.select(this).style("opacity", 0.6);
                    tip.show(d, j);
                })
                .on('mouseout', function(d, j){
                    d3.select(this).style("opacity", 1);
                    tip.hide(d, j);
                })
                .on("click", function(d, j) {
                  zoomInD3(vm, options.labels[j]);
                });
Run Code Online (Sandbox Code Playgroud)

我不需要堆积条形图,而是并排图表。有什么有用的提示吗?

我的数据存储在仅包含值的数组中。

C. *_*ort 5

我其实已经想通了。我已将两个数据数组组合成具有类名的对象列表。

//Combine both sets of data into a list of objects
var combinedList = []
for(var i = 0; i < xAxisLabels.length; i++) {
    var object = {first: options.series[i].data, second: options.series[i].data1}
    combinedList.push(object); //Push object into list
}
//Create container for the bar objects of class bar
var multigraph = svg.selectAll(".bar")
            .data(combinedList)
            .enter().append("g")
            .attr("class", "bar")
//Create a rect of the "first" element in object
var bar1 = multigraph.append("rect")
            .attr("class", "first")
            .attr("class","bar negative")
            .attr("height", function(d) {
                return Math.abs(yScale(d.fist) - yScale(0));
            })
            .attr("y", function(d) {
                if (d.first > 0) {
                    return yScale(d.first);
                } else {
                    return yScale(0);
                }
            })
            .attr("width", (xScale.bandwidth()))
            .attr("x", function(d, j) {
                return xScale(options.labels[j])
            })
            .on('mouseover', function(d, j){
                d3.select(this).style("opacity", 0.6);
                tip.show(d.first, j);
            })
            .on('mouseout', function(d, j){
                d3.select(this).style("opacity", 1);
                tip.hide(d.first, j);
            })
            .on("click", function(d, j) {
              zoomInD3(vm, options.labels[j]);
            });
//Create a rect of the "second" element in object
var bar2 = multigraph.append("rect")
            .attr("class", "second")
            .attr("class","bar positive")
            .attr("height", function(d) {
                return Math.abs(yScale(d.second) - yScale(0));
            })
            .attr("y", function(d) {
                if (d.second> 0) {
                    return yScale(d.second);
                } else {
                    return yScale(0);
                }
            })
            .attr("width", (xScale.bandwidth()))
            .attr("x", function(d, j) {
                return xScale(options.labels[j])
            })
            .on('mouseover', function(d, j){
                d3.select(this).style("opacity", 0.6);
                tip.show(d.second, j);
            })
            .on('mouseout', function(d, j){
                d3.select(this).style("opacity", 1);
                tip.hide(d.second, j);
            })
            .on("click", function(d, j) {
              zoomInD3(vm, options.labels[j]);
            });
Run Code Online (Sandbox Code Playgroud)

仍然需要根据条形之间的距离在 x 轴上进行调整。基本上,通过可调用对象中的元素,可以从类属性中调用数据。

因此,当检查页面元素的检查器时,会清楚地看到有一个包含两个“rect”对象的“g”容器。