【问题标题】:DC.JS dynamic filtered range on histograms直方图上的 DC.JS 动态过滤范围
【发布时间】:2017-01-06 13:14:25
【问题描述】:

就我而言,我想动态调整我的 DC 仪表板中多个直方图中使用的数据范围。例如,在图形“猫”上应用过滤器,我希望图形“深度”的边界可以使用 elasticX 功能进行调整。但这种情况并非如此。

有没有办法在应用过滤器后动态调整 depthRange 和 catRange ?非常感谢您提前的支持。

HTML代码如下:

<div id="chart-depth">
  <div>Depth</div>
  <a class="reset" href="javascript:depthChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
  <span class="reset" style="display: none;"><span class="filter"></span></span>
  <br>
  <br>
</div>

<div id="chart-cat">
  <div>Cat</div>
  <a class="reset" href="javascript:catChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
  <span class="reset" style="display: none;"><span class="filter"></span></span>
  <br>
  <br>
  </div>


<div id="dataTable" style="height: 300px;">
  <div class='header'>
    <span>Id</span>
    <span>Cat</span>
    <span>Depth</span>
  </div>
</div>

JS代码如下:

 //================================================================
    points = [];
    for (var i = 1; i < 100; i++) {
      points.push({
        Id: i,
        Cat: Math.random()*120.,
        Depth: Math.random() * 6000.
      });
    }

    //================================================================
    var filter;
    var depthDimension;
    var catDimension;
    var depthGrouping;
    var catGrouping;

    //-----------------------------------
    filter = crossfilter(points);

    // Threshold has to be put on dimension not on group
    // to get last bin filled with thresholded values
    // Compare with https://jsfiddle.net/PBrockmann/ma3wr55k/

    //-----------------------------------
    depthRange = [0., 5000.];
    catRange=[0.,100.];
    depthBinWidth = 500.;
    catBinWidth = 2.;
    depthDimension = filter.dimension(function(d) {
      // Threshold
      var depthThresholded = d.Depth;
      if (depthThresholded <= depthRange[0]) depthThresholded = depthRange[0];
      if (depthThresholded >= depthRange[1]) depthThresholded = depthRange[1] - depthBinWidth;
      return depthBinWidth * Math.floor(depthThresholded / depthBinWidth);
    });

    catDimension=filter.dimension(function(d){
        // Threshold
      var catThresholded = d.Cat;
      if (catThresholded <= catRange[0]) catThresholded = catRange[0];
      if (catThresholded >= depthRange[1]) catThresholded = catRange[1] - catBinWidth;
      return catBinWidth * Math.floor(catThresholded / catBinWidth);
    });

    catGrouping=catDimension.group();
    depthGrouping = depthDimension.group(); // by default reduceCount

    //-----------------------------------
    depthChart = dc.barChart("#chart-depth");
    catChart=dc.barChart("#chart-cat");
    dataTable = dc.dataTable("#dataTable");

    //-----------------------------------
    depthChart
      .width(380)
      .height(200)
      .margins({
        top: 10,
        right: 20,
        bottom: 30,
        left: 30
      })
      .centerBar(false)
      .elasticY(true)
      .elasticX(true)
      .dimension(depthDimension)
      .group(depthGrouping)
      .x(d3.scale.linear().domain(depthRange))
      .xUnits(dc.units.fp.precision(depthBinWidth))
      .round(function(d) {
        return depthBinWidth * Math.floor(d / depthBinWidth)
      })
      .renderHorizontalGridLines(true);

    xAxis_depthChart = depthChart.xAxis();
    xAxis_depthChart.tickFormat(d3.format("d"));
    yAxis_depthChart = depthChart.yAxis();
    yAxis_depthChart.ticks(6).tickFormat(d3.format("d")).tickSubdivide(0); // tickSubdivide(0) should remove sub ticks but not

    catChart
      .width(380)
      .height(200)
      .margins({
        top: 10,
        right: 20,
        bottom: 30,
        left: 30
      })
      .centerBar(false)
      .elasticY(true)
      .elasticX(true)
      .dimension(catDimension)
      .group(catGrouping)
      .x(d3.scale.linear().domain(catRange))
      .xUnits(dc.units.fp.precision(catBinWidth))
      .round(function(d) {
        return catBinWidth * Math.floor(d / catBinWidth)
      })
      .renderHorizontalGridLines(true);




    //-----------------------------------
    dataTable
      .dimension(depthDimension)
      .group(function(d) {
        return d.Id + "   " + d.Cat + "   " + d.Depth; // Data table does not use crossfilter group but rather a closure as a grouping function
      })
      .size(30);

    //-----------------------------------
    dc.renderAll();

【问题讨论】:

    标签: dc.js crossfilter


    【解决方案1】:

    我认为除了elasticX(true) 之外,您在这里寻找的是能够在垃圾箱为空时移除垃圾箱的能力。

    Crossfilter 仍会为那些现在聚合为零的 bin 报告值为零,并且 dc.js 将忠实地绘制它们。我认为我们不想总是假设不应该绘制零,因此我们需要预处理 crossfilter 和 dc.js 之间的数据以删除空 bin。

    最好的技术,记录在in the FAQ,是创建一个“假组”,它包装交叉过滤组并过滤它。

    function remove_empty_bins(source_group) {
        return {
            all:function () {
                return source_group.all().filter(function(d) {
                    return d.value != 0;
                });
            }
        };
    }
    

    像这样使用它:

    depthGroup.group(remove_empty_bins(depthGrouping))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-11
      • 2019-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多