2013-02-12 74 views
1

中工作d3.js,我正在寻找一种显示分类时间序列数据的好方法。数据值不能共现,也不是均匀间隔,所以我的数据完全一样:d3.js分类时间序列(evolustrip)

location = [[time1: home], [time4: work], [time5: cafe], [time7: home]] 

等等。我的理想结果图像类似于可称为evolustrip的东西 - 查看此图表的一种方式是以可变宽度条形式显示的时间系列图表,条形颜色对应于类别(例如“主页”)。

任何人都可以指向正确的方向吗?非常感谢!

回答

1

所以我结束了各具特色我自己d3.js解决方案:

我用d3.time.scale规模为时间维度,然后d3.scale.category20规模为类别的颜色。然后,我将分类数据绘制为时间轴上开始时间的高度相关值,并使用d3.time.scale比例来计算每个矩形的相应箱宽。

可重用的组件(以下在http://bost.ocks.org/mike/chart/模式)的例子可以看这里:

function timeSeriesCategorical() { 
    var w = 860, 
     h = 70, 
     margin = {top: 20, right: 80, bottom: 30, left: 50}, 
     width = w - margin.left - margin.right, 
     height = h - margin.top - margin.bottom; 
    var xValue = function(d) { return d[0]; }, 
     yValue = function(d) { return d[1]; }; 
    var yDomain = null; 
    var xScale = d3.time.scale() 
     .range([0, width]); 
    var yScale = d3.scale.category20(); 
    var xAxis = d3.svg.axis() 
     .scale(xScale) 
     .tickSubdivide(1) 
     .tickSize(-height) 
     .orient('bottom'); 
    var yAxis = d3.svg.axis() 
     .scale(yScale) 
     .ticks(5) 
     .orient('left'); 
    var binwidth = 20; 

    function chart(selection) { 
     selection.each(function(data) { 

      // convert data to standard representation 
      data = data.map(function(d, i) { 
       return [xValue.call(data, d, i), yValue.call(data, d, i)]; 
       //return d; 
      }); 

      // scale the x and y domains based on the actual data 
      xScale.domain(d3.extent(data, function(d) { return d[0]; })); 
      if (!yDomain) { 
       yScale.domain(d3.extent(data, function(d) { return d[1]; })); 
      } else { 
       yScale.domain(yDomain); 
      } 

      // compute binwidths for TODO better comment 
      // d looks like {timestamp, category} 
      data.forEach(function(d, i) { 
       if (data[i+1]) { 
        w_current = xScale(data[i][0]); 
        w_next = xScale(data[i+1][0]); 
        binwidth = w_next - w_current; 
       } 
       d.binwidth = binwidth; 
      }); 

      // create chart space as svg 
      // note: 'this' el should not contain svg already 
      var svg = d3.select(this).append('svg').data(data); 

      // external dimensions 
      svg.attr('width', w) 
       .attr('height', h); 

      // internal dimensions 
      svg = svg.append('g') 
       .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); 

      // x axis 
      svg.append('g') 
       .attr('class', 'x axis') 
       .attr('transform', 'translate(0,' + height + ')') 
       .call(xAxis); 

      // TODO bars legend 

      // bars 
      svg.selectAll('rect') 
       .data(data) 
       .enter().append('rect') 
       .attr('x', function(d, i) { return xScale(d[0]); }) 
       .attr('width', function(d, i) { return d.binwidth; }) 
       .attr('height', height) 
       .attr('fill', function(d, i) { return yScale(d[1]); }) 
       .attr('stroke', function(d, i) { return yScale(d[1]); }); 

     }); 
    } 

    chart.x = function(_) { 
     if (!arguments.length) return xValue; 
     xValue = _; 
     return chart; 
    }; 

    chart.y = function(_) { 
     if (!arguments.length) return yValue; 
     yValue = _; 
     return chart; 
    }; 

    chart.yDomain = function(_) { 
     if (!arguments.length) return yDomain; 
     yDomain = _; 
     return chart; 
    }; 

    return chart; 
} 

而且是可调用的东西,如:

d3.csv('./data.csv', function(data) { 
    var chartActivity = timeSeriesCategorical() 
     .x(function(d) { return d.when; }) 
     .y(function(d) { return d.activity; }) 
     .yDomain([0,1]); 
    d3.select('#chart-activity') 
     .datum(data) 
     .call(chartActivity); 
}); 

但愿这是有帮助的人!这个项目是在https://github.com/interaction-design-lab/stress-sense-portal

+0

非常酷:)做得很好。 – 2015-05-25 20:09:09