如何使用 dc.js 创建多线图

Posted

技术标签:

【中文标题】如何使用 dc.js 创建多线图【英文标题】:how to create multiline chart using dc.js 【发布时间】:2014-05-26 11:00:21 【问题描述】:

我正在使用基于 d3 和 crossfilter 的 Dimensional Charting javascript 库 dc.js 制作多折线图。我是 dc.js 库中的新手。我正在尝试使用 csv 文件显示多线图。我无法理解如何按照 csv 格式创建多线图。

我的 csv 列格式是

 Age_19_Under   Age_19_64   Age_65_84   Age_85_and_Over
    26.9              62.3            9.8               0.9
    23.5              60.3            14.5              1.8
    24.3              62.5            11.6              1.6
    24.6              63.3            10.9              1.2
    24.5              62.1            12.1              1.3
    24.7              63.2            10                2.2
    25.6              58.5            13.6              2.4
    24.1              61.6            12.7              1.5
    24.8              59.5            13.5              2.2

我正在尝试愚弄代码:

 % extends "base.html" %
 % load staticfiles %
 % block content %
 <head>
 <link href="% static 'css/dc.css' %"  rel="stylesheet" media="screen">
 <link href="% static 'css/example-styles.css' %"  rel="stylesheet" media="screen">
 </head>
 <div class="container" style="margin-top: 140px">

     <div class="col-lg-12" id="chart-row-Poverty1">
     </div>
 </div>
 <script type="text/javascript" src="% static 'js/d3.js' %"></script>
 <script type="text/javascript" src="% static 'js/crossfilter.js' %"></script>
 <script type="text/javascript"  src="% static 'js/dc.js' %"></script>
 <script type="text/javascript"  src="% static 'js/bootstrap.min.js' %"></script>
 <script type="text/javascript"   src="% static 'js/d3.js' %"></script>
 <script type="text/javascript"   src="% static 'js/index.js' %"></script>
 <script type="text/javascript">

  var lineChart1=dc.compositeChart("#chart-row-Poverty1");
 var g;

d3.csv("% static 'sampledata/helthdata.csv' %", function(error, experiments) 

 var dateFormat = d3.time.format("%Y");
 var numberFormat = d3.format(",f");

 var ndx = crossfilter(experiments);
 var all = ndx.groupAll();

var runDimension = ndx.dimension(function(d) return [+d.Age_19_Under, +d.Age_19_64,   +d.Age_65_84,+d.Age_85_and_Over]; );
var runGroup = runDimension.group().reduceSum(function(d)  return 1; );

lineChart1.width(1160)
.height(250)
.margins(top: 10, right: 10, bottom: 20, left: 40)
.dimension(runDimension)
.group(runGroup)
.transitionDuration(500)
.elasticY(true)
.brushOn(false)
.valueAccessor(function (d) 
                return d.value;
            )
.title(function(d)
  return "\nNumber of Povetry: "+d.key;

  )
.x(d3.scale.linear().domain([4, 27]))
.xAxis();

 dc.renderAll();


 );

</script>
% endblock %

【问题讨论】:

【参考方案1】:

将维度视为您希望沿 X 轴查看的值,将组视为您希望将 X 轴上任何一个坐标的数据组合成单个 Y 值的方式会有所帮助.这样,一组代表多线图上一条线的数据。一旦你解决了这个问题,你就需要在 dc.js 中创建 N+1 个图表。也就是说,您要查看的每个图表对应一个 lineChart,然后是一个 CompositeChart 将它们收集在一起。单独的 lineCharts 可以非常简单,因为它们会从包含它们的 compositeChart 继承许多属性。

直到我整理完下面的代码,我才注意到您为 X 轴设置的实际值,并意识到我认为我可能误解了您真正想要做的事情。对于那个很抱歉。希望它仍能为您阐明基本思想。

