【问题标题】:How to crossfilter histogram and scatterplot matrix in d3 v4?如何在 d3 v4 中交叉过滤直方图和散点图矩阵?
【发布时间】:2018-08-29 23:49:18
【问题描述】:

我在d3 中使用this kind of scatterplot matrix 和直方图作为两个视图。他们都从同一个csv 文件中获取数据。这是直方图的样子(x 轴):

刷直方图我使用下面的代码,类似于this snippet

    svg.append("g")
        .attr("class", "brush")
        .call(d3.brushX()
        .on("end", brushed));

    function brushed() {
        if (!d3.event.sourceEvent) return;
        if (!d3.event.selection) return; 
        var d0 = d3.event.selection.map(x.invert),
            d1 = [Math.floor(d0[0]*10)/10, Math.ceil(d0[1]*10)/10];

        if (d1[0] >= d1[1]) {
            d1[0] = Math.floor(d0[0]);
            d1[1] = d1[0]+0.1;
        }

        d3.select(this).transition().call(d3.event.target.move, d1.map(x));
    }

如何链接两个视图,这样当我刷直方图时,散点图矩阵会将刷过的点显示为 红色,而其他点则显示为 灰色

【问题讨论】:

  • @Cyber​​netic 我看不出这与我的问题有什么关系。我的是关于链接的,那个是关于为直方图的条形填充颜色的。
  • 你说“当我刷直方图时,散点图会将刷过的点显示为红色,而其他点显示为灰色?”
  • @Cyber​​netic 是的,我说 scatterplot 将显示拉丝点。该答案的散点图在哪里?它只回答刷直方图
  • 明白了。查看答案以获得可能的开始。

标签: javascript d3.js svg


【解决方案1】:

这可以帮助您入门

3 个 html 文件:

  • 2 用于视觉效果(histogram.html 和 scatter.html)
  • 1 将它们保存在 iframe (both.html) 中:

依赖:

  • jQuery(添加到所有 3 个文件)

创建 table,在 both.html 中包含 2 个单元格:

向每个单元格添加iframe

<iframe id='histo_frame' width='100%' height='600px' src='histo.html'></iframe>
<iframe id='scatter_frame' width='100%' height='600px' src='scatter.html'></iframe>

我正在使用这个histogram,还有这个scatterplot

添加 linky_dink 函数以调用 scatter.html 中的函数(见下文...):

function linky_dink(linked_data) {
   document.getElementById('scatter_frame').contentWindow.color_by_value(linked_data);
}

在您的 scatter.html 中将您的 cell.selectAll 函数更改为:

cell.selectAll("circle")
        .data(data)
        .enter().append("circle")
        .attr("cx", function(d) { return x(d[p.x]); })
        .attr("cy", function(d) { return y(d[p.y]); })
        .attr("r", 4)
        .attr('data-x', function(d) { return d.frequency }) // get x value being plotted
        .attr('data-y', function(d) { return d.year }) // get y value being plotted
        .attr("class", "all_circles") // add custom class 
        .style("fill", function(d) { return color(d.species); });
  }

注意添加的粗体行:

现在,我们的直方图圆形元素保留了 x 和 y 值,以及可用于定位的自定义类

创建一个 color_by_value 函数

function color_by_value(passed_value) {
    $('.all_circles').each(function(d, val) { 
    if(Number($(this).attr('data-x')) == passed_value) {
    $(this).css({ fill: "#ff0000" })
    }
    });
}

从上面我们知道这个函数会被父html文件的linky_dink函数调用。如果传递的值与圆圈的值匹配,它将重新着色为#ff0000。

最后,在 histogram.html 文件中查找 brushend() 函数。找到它说的地方: d3.selectAll("rect.bar").style("opacity", function(d, i) { .... 并更改为:

d3.selectAll("rect.bar").style("opacity", function(d, i) {
      if(d.x >= localBrushYearStart && d.x <= localBrushYearEnd || brush.empty()) {
      parent.linky_dink(d.y)
      return(1)
      } else {
      return(.4)
      }
    });

现在,除了控制画笔时的矩形不透明度外,我们还在 both.html 文件中调用我们的 linky_dink 函数,从而将任何画笔直方图值传递到散点图矩阵以重新着色。

结果

由于显而易见的原因,这不是最好的解决方案。它仅在刷亮结束时重新着色散点图。它通过扫描所有类来瞄准圈子,这是非常低效的。当刷亮离开这些值时,彩色圆圈不会不着色,因为这会压倒 linky_dink 函数。而且我想您宁愿不使用 iframe,更不用说 3 个独立文件了。最后,实际上并不需要 jQuery,因为 D3 提供了所需的功能。但是也没有发布解决方案,所以也许这会帮助您或其他人想出更好的答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-09
    • 1970-01-01
    • 1970-01-01
    • 2017-04-19
    • 2016-12-29
    • 1970-01-01
    • 2013-08-29
    • 2015-08-27
    相关资源
    最近更新 更多