表格中的内联D3迷你图和文字 [英] Inline D3 sparklines in a table alongside text

查看:114
本文介绍了表格中的内联D3迷你图和文字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说是否有这样的表格:

var data = [
    ['Orange', 'Orange', [6,3,3,2,5]],
    ['Apple', 'Red', [6,2,6,5,5]],
    ['Grape', 'Purple', [9,1,2,3,1]]
]

我希望将字符串表示为字符串,但将数字数组表示为D3折线图.如果只是我关心的文本,则可以selectAll td元素并插入一些文本.

I'd like the strings to represented as strings, but the number array represented as a D3 line chart. If it's just text that I care about, I can selectAll td elements and insert some text.

var tcells = trows
    .selectAll("td")
    .data(function(d, i) { return d; })
    .enter()
    .append("td")
    .text(function(d, i) { return d; });

第三列是文本,因此我想用图形更新它或附加另一列图形.说lines是创建折线图的函数,我想调用lines(),因为它传递了来自每一个行的第三列的数据.

The 3rd column is text so I'd like to update it with graphs or alternatively append another column of graphs. Say lines is a function that creates a line graph, I would like to call lines() as it passes data from the 3rd column for each row.

trows.selectAll("td")
    .data(function(d) {return d[2]}) // scope out data from 3rd column
    .enter()
    .append("td")
    //.call(lines([3,8,2,5,8,4])); // this works
    .call(lines);                // this doesn't

我的D3知识参差不齐,因此我不清楚如何传递数据和选择.

My D3 knowledge is spotty so I am not clear on how the data and the selection are passed.

这是完整的代码: jsfiddle链接

推荐答案

您正在混淆 selection.each(func) 方法.

You're confusing the selection.call(func) method with the selection.each(func) method.

call是一种方便的方法,用于调用将选择作为一个整体接受参数的函数. trows.call(lines)lines(trows)等效,除了它可以是方法链的一部分.

call is a convenience method for calling functions that accept the selection as a whole as a parameter. trows.call(lines) is equivalent to lines(trows), except that it can be part of a method chain.

each用于为所选内容中的每个元素调用一次函数,将数据和索引作为参数传递.

each is used to call a function once for each element in the selection, passing the data and index as parameters.

至于为什么trows.call(lines([3,8,2,5,8,4]))有效",那么它只能是合理的.您正在调用带有硬编码数据数组的函数lines,但是该函数不会返回任何内容,因此选择内容本身对call没有任何作用. (如果您不了解其中的区别,则可以

As for why trows.call(lines([3,8,2,5,8,4])) "works", well it only sort-of works. You're calling the function lines, with the hard-coded data array, but that function doesn't return anything, so there is nothing to call on the selection itself. (If you don't understand the difference, you might find this answer useful.)

您的方法目前也仅将折线图附加到主体,而不将其插入表中.您有以下代码,您确认无法使用:

Your method also currently only appends the line graph to the body, it doesn't insert it into the table. You have the following code that you acknowledge doesn't work:

// dynamic selection doesn't
this.append("td").append('svg')
    .attr('width', width).attr('height', height)
    .append('path').attr('class','line')
    .datum(data).attr('d', line);

失败的原因有几个:

    在您调用函数的上下文中,直接调用lines([3,8,2,5,8,4])
  • 不会设置this的值,因此它指向窗口对象;
  • 即使您使用each方法(设置this值)调用该函数,this也将指向DOM节点,而不是您可以为其调用d3方法的选择;
  • 除了您的特定情况外,它甚至都不会指向DOM节点,因为您是从enter()选择中调用它的,而您还没有附加新节点.
  • in the context you're calling the function, with lines([3,8,2,5,8,4]) being called directly, the this value will not be set, so will point to the window object;
  • even if you were calling the function with an each method (which sets the this value), this would point to the DOM node, not a selection that you can call d3 methods for;
  • except in your specific case, it wouldn't even point to a DOM node, because you're calling it from an enter() selection in which you haven't appended the new nodes yet.

总而言之,要使工作正常进行:

In summary, to get things working:

  1. 在主程序中,在创建新的<td>元素后,使用each调用lines函数:

  1. In the main program, use each to call your lines function, after creating your new <td> elements:

trows.selectAll("td.graph")  
     //use a class so you don't re-select the existing <td> elements
  .data(function(d) {return [d[2]];})
     // the value returned by a data function must always be an array
     // containing data objects for each new element you create -- 
     // you only want one element containing the entire data array, 
     // not individual elements for each number, so wrap it in another array
  .enter()
    .append("td")
    .attr("class", "graph")
    .each(lines); 

  • lines函数中,重新选择this元素(现在将指向刚刚创建的<td>),然后将迷你图SVG附加到该元素:

  • In the lines function, re-select the this element (which will now point to the just-created <td>), and append your sparkline SVG to it:

    d3.select(this).append('svg')
            .attr('width', width)
            .attr('height', height)
         .append('path')
            .attr('class','line')
            .datum(data)
            .attr('d', line);
    

  • http://jsfiddle.net/Lgq6ct9f/9/
    (进行了一些其他清理,因此您在主程序中间没有函数定义)

    http://jsfiddle.net/Lgq6ct9f/9/
    (with some other clean-up so you don't have a function definition in the middle of your main program)

    这篇关于表格中的内联D3迷你图和文字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