how to create multiline chart using dc.js
Asked Answered
L

1

8

I'm making a multi line chart using the Dimensional Charting javascript library dc.js, which is based on d3 and crossfilter. i am new in dc.js library.i am trying to display the multiline chart using csv file.i cant understand how to create multiline chart following csv format.

my csv column format is

 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

i am trying foolowing code:

 {% 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 %}
Legislative answered 12/4, 2014 at 6:30 Comment(0)
P
18

It can help to think of the dimension as being the values you want to see along the X-axis and the groups as being how you want the data for any one coordinate on the X-axis grouped together into a single Y value. In this way, one group represents the data for one line on your multiline graph. Once you've got that worked out then you need to create N+1 charts in dc.js. That is, one lineChart for each graph you want to see and then one compositeChart to gather them all together. The individual lineCharts can be pretty simple because they'll inherit many properties from the compositeChart they're contained in.

It wasn't until I finished putting together the code below I noticed the actual values you set for the X axis and realized that I think I may have misinterpreted what you are really trying to do. Sorry about that. Hopefully it will still illustrate the fundamental ideas for you.

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();

Notice how I inserted a "Run" property in your data to create a unifying value for the dimension. I chose integers because they're easy, but the values could just as well be dates, or names of experiments, or whatever it is that creates a row in your data. The values in your data set show up directly in the graph because my choice of dimension has all unique values. Had there been repeated values (say a 10th row with Measurement = 9 and a value of 10 for each age range) then all the data for a given dimension values would have been summed together by the .reduceSum() method (so, a value of 34.8 for 9 on the X-axis).

Paleolithic answered 20/4, 2014 at 20:3 Comment(3)
compose not working for me.. any idea why. I get unknown functionMullah
@Dilip - It's hard to say without seeing the actual code. One general thing I can say is that if you're chaining methods together like in the example above then the order can matter because, as I recall, the methods don't all return the exact same object type. It's easy to fall into the trap of thinking that .compose() is being called on lineChart1 when it's really being called on whatever is returned from the call to .x().Paleolithic
If you get an error that compose is not a function, make sure you set the original chart type to compositeChart. (ex. var lineChart1=dc.compositeChart("#chart-row-Poverty1");) Then you can define the individual chart type on each argument you give to to compose.Brister

© 2022 - 2024 — McMap. All rights reserved.