【问题标题】:Interactive Notes in a div element from table d3.js表 d3.js 中 div 元素中的交互式注释
【发布时间】:2020-01-09 03:09:55
【问题描述】:

当鼠标悬停在 td 标签上时,我试图在 div 元素中包含特定文本。

我的桌子:

<script>
d3.json("{% url "fund:data_simple_table" fund %}", function(error, data) {
    if (error) throw error;
        var columns = ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 
    'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'YTD'];
var table   = d3.select('#returns').append('table');
var thead   = table.append('thead');
var tbody   = table.append('tbody');

// append the header row
thead.append('tr')
  .selectAll('th')
  .data(columns).enter()
  .append('th')
  .text(function (column) { return column; });

// create a row for each object in the data
var rows = tbody.selectAll('tr')
  .data(data['values'])
  .enter()
  .append('tr');

// create a cell in each row for each column
var cells = rows.selectAll('td')
  .data(function (row) {
    return columns.map(function (column) {
      return {column: column, value: row[column]};
    });
  })
  .enter()
  .append('td')
  .style("color", function(d){ return d.value <= 0 ? "red" : "green"})    
  });
</script>

我有两个数据集,它们的格式相同,但一个带有值,第二个带有文本:data['values']data['text']。当鼠标悬停在相关值上时,我想显示相应的文本。所以我围绕同一个想法尝试不同的东西:

d3.selectAll('td') // I tried also tbody.selectAll('td') or rows.selectAll('td')
  .data(data['highlights'])
  .each(function (d, i) {
    return columns.map(function (column) {
      return {column: column, value: i[column]};
    });
  })
  .enter()
  .on('mouseover', function(d, i) {
  // Select the element by class, use .text to set the content
     d3.select(".highlight").text(d['highlights']);
        })

这里有问题。我得到了错误:

(索引):478 未捕获的类型错误: d3.selectAll(...).data(...).each(...).enter(...).on 不是函数。

我不确定这是否是正确的方法。如果有,有什么问题?

非常感谢您的帮助。

数据['值']: 结果= {list}:[{'':'2017','Jan':'','Feb':'','Mar':'','Apr':'','May':-0.0048, “六月”:0.0087,“七月”:0.0087,“八月”:0.005,“九月”:0.0182,“十月”:0.0079,“十一月”:0.0088,“十二月”:0.0104,“年初至今”:0.0642},{ '':'2017','一月':'','二月':'','三月':'', 0 = {dict}:{'':'2017','一月':'','二月':'','三月':'','四月':'','五月':-0.0048,'六月:0.0087,七月:0.0087,八月:0.005,九月:0.0182,十月:0.0079,十一月:0.0088,十二月:0.0104,年初至今:0.0642} 1 = {dict}:{'':'2017','Jan':'','Feb':'','Mar':'','Apr':'','May':0.0102,'Jun ':-0.0327,'七月':0.0353,'八月':0.0376,'九月':-0.0566,'十月':0.0673,'十一月':-0.0037,'十二月':0.0045,'年初至今':0.0573} 2 = {dict}:{'':'2017','一月':'','二月':'','三月':'','四月':'','五月':-0.0078,'六月:0.0181,七月:0.0267,八月:-0.0007,九月:0.0064,十月:0.0154,十一月:0.0422,十二月:-0.0008,年初至今:0.1026} 3 = {dict}:{'':'2018','Jan':0.0342,'Feb':-0.0148,'Mar':-0.0068,'Apr':-0.0055,'May':0.003,'Jun' : 0.0002, 'Jul': '', 'Aug': '', 'Sep': '', 'Oct': '', 'Nov': '', 'Dec': '', 'YTD': 0.0094 } 4 = {dict}:{'':'2018','Jan':0.0668,'Feb':-0.106,'Mar':-0.0038,'Apr':-0.0212,'May':0.0007,'Jun' : 0.0079, 'Jul': '', 'Aug': '', 'Sep': '', 'Oct': '', 'Nov': '', 'Dec': '', 'YTD': - 0.0623} 5 = {dict}:{'':'2018','一月':0.0679,'二月':-0.0066,'三月':-0.0427,'四月':-0.0181,'五月':0.0166,'六月' : 0.0065, 'Jul': '', 'Aug': '', 'Sep': '', 'Oct': '', 'Nov': '', 'Dec': '', 'YTD': 0.02 }

我将最终代码与旅鼠的解决方案放在下面:

d3.json("{% url "fund:data_complex_table" fund %}", function(error, data) {
    if (error) throw error;
        var columns = ['Years', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'YTD'];
        var table   = d3.select('#full_returns').append('table');
        var thead   = table.append('thead');
        var tbody   = table.append('tbody');
        var nb_rows = d3.selectAll(data['table']).size()
        console.log(nb_rows);

      // append the header row
    thead.append('tr')
      .selectAll('th')
      .data(columns).enter()
      .append('th')
        .text(function (column) { return column; });

     processedData = data['values'].map((row, rowIndex) => {
        return columns.map(column => {
            return {
                    column: column,
                    value: row[column],
                    highlight: data['highlights'][rowIndex][column]
                    };
                });
        });

 // create a row for each object in the data
    var rows = tbody.selectAll('tr')
      .data(processedData)
      .enter()
      .append('tr')
        .each(function (d,i){
            if (i % 3 === 1) {
                d3.select(this).attr("class", "row_fd").attr("text-anchor", 
      "start")

            }
            else if (i % 3 === 2 ) {
                d3.select(this).attr("class", "row_bchk")
                d3.select(this).style("font-size", "0.6em")
            }
            else if (i % 3 === 0) {
                d3.select(this).attr("class", "row_mkt")
                d3.select(this).style("font-size", "0.6em")
            }
        });

    // create a cell in each row for each column
        var cells = rows.selectAll('tr td')
          .data(function(row) { return row; })
          .enter()
          .append('td')
          .style("color", function(d){ return d.value <= 0 ? "red" : 
    "green"})
          .text(d => d.value)
          .on('mouseover', function(d) {
          // Show the highlight
             d3.select(".highlight").style('visibility', 'visible');
             d3.select('.highlight').text(d.highlight);
             d3.select(this).style("background-color", "#c1c1c1");
          })
          .on("mouseout", function(){
          // Hide the highlight
            d3.select(".highlight").style('visibility', 'hidden');
            d3.select(this).style("background-color", "#f2f2f2");
          })
          .html(function(d){ return typeof(d.value)==="number"? 
    (100*d.value).toFixed(2)+"%":d.value;})
        .each(function (d, i) {
            if (i === 0){
                d3.select(this).style("font-weight", "bold")
            }
            else if (i=== 13)
            {
                d3.select(this).style("font-weight", "bold")
            }
        });

    d3.selectAll('tr.row_fd').selectAll('td')
        .style('border-bottom-color', "#f2f2f2")
        .style('border-top-color', "#f2f2f2");
    d3.selectAll('tr.row_mkt').selectAll('td')
        .style('border-bottom-color', "#f2f2f2")
        .each(function (d, i) {
            if (i === 0){
                d3.select(this).text("mkt")
            }});
    d3.selectAll('tr.row_bchk').selectAll('td')
        .style('border-top-color', "#f2f2f2")
        .each(function (d, i) {
            if (i === 0){
                d3.select(this).text("bchk")
            }});


});
</script>

【问题讨论】:

  • 我们可以看看一小部分数据的样子吗?
  • 当然:我添加了数据['values']。 data['text'] 与 text 而不是 values 的格式完全相同

标签: d3.js


【解决方案1】:
  1. 我认为您使用each() 函数的目的是为了转换每个元素的绑定数据。但它只是为当前选择中的每个元素执行任意代码。无论您返回什么都不会影响绑定的数据。

  2. 1234563 .
  3. 在鼠标悬停时,您正在尝试选择具有highlight 类的元素。我在您的代码中的任何地方都看不到这个元素,所以我不确定您是否打算让每个 td 包含一个最初隐藏的 span.highlight 元素,或者页面上是否只有一个带有此类的元素.

解决方案

我认为您应该预先计算数据,以便值和突出显示的文本在同一个对象中。假设data['values']data['highlights'] 的长度总是相同的,你可以这样做:

processedData = data['values'].map((row, rowIndex) => {
  return columns.map(column => {
    return {
      column: column,
      value: row[column],
      highlight: data['highlight'][rowIndex][column]
    };
  });
});

然后您可以创建表格行和单元格,并按如下方式设置鼠标悬停事件(假设只有一个带有 highlight 类的元素):

// create a row for each object in the data
var rows = tbody.selectAll('tr')
  .data(processedData)
  .enter()
  .append('tr');

// create a cell in each row for each column
var cells = rows.selectAll('tr td')
  .data(function(row) { return row; })
  .enter()
  .append('td')
  .style("color", function(d){ return d.value <= 0 ? "red" : "green"})
  .text(d => d.value)
  .on('mouseover', function(d) {
    d3.select('.highlight').text(d.highlight);
  });

【讨论】:

  • 您好,旅鼠,非常好的解决方案。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
  • 2017-02-11
  • 2012-07-24
  • 1970-01-01
相关资源
最近更新 更多