繁体   English   中英

如何在 d3 v4 中交叉过滤直方图和散点图矩阵?

[英]How to crossfilter histogram and scatterplot matrix in d3 v4?

我在d3使用这种散点图矩阵和直方图作为两个视图。 他们都从同一个csv文件中获取数据。 这是直方图的样子( x 轴): 直方图

要刷直方图,我使用下面的代码,它类似于此代码段

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

如何链接这两个视图,以便在我刷直方图时,散点图矩阵将刷点显示为红色,其他点显示为灰色

这可以让你开始

3个html文件:

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

依赖:

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

2个细胞both.html创建

在此处输入图片说明

向每个单元格添加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>

在此处输入图片说明

我正在使用这个直方图和这个散点图

添加 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)
      }
    });

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

结果

在此处输入图片说明

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM