使用Crossfilter和D3重绘直方图

时间:2012-08-06 07:48:38

标签: javascript visualization d3.js crossfilter

我正在调整Crossfilter库来查看我从Olympics收集的一些推文。我试图以两种方式扩展最初的例子:

  1. 我不想显示基于原始数据集的航班列表,而是显示由crossfilter当前选中的项目所键入的另一个数据集中的项目列表。
  2. 在不同数据源之间切换并重新加载直方图和表格。
  3. 我已经按计划工作了(1)。但是,第(2)部分给了我一些麻烦。我目前正在通过选择新的" sport"来更改数据集。显示或选择新的摘要算法。当切换其中任何一个时,我相信我应该首先删除先前创建和显示的过滤器,图表和列表,然后重新加载新数据。

    然而,对于前端可视化有点新,特别是D3和Crossfilter,我还没有想出如何做到这一点,也不确定如何最好地表达这个问题。

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

    Screen image of Fencing data after switching sports while filtering on Date

    如上所述,大部分代码都来自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 个答案:

答案 0 :(得分:13)

经过一夜的睡眠,解决方案来找我。

我只需要打电话

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

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