使用 Crossfilter 和 D3 重绘直方图

Posted

技术标签:

【中文标题】使用 Crossfilter 和 D3 重绘直方图【英文标题】:Redrawing histograms with Crossfilter and D3 【发布时间】:2012-08-03 04:36:53 【问题描述】:

我正在调整Crossfilter 库以可视化我从Olympics 收集的一些推文。我试图以两种方式从本质上扩展初始示例:

    我不想显示基于原始数据集的航班列表,而是显示另一个数据集中的项目列表,该数据集中由交叉过滤器当前选择的项目作为键。 在不同的数据源之间切换并重新加载直方图和表格。

我的第 (1) 部分已按计划进行。但是,第 (2) 部分给我带来了一些麻烦。我目前正在通过选择要显示的新“运动”或选择新的汇总算法来更改数据集。在切换其中任何一个时,我认为我应该先删除之前创建和显示的过滤器、图表和列表,然后重新加载新数据。

但是,对于前端可视化,尤其是 D3 和 Crossfilter,我还不太熟悉,我也不知道如何最好地表达这个问题。

我有一个关于我的问题here 的工作示例。在 Date 上选择一个范围,然后从 Archery 切换到 Fencing,然后选择 reset 显示了一个很好的错误示例:并非所有新数据都被绘制。

如前所述,大部分代码都是从Crossfilter 示例和Tutorial on making radial visualizations 中提取的。以下是我认为相关的一些关键代码块:

选择一个新的数据源:

d3.selectAll("#sports a").on("click", function (d) 
    var newSport = d3.select(this).attr("id");
    activate("sports", newSport);
    reloadData(activeLabel("sports"), activeLabel("methods"));
);                          

d3.selectAll("#methods a").on("click", function (d) 
    var newMethod = d3.select(this).attr("id");
    activate("methods", newMethod);
    reloadData(activeLabel("sports"), activeLabel("methods"));
); 

重新加载数据:

function reloadData(sportName, methodName) 
    var filebase = "/tweetolympics/data/tweet." + sportName + "." + methodName + ".all.";
    var summaryList, tweetList, remaining = 2;
    d3.csv(filebase + "summary.csv", function(summaries) 
        summaries.forEach(function(d, i) 
           d.index = i;
           d.group = parseInt(d.Group);
           d.startTime = parseTime(d.Start);
           d.meanTime = parseTime(d.Mean);
        );
        summaryList = summaries;
        if (!--remaining)
            plotSportData(summaryList, tweetList);
    );

    d3.csv(filebase + "groups.csv", function(tweets) 
        tweets.forEach(function(d, i) 
            d.index = i;
            d.group = parseInt(d.Group);
            d.date = parseTime(d.Time);
        );
        tweetList = tweets;
        if (!--remaining)
            plotSportData(summaryList, tweetList);
    );
   

并使用数据加载交叉过滤器:

function plotSportData(summaries, tweets) 

    // Create the crossfilter for the relevant dimensions and groups.
    var tweet = crossfilter(tweets),
        all = tweet.groupAll(),
        date = tweet.dimension(function(d)  return d3.time.day(d.date); ),
        dates = date.group(),
        hour = tweet.dimension(function(d)  return d.date.getHours() + d.date.getMinutes() / 60; ),
        hours = hour.group(Math.floor),
        cluster = tweet.dimension(function(d)  return d.group; ),
        clusters = cluster.group();

     var charts = [
        // The first chart tracks the hours of each tweet.  It has the
        // standard 24 hour time range and uses a 24 hour clock.
        barChart().dimension(hour)
                  .group(hours)
                  .x(d3.scale.linear()
                             .domain([0, 24])
                             .rangeRound([0, 10 * 24])),
        // more charts added here similarly...
      ];

    // Given our array of charts, which we assume are in the same order as the
    // .chart elements in the DOM, bind the charts to the DOM and render them.
    // We also listen to the chart's brush events to update the display.
    var chart = d3.selectAll(".chart")
                  .data(charts)
                  .each(function(chart)  chart.on("brush", renderAll)
                                               .on("brushend", renderAll); );

    // Render the initial lists.
    var list = d3.selectAll(".list")
                 .data([summaryList]);

    // Print the total number of tweets.
    d3.selectAll("#total").text(formatNumber(all.value()));

    // Render everything..
    renderAll();

我的猜测是我应该从清除旧数据集的东西开始plotSportData,但我不确定它应该是什么样子。任何建议或想法将不胜感激。

【问题讨论】:

【参考方案1】:

睡了一夜之后,我找到了解决方案。

我只需要打电话

d3.selectAll(".chart").selectAll("svg").remove();

plotSportData 的开头,它将抓取嵌套在.chart div 下的任何直方图并将其删除。如果没有要删除的元素,那将是无操作的。

【讨论】:

感谢分享,crossfilter可用的例子不多。祝你的项目好运。

以上是关于使用 Crossfilter 和 D3 重绘直方图的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法告诉 crossfilter 将数组元素视为单独的记录,而不是将整个数组视为单个键?

d3.js 画笔填充颜色直方图

.data() 处的 D3 新数据使 svg 重绘而不是更新节点位置

d3 几种常用的柱状图

crossfilter.js & dc.js:对要使用的维度和事实的数量有限制吗?

text 带有D3直方图的CARTO 4.0