K. Anthony
K. Anthony

Reputation: 79

D3 Timeline CSV Data

I am using the d3 Timeline plugin (https://github.com/jiahuang/d3-timeline) and I finally got it to where the viz can read my data. However, I now need to make it so that all entries for a particular student show on the same line. The viz is currently displaying each entry separately.

CSV data looks like this:

Start,End,Student,Event Type,tooltip
2015-May-27 20:08:15,2015-May-27 20:08:21,Student 338,Pretest,Student 338 spent 00:00:06 on Biological Chemistry test.  Student scored 100%.
2015-May-27 20:08:21,2015-May-27 20:08:30,Student 338,Learning Path,Student 338 spent 00:00:09 on Biological Buffers Website.  
2015-May-27 20:08:30,2015-May-27 20:08:34,Student 338,Learning Path,Student 338 spent 00:00:04 on Organic Molecules Textbook.  
2015-May-27 20:08:34,2015-May-27 20:08:36,Student 338,Learning Path,Student 338 spent 00:00:03 on Nucleic Acid Structure and Function Textbook 2. 

The viz file looks like this:

<script type="text/javascript">
window.onload = function() {

  var width = 800;
  var height = 700;


  var parseDate = d3.time.format("%Y-%b-%d %H:%M:%S").parse; //With parseDate, I define what my time data looks like for d3
  d3.csv("https://dl.dropboxusercontent.com/u/42615722/LeaP/biology-course2.csv", function(d){
    return {
        label : d.Student,
        eventType: d["Event Type"],
        times:[{"starting_time" : parseDate(d.Start),
                "ending_time" : parseDate(d.End)}], //the timeline plugin is looking for a times array of objects with these keys so they must be defined.
        info: d.tooltip
    };
    }, function(data) {
    console.log(data);


    function timelineRect() {

    var colorScale = d3.scale.ordinal().range(['#ed5565','#ffce54','#48cfad','#5d9cec','#ec87c0','#ac92ec','#4fc1e9','#fc6e51','#a0d468','#656d78'])
        .domain(['Pretest','Learning Path','Supplemental Info','Questions','Test Me','Remedial Page','Search Query','Recommended Reading','Search Results','Practice Questions']);
    var chart = d3.timeline()
        .colors( colorScale )
        .colorProperty('event_type')
        .rotateTicks(45)
        .stack(); //necessary to unstack all of the labels

    var svg = d3.select("#timeline1").append("svg").attr("width", width)
      .datum(data).call(chart);
  }
 timelineRect();

  });

    }
  </script>
</head>
<body>

  <div>
    <div id="timeline1"></div>
  </div>

</body>

None of the examples define domain for this and, unfortunately, all of the example data is given in arrays, instead of from a CSV. How can I define the data so that each entry with the same student label will appear on the same timeline row?

Upvotes: 3

Views: 1500

Answers (1)

Cyril Cherian
Cyril Cherian

Reputation: 32327

Problem 1

You are not grouping your csv data this can be done like this: What I mean is

//this will do the grouping
   var k = d3.nest()
    .key(function(d) {
      return d.label;
    }).entries(data);
  var b = [];
//this will make it in the format expected by d3 time line
  k.forEach(function(d) {
    var ob = {};
    ob.label = d.key;
    ob.times = [];
    b.push(ob);
    d.values.forEach(function(v) {
      ob.times.push(v.times);//collecting all the times
    });
    ob.times = [].concat.apply([], ob.times);
  });

Problem 2

You have to define the tick format

  .tickFormat({
    format: d3.time.format("%d-%m"),
    tickTime: d3.time.day,
    tickInterval: 20,
    tickSize: 6
  })

Refer this for d3 time format

Your data set is very close on seconds and so the rectangle are coming very small..:( i tried my level best to span it up.. best of luck with it :)

Working code here

Hope this helps!

Upvotes: 1

Related Questions