在 D3.js 中为多个小条形图下的轴绘制单独的域

2024-03-01

我的目的是在一个具有不同域的 svg 中绘制多个小条形图,建立在这个例子 http://bl.ocks.org/officeofjane/7315455.

我遇到的主要问题似乎是从输出中提取特定键的值的问题d3.nest并定义每个密钥对应的域。绘制所有值时会出现问题,这些值的日期是在域中绘制的。由于并非每个键都有对应于所有可能日期的值,因此右侧绘制了一个尾部,这破坏了顺序。您能否告诉我如何修复它,如何从绘制的值集中删除没有相应输出的输入?

结果如下:

https://plnkr.co/edit/KUnMSfJwWan3JaIpZutZ/ https://plnkr.co/edit/KUnMSfJwWan3JaIpZutZ/

数据的形式如下:

CSC     20160919    4.0
MAT     20160923    16.0

在给出的数据示例样本中,有两个日期,并且将为每个小子图绘制两个日期。最好将与特定键相对应的日期分开,以便仅绘制那些有相应分数的日期。

存在一个缺陷:域必须是独立的,而在上面的示例中它们不是。 你能告诉我如何用date对应于特定的key定义如下d3.nest?

代码的相关部分似乎在这里:

x.domain(data.map(function(d) { return d.date; }));

和这里:

 svg.selectAll(".bar")
    .data(function(d) {return d.values;})
    .enter()
    .append("rect")
    .attr("class", "bar")
    .attr("x", function(d) { return x(d.date); })
    .attr("width", x.rangeBand())
    .attr("y", function(d) { return y(d.score); })
    .attr("height", function(d) { return height - y(d.score); })
    .attr("fill", function(d) {return color(d.score)})

APPENDIX

以下问题可能有用:

D3.js 将对象绑定到数据并附加每个键 https://stackoverflow.com/questions/12923942/d3-js-binding-an-object-to-data-and-appending-for-each-key

d3.js 中多个分组条形图中的 X,Y 域数据绑定 https://stackoverflow.com/questions/28130411/x-y-domain-data-binding-in-multiple-grouped-bar-charts-in-d3-js?rq=1

您还可以找到有用的以下链接:

分组条形图 https://bl.ocks.org/mbostock/3887051

教程:分组条形图 https://www.dashingd3js.com/lessons/basic-chart-grouped-bar-chart

数据分组 http://learnjsdata.com/group_data.html


假设


我们可以将数据嵌套两次,首先按课程,然后按日期,然后在轴上绘制键的键吗?嵌套是解决问题的最佳方法吗?


这是我的解决方案(警告:我是第一个承认我的代码太复杂的人。让我们看看其他人是否有更简单的解决方案)。

首先,我们创建一个空对象:

var xScale = {};

并用两个函数填充这个新对象,每个函数对应不同的比例。

courses.forEach(function(d) {
    xScale[d.key] = d3.scale.ordinal()
        .rangeRoundBands([0, width], .1)
        .domain(d.values.map(function(e) {
            return e.date
        }));
});

之后,我们将有两个不同的比例:

xScale.HIS//this is the scale for the first SVG
xScale.PHY//this is the scale for the second SVG

现在您可以在酒吧中使用这些音阶,但不能直接使用。我们必须定义什么比例将用于什么 SVG。

为此,首先,我们将得到key每个 SVG 数据中的属性,然后使用该值访问内部正确的对象xScale,其中包含适当的比例:

.attr("x", function(d) {
        var scale = d3.select(this.parentNode).datum().key;
        return xScale[scale](d.date);
    })
    .attr("width", function() {
        var scale = d3.select(this.parentNode).datum().key;
        return xScale[scale].rangeBand()
    })

最复杂的部分是调用轴。在这里,我们将使用each打电话xAxis两次,使用第一个参数(数据)来获取值key:

svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .each(function(d) {
        return d3.select(this).call(xAxis.scale(xScale[d.key]))
            .selectAll("text")
            .style("text-anchor", "end")
            .attr("dx", "-.8em")
            .attr("dy", "-.55em")
            .attr("transform", "rotate(-90)");
    })

总而言之,这是您更新的 plunker:https://plnkr.co/edit/XFKzQm0zp0MkhzK4Qt5d?p=preview https://plnkr.co/edit/XFKzQm0zp0MkhzK4Qt5d?p=preview

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 D3.js 中为多个小条形图下的轴绘制单独的域 的相关文章