【问题标题】:D3- How do I draw dots on a multi line graph? (Iterate through array)D3-如何在多线图上绘制点? (遍历数组)
【发布时间】:2018-12-07 23:25:16
【问题描述】:

我有一个多折线图,我想在上面画点(最终添加我的工具提示。)我似乎无法正确地遍历数据并将它们全部绘制出来。我的数据是一个数组数组,每个子数组都是它自己的线,我想在上面画点。 x(inspected_at), y(flow_data)

完整的代码在这里,大约第 388 行:https://codepen.io/lahesty/pen/aKQjVK?editors=0011

var dots = 
    svg.selectAll('.dots').data(data).enter().append("g").attr("class", 
    "dot");
dots.selectAll('.dot')
    .data(data)
    .enter()
    .append('circle')
    .attr("r", 2.5)
    .attr("cx", function(d) { return x(d.inspected_at); })
    .attr("cy", function(d) { return y(d.flow_data); })
    .style("fill", "blue").style("opacity", ".5") 

我认为它是类似的,因为当我将第二个 .data(data) 更改为 .data(data[0]) 时,第一个点数组会出现,但我希望它们都出现。我也试过这样的东西,而不是上面的:

svg.selectAll("g.dot")
    .data(data)
    .enter().append("g")
    .attr("class", "dot")
    .selectAll("circle")
    .data(function(d, i) { return d[i]; })
    .enter().append("circle")
    .attr("r", 6)
    .attr("cx", function(d,i) {  return x(d.inspected_at); })
    .attr("cy", function(d,i) { return y(d.flow_data); })

我使用 v4。有什么想法吗?非常感谢您的帮助!

【问题讨论】:

    标签: javascript arrays d3.js svg


    【解决方案1】:

    你快完成了。输入g.dot 选择后,您必须保持相同的绑定才能将数据传播到圈子。这可以通过标识函数来完成,function(d) { return d; }Object

    内部迭代将在Selection 内隐式完成。

    svg.selectAll("g.dot")
       .data(data)
       .enter().append("g")
         .attr("class", "dot")
       .selectAll("circle")
       .data(Object) // <--- identity function here
       .enter().append("circle")
         .attr("r", 6)
         .attr("cx", function(d,i) {  return x(d.inspected_at); })
         .attr("cy", function(d,i) { return y(d.flow_data); })
    

    【讨论】:

    • 有趣!我喜欢这种简洁。如果您不介意跟进,我该如何添加剪辑路径?我不确定如何将其与 g.dot 选择相匹配。谢谢!
    • 没关系!我实际上是为这种方法想出来的。我将:svg.selectAll("g.dot") 更改为:svg.append('g').attr('clip-path', 'url(#clipper)').selectAll("g.dot") 看起来就像我需要添加一个 ('g') 组并将我的剪辑路径附加到该组。
    【解决方案2】:

    我还要说你快到了 - 这是你可以继续前进的方法:data() 的第一个参数需要是

    • 一个可迭代的对象 (vulgo: array) 或
    • 一个函数解析为一个对象,用于您拥有的第二级嵌套(c 也在这里:selection.data)。

    您可以(并且可能应该)提供关键功能。

    因此,对data() 的外部调用变为

    var dots = svg.selectAll('.dots').data(data, function(d, i) { return d[0]; }).enter() // and so on
    

    内部调用利用外部的每一行(即data[0]data[1]、 等)并选择内部集合。方便的是,这就是你得到的——但除非你使用一个函数,否则你永远无法告诉 D3 要做什么。因此,以下内容有点疯狂:

    dots.selectAll('.dot')
        .data(function(d) { return d; }, function(d_, i_) { return i_})
        .enter() // and so on
    

    但是你需要一个函数返回它自己的参数(和一个很好的衡量标准的密钥生成器)。我确实叉了你的笔 - c 在这里:https://codepen.io/sebredhh/pen/VdVOxQ?editors=0010 并更改了第 389 和 391 行。看起来像你在寻找的东西 - 希望对你有帮助...

    【讨论】:

    • 啊!不知何故,我没有意识到 data() 应该解析为一个对象。这就说得通了。您介意澄清下划线的作用吗?此外还有一个后续问题,我的剪辑路径呢?它曾经被附加到一个“g”对象(就像我的线条一样),但在点上它只是将它们切断。谢谢!
    • 没关系!刚刚发现我需要添加一个 ('g') 组并将我的剪辑路径附加到该组,就在我选择所有点之前。这两种方法我都喜欢!
    • “data() 的第一个参数必须是对象或解析为对象的函数”... 不幸的是,这不正确:data 没有'不接受对象,它只接受三样东西:一个数组,一个函数或什么都没有。正如你所说,它确实接受一个返回对象的函数,但不仅仅是一个对象。
    • 我只是用下划线来说明什么是第一级和第二级,所以变量更具描述性。没有与之相关的功能。至于“对象”,Gerardo 是对的:它不仅仅是任何对象,而是一个数组。很抱歉造成混乱(将在上面解决)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-23
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    • 1970-01-01
    • 2014-01-26
    相关资源
    最近更新 更多