Search code examples
d3.jstime-seriesdc.jscrossfiltertimeserieschart

Timeseries line-chart in dc.js - time Dimension not working


I'm a newbie to d3 and dc.js and am trying to make a timeseries chart of stock prices.

For some reason, I can't get my time Dimension to work. I have a feeling it has something to do with the way my dates are formatted, and I've tried experimenting with this but have not been able to solve the problem.

My code is as follows

//create global variable 'stockpricedata' to store CSV data;  
var stockpricedata = [];

//create global variable to enable parsing of dateFormat
var dateFormat = d3.time.format('%d/%m/%Y');


//create function that will input CSV data and draw a timechart.
//this function is called in a seperate piece of code using queue.js
//the code that loads the CSV data is also executed separately to this code

function makeChart(error, data) {

  //First lets create a nested function that converts 'Test_Score' variable 
  //from char to numeric

  function convData(data) {

    stockpricedata = data;
    stockpricedata.forEach(function(d){ 
      d['Open'] = +d['Open']; 
      d['High'] = +d['High']; 
      d['Low'] = +d['Low']; 
      d['Close'] = +d['Close']; 
      d['Volume'] = +d['Volume'];    
      d['Adj Close'] = +d['Adj Close']; 
      d['Adj Close'] = +d['Adj Close'];
      d.daydate = dateFormat.parse(d.Date);


    });

    };

  //Call the function
  convData(data);


  //initiate crossfilter

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

  //test ndx object to ensure that it initiated correctly
  var n = ndx.groupAll().reduceCount().value();
  console.log(stockpricedata);
  console.log("Lets say there are " + n + " datapoints in my file"); //yes, this is showing a valid number, so this is working.


  //Create 'Date' dimension that returns the DAY.
  var DateDim = ndx.dimension(function(d) 
    {return d.daydate;}
    );
  console.log(DateDim.top(5))



  //Create 'Sum' grouping to Sum the price (there will only be 1 for each day, so should just show the stockprice) to calculate y-axis

  var PriceGroup = DateDim.group().reduceSum(function(d){return d.Close;}); //d.Close is the 'closing price' datapoint


  //create chart object and link it to HTML element
  var StockPriceChart  = dc.barChart('#histprice-line-chart');


  //create minDate and maxDate variables so that we can set the x-axis scale.

  var minDate = DateDim.bottom(1)[0].date;
  var maxDate = DateDim.top(1)[0].date;
  console.log("min date is " + minDate + " and max date is " + maxDate);

  //chart attributes
   StockPriceChart
      .width(600)
      .height(180)
      .dimension(DateDim) //x-axis (range of scores)
      .group(PriceGroup) //y-axis 
      .x(d3.time.scale().domain([minDate,maxDate]))
      .elasticY(true)
      .xAxisLabel('Time')
      .yAxisLabel('Price')
     //.xAxis();
     // .margins({top: 10, right: 20, bottom: 50, left: 50});

     // showtime!
    dc.renderAll();


};

The data seems to be loading and showing up in the console just fine. My original 'Date' field is formatted to D3 format in my 'daydate' variable. An example datapoint in the console is as follows:

200: Object Adj Close: 90.22737 Close: 93.8913 Date: "3/04/15" High: 93.8913 Low: 93.8913 Open: 93.8913 Volume: 0 daydate: Fri Apr 03 15 00:00:00 GMT+1100 (AEDT)

But for some reason the following code doesn't seem to be working.

var DateDim = ndx.dimension(function(d) 
{return d.daydate;}
);
console.log(DateDim).top(5); // ?!?!? why is this not working ?!?!?!?

I also get the following error in the console: 'Uncaught TypeError: Cannot read property 'top' of undefined', when I try log DateDim to the console.

Any help on this would be much appreciated!

Thanks,

J


Solution

  • The problem ended up being caused by too many datapoints being rendered in a barChart. Reducing the # of data points in 1 chart, as well as changing from .barChart to .lineChart solved this. Huge thanks @Ethan for helping troubleshoot this and solve a number of additional issues!