简体   繁体   English

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

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

I am using this kind of scatterplot matrix and a histogram as two views, in d3 .我在d3使用这种散点图矩阵和直方图作为两个视图。 Both of them get the data from the same csv file.他们都从同一个csv文件中获取数据。 This is how the histogram looks like ( x axis ):这是直方图的样子( x 轴): 直方图

To brush the histogram I use the code below, which is similar to 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));
    }

How can I link the two views, so that when I brush the histogram, the scatterplot matrix will show the brushed points as colored in red , and the other points as, lets say, grey ?如何链接这两个视图,以便在我刷直方图时,散点图矩阵将刷点显示为红色,其他点显示为灰色

This can get you started :这可以让你开始

3 html files: 3个html文件:

  • 2 for the visuals (histogram.html and scatter.html) 2 用于视觉效果(histogram.html 和 scatter.html)
  • 1 to hold them in iframes (both.html): 1 将它们保存在 iframes (both.html) 中:

Dependency:依赖:

  • jQuery (add to all 3 files) jQuery(添加到所有 3 个文件)

Create table with 2 cells in both.html: 2个细胞both.html创建

在此处输入图片说明

Add iframes to each cell:向每个单元格添加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>

在此处输入图片说明

I am using this histogram , and this scatterplot .我正在使用这个直方图和这个散点图

Add the linky_dink function to call the function inside your scatter.html (see below...):添加 linky_dink 函数以调用 scatter.html 中的函数(见下文...):

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

In your scatter.html change your cell.selectAll function to this:在您的 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); });
  }

Note the added lines in bold:请注意添加的粗体行:

在此处输入图片说明

Now our histogram circle elements retain the x and y values , along with a custom class we can use for targeting.现在我们的直方图圆元素保留了x 和 y 值,以及我们可以用于定位的自定义类

Create a color_by_value function :创建一个 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" })
    }
    });
}

We know from above this function will be called from the linky_dink function of the parent html file.我们从上面知道这个函数会从父 html 文件的 linky_dink 函数中调用。 If the passed value matches that of the circle it will be recolored to #ff0000.如果传递的值与圆圈的值匹配,它将被重新着色为 #ff0000。

Finally, look for the brushend() function inside your histogram.html file.最后,在 histogram.html 文件中查找Brushend() 函数 Find where it says: d3.selectAll("rect.bar").style("opacity", function(d, i) { .... and change to:找到它说的地方: 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)
      }
    });

Now, in addition to controlling the rect opacity on brushing, we are also calling our linky_dink function in our both.html file, thus passing any brushed histogram value onto the scatterplot matrix for recoloring.现在,除了控制刷亮时的 rect 不透明度之外,我们还在 both.html 文件中调用了 linky_dink 函数,从而将任何刷亮的直方图值传递到散点图矩阵上以进行重新着色。

Result :结果

在此处输入图片说明

Not the greatest solution for obvious reasons.由于显而易见的原因,这不是最好的解决方案。 It only recolors the scatterplot when the brushing ends.它仅在刷亮结束时重新着色散点图。 It targets circles by sweeping over all classes which is horribly inefficient.它通过扫描所有类来针对圈子,这是非常低效的。 The colored circles are not uncolored when the brushing leaves those values since this overwhelms the linky_dink function.当刷牙离开这些值时,彩色圆圈不是未着色的,因为这会压倒 linky_dink 函数。 And I imagine you'd rather not use iframes, let alone 3 independent files.我想你宁愿不使用 iframe,更不用说 3 个独立的文件了。 Finally, jQuery isn't really needed as D3 provides the needed functionality.最后,实际上并不需要 jQuery,因为 D3 提供了所需的功能。 But there was also no posted solution, so perhaps this will help you or someone else come up with a better answer.但是也没有发布解决方案,所以也许这会帮助您或其他人提出更好的答案。

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

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