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

时间:2017-01-22 02:37:28

标签: javascript arrays d3.js svg

我的目的是在一个svg中绘制多个小型条形图,其中包含the example

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

结果如下:

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)})

附录

以下问题非常有用:

D3.js binding an object to data and appending for each key

X,Y domain data-binding in multiple grouped bar charts in d3.js

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

Grouped Bar Chart

Tutorial: Grouped Bar Chart

Grouping Data

假说

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

1 个答案:

答案 0 :(得分:2)

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

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

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中使用什么比例。

要做到这一点,首先,我们将在每个SVG的数据中获取key属性,然后使用此值访问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