var experiments = [
     Run: 1, Age_19_Under: 26.9, Age_19_64: 62.3, Age_65_84: 9.8, Age_85_and_Over: 0.9 ,
     Run: 2, Age_19_Under: 23.5, Age_19_64: 60.3, Age_65_84: 14.5, Age_85_and_Over: 1.8 ,
     Run: 3, Age_19_Under: 24.3, Age_19_64: 62.5, Age_65_84: 11.6, Age_85_and_Over: 1.6 ,
     Run: 4, Age_19_Under: 24.6, Age_19_64: 63.3, Age_65_84: 10.9, Age_85_and_Over: 1.2 ,
     Run: 5, Age_19_Under: 24.5, Age_19_64: 62.1, Age_65_84: 12.1, Age_85_and_Over: 1.3 ,
     Run: 6, Age_19_Under: 24.7, Age_19_64: 63.2, Age_65_84: 10, Age_85_and_Over: 2.2 ,
     Run: 7, Age_19_Under: 25.6, Age_19_64: 58.5, Age_65_84: 13.6, Age_85_and_Over: 2.4 ,
     Run: 8, Age_19_Under: 24.1, Age_19_64: 61.6, Age_65_84: 12.7, Age_85_and_Over: 1.5 ,
     Run: 9, Age_19_Under: 24.8, Age_19_64: 59.5, Age_65_84: 13.5, Age_85_and_Over: 2.2 ,
];

var ndx = crossfilter(experiments);
var all = ndx.groupAll();

var runDimension = ndx.dimension(function (d)  return d.Run; );

var age19UnderGroup = runDimension.group().reduceSum(function (d)  return d.Age_19_Under; );
var age19To64Group = runDimension.group().reduceSum(function (d)  return d.Age_19_64; );
var age65To84Group = runDimension.group().reduceSum(function (d)  return d.Age_65_84; );
var age85AndOverGroup = runDimension.group().reduceSum(function (d)  return d.Age_85_and_Over; );

lineChart1.width(1160)
    .height(250)
    .margins( top: 10, right: 10, bottom: 20, left: 40 )
    .dimension(runDimension)
    .transitionDuration(500)
    .elasticY(true)
    .brushOn(false)
    .valueAccessor(function (d) 
        return d.value;
    )
    .title(function (d) 
        return "\nNumber of Povetry: " + d.key;

    )
    .x(d3.scale.linear().domain([4, 27]))
    .compose([
        dc.lineChart(lineChart1).group(age19UnderGroup),
        dc.lineChart(lineChart1).group(age19To64Group),
        dc.lineChart(lineChart1).group(age65To84Group),
        dc.lineChart(lineChart1).group(age85AndOverGroup)
    ])
;

dc.renderAll();

请注意我是如何在您的数据中插入“运行”属性来为维度创建统一值的。我选择整数是因为它们很简单,但值也可以是日期、实验名称,或者在数据中创建一行的任何内容。数据集中的值直接显示在图表中,因为我选择的维度具有所有唯一值。如果有重复的值(比如第 10 行,Measurement = 9,每个年龄范围的值为 10),那么给定维度值的所有数据将通过 .reduceSum() 方法汇总在一起(因此,一个值X 轴上的 9 为 34.8)。

【讨论】:

作曲对我不起作用..知道为什么。我得到未知的功能 @Dilip - 没有看到实际代码很难说。我可以说的一件事是,如果您像上面的示例一样将方法链接在一起,那么顺序可能很重要,因为我记得,这些方法并不都返回完全相同的对象类型。很容易陷入这样的陷阱:认为 .compose() 正在被 lineChart1 调用,而实际上它被调用到从对 .x() 的调用返回的任何内容上。 如果您收到 compose 不是函数的错误,请确保将原始图表类型设置为 compositionChart。 (例如 var lineChart1=dc.compositeChart("#chart-row-Poverty1");)然后您可以在您提供给 compose 的每个参数上定义单独的图表类型。

以上是关于如何使用 dc.js 创建多线图的主要内容,如果未能解决你的问题,请参考以下文章

如何使用dc.js进行放大刷牙

如何在箱形图dc.js中仅显示有限数量的记录

多个链接的 dc.js 图表的 d3-tooltips

dc.js饼图图例溢出

DC-js 中的多系列条形图

光学字符识别多线检测