Re: [dc.js users] Cannot read property 'getFullYear' of null

929 views
Skip to first unread message

Gordon Woodhull

unread,
Aug 3, 2016, 2:35:05 PM8/3/16
to dc.js user group
Hi Daniela,

dc.js doesn't automatically infer anything from your data - you have to define the groups and dimensions yourself and can't use the code from the stock.js file for this. That code is for looking at fluctuations in the stock market. 

I'd recommend starting with a small example and really understanding how the code works, rather than trying to copy and paste from a much larger dashboard like that one. For instance, this simple filtering example is less than 100 lines and should give you a sense of how the library works:


You probably want at least a year dimension and group summing bitrates, after parsing your dates, and maybe other dimensions depending how you want to filter your data.

You'll also want to read the crossfilter documentation. It is somewhat terse but you can get the concepts there:


Finally, there are some other dc.js tutorials listed here:


Cheers,
Gordon


On Aug 3, 2016, at 1:16 PM, DaniB <danielabran...@gmail.com> wrote:

Hi all,

I am trying to implement the line graph and the data table(new to D3,crossfilter ,dc.js). I would like to sum bitrate per channel per year. I keep getting the message error "Cannot read property 'getFullYear' of null" coming from the d3.js file:

Here is the html code (index.html):

 

<!DOCTYPE html>

<html lang="en">

<head>

    <!--<title>dc.js - Dimensional Charting Javascript Library</title>-->

 

    <meta charset="UTF-8">

 

    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">

    <link rel="stylesheet" type="text/css" href="css/dc.css"/>

    <!--<link rel="icon" type="image/x-icon" href="dc.logo.png"/>-->

 

    <style>

        #monthly-volume-chart g.y {

            display: none;

        }

        #logo {

            margin-right: 2em;

            margin-top: 2em;

            display: none;

        }

    </style>

</head>

<body>

 

<div class="container">

 

<!--<img id="logo" src="dc.logo.png" style="float:left" width=125 height=125></img>-->

<!--<h2>dc.js - Dimensional Charting Javascript Library</h2>-->

 

 

<p>

    <!--dc.js is a javascript charting library with native <a href="http://square.github.com/crossfilter/">crossfilter</a>

    support and allowing highly efficient exploration on large multi-dimensional dataset (inspired by crossfilter's

    demo). It leverages <a href="http://d3js.org/">d3</a> engine to render charts in css friendly svg format. Charts

    rendered using dc.js are naturally data driven and reactive therefore providing instant feedback on user's

    interaction. The main objective of this project is to provide an easy yet powerful javascript library which can be

    utilized to perform data visualization and analysis in browser as well as on mobile device.-->

</p>

 

<!--<h4>Version Status</h4>

<p>This page is running version: v<span id="version"></span>. The latest stable version is v<span id="latest"></span>.</p>

 

<h4>Getting Started</h4>

<p>

    Take a look at the <a href="docs/stock.html">annotated source</a> to the Nasdaq Example that is shown below.

</p>

 

<h4>For more information and assistance</h4>-->

<!--<ul>

  <li><a href="http://github.com/dc-js/dc.js/releases/">Release Notes</a></li>

  <li><a href="https://github.com/dc-js/dc.js/wiki">Wiki</a> - Additional examples</li>

  <li><a href="https://github.com/dc-js/dc.js/wiki/Roadmap">Roadmap</a> - Future Plans</li>

  <li><a href="https://github.com/dc-js/dc.js/blob/master/web/docs/api-1.6.0.md">Stable API</a> - Documentation</li>

  <li><a href="https://github.com/dc-js/dc.js/blob/master/web/docs/api-latest.md">Master API</a> - Bleeding Edge</li>

  <li><a href="https://groups.google.com/forum/?fromgroups#!forum/dc-js-user-group">Mailing List</a> - The users group and best place to post support questions.</li>

  <li><a href="https://github.com/dc-js/dc.js/issues">Issues</a> - Please post any issues you have found or enhancements you would like to see. Usage questions should be directed to the mailing list</li>

</ul>

 

<p>

    Fork me @ <a href="https://github.com/dc-js/dc.js">https://github.com/dc-js/dc.js</a> and also feel free

    to report any issue or request a new type of chart to be included in the next release.

</p>

 

<h3>Examples</h3>

 

<p>

    The following charts provide a live example of dc.js used against Nasdaq 100 index for the last 27 years. (You

    can run this example completely off-line). Although it is just an example, using it you can

    already ask some quite interesting questions. If I am going to gamble whether Nasdaq 100 will gain or lose

    tomorrow what is my chance? Is Friday or Monday the most unlucky day for investors? Is spring better than winter to

    invest? Can you find the outliers? When did the outliers occur?

 

    Public data source: <a href="http://pitrading.com/free_market_data.htm" target="_blank">PiTrading.com</a>.

</p>

 

<p>

    Try it out or check out these other examples.

</p>

<ul>

    <li><a href="vc/index.html">US Venture Capital Landscape 2011 (choropleth chart, bubble chart)</a></li>

    <li><a href="crime/index.html">Major Canadian City Crime Stats 1998-2011 (bubble overlay, bar chart, line chart)</a></li>

    <li><a href="https://github.com/dc-js/dc.js/wiki#examples-contributed-by-community">List of Community Contributed Examples</a></li>

    <li><a href="./examples">Simple, Specific Chart Examples</a> (<a href="https://github.com/dc-js/dc.js/tree/master/web/examples">source</a>)</li>

</ul>-->

 

<!--<h2>Nasdaq 100 Index 1985/11/01-2012/06/29</h2>-->

    <h2>Nasdaq </h2>

 

<!--<div class="row" style="display:none">

    <div id="yearly-bubble-chart" class="dc-chart">

        <strong>Yearly Performance</strong> (radius: fluctuation/index ratio, color: gain/loss)

        <a class="reset" href="javascript:yearlyBubbleChart.filterAll();dc.redrawAll();"

           style="display: none;">reset</a>

 

        <div class="clearfix"></div>

    </div>

</div>-->

 

<!--<div class="row">

    <div id="gain-loss-chart" style="display:none">

        <strong>Days by Gain/Loss</strong>

        <a class="reset" href="javascript:gainOrLossChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>

 

        <div class="clearfix"></div>

    </div>

 

    <div id="quarter-chart" style="display:none">

        <strong>Quarters</strong>

        <a class="reset" href="javascript:quarterChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>

 

        <div class="clearfix"></div>

    </div>

 

    <div id="day-of-week-chart" style="display:none">

        <strong>Day of Week</strong>

        <a class="reset" href="javascript:dayOfWeekChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>

 

        <div class="clearfix"></div>

    </div>

 

    <div id="fluctuation-chart" style="display:none">

        <strong>Days by Fluctuation(%)</strong>

        <span class="reset" style="display: none;">range: <span class="filter"></span></span>

        <a class="reset" href="javascript:fluctuationChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>

        <div class="clearfix"></div>

    </div>

</div>-->

 

<div class="row">

    <div id="monthly-move-chart">

        <!--<strong>Monthly Index Abs Move & Volume/500,000 Chart</strong>-->

        <span class="reset" style="display: none;">range: <span class="filter"></span></span>

        <a class="reset" href="javascript:moveChart.filterAll();volumeChart.filterAll();dc.redrawAll();"

           style="display: none;">reset</a>

        <div class="clearfix"></div>

    </div>

</div>

 

   

<!--<div class="row" style="display:none">

    <div id="monthly-volume-chart">

    </div>

    <p class="muted pull-right" style="margin-right: 15px;">select a time range to zoom in</p>

</div>-->

 

 

 

    <div class="row">

        <div id="monthly-move-chart-daniela">

            <strong></strong>

            <span class="reset" style="display: none;">range: <span class="filter"></span></span>

            <a class="reset" href="javascript:moveChart.filterAll();volumeChart.filterAll();dc.redrawAll();"

               style="display: none;">reset</a>

            <div class="clearfix"></div>

        </div>

    </div>

 

 

<div class="row">

    <div>

        <div class="dc-data-count">

            <span class="filter-count"></span> selected out of <span class="total-count"></span> records | <a

                href="javascript:dc.filterAll(); dc.renderAll();">Reset All</a>

        </div>

    </div>

    <table class="table table-hover dc-data-table">

    </table>

</div>

 

<div class="clearfix"></div>

 

<!--<a href="https://github.com/dc-js/dc.js"><img style="position: absolute; top: 0; right: 0; border: 0;"

                                                  src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"

                                                  alt="Fork me on GitHub"></a>-->

</div>

 

<!--</div>-->

 

<script type="text/javascript" src="js/d3.js"></script>

<script type="text/javascript" src="js/crossfilter.js"></script>

<script type="text/javascript" src="js/dc.js"></script>

<script type="text/javascript" src="js/colorbrewer.js"></script>

<script type="text/javascript" src="stock_sxm.js"></script>

 

<script type="text/javascript">

    var _gaq = _gaq || [];

    _gaq.push(['_setAccount', 'UA-33628816-1']);

    _gaq.push(['_trackPageview']);

 

    (function () {

        var ga = document.createElement('script');

        ga.type = 'text/javascript';

        ga.async = true;

        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';

        var s = document.getElementsByTagName('script')[0];

        s.parentNode.insertBefore(ga, s);

    })();

</script>

 

</body>

</html>

 

Here is the js code (stock.js):

 

//# dc.js Getting Started and How-To Guide

'use strict';

/* jshint globalstrict: true */

/* global dc,d3,crossfilter,colorbrewer */

// ### Create Chart Objects

// Create chart objects associated with the container elements identified by the css selector.

// Note: It is often a good idea to have these objects accessible at the global scope so that they can be modified or

// filtered by other page controls.

 

// ### Anchor Div for Charts

var moveChart = dc.lineChart('#monthly-move-chart');

var nasdaqCount = dc.dataCount('.dc-data-count');

var nasdaqTable = dc.dataTable('.dc-data-table');

 

//### Load your data

d3.csv('CHANNEL_CLUSTER_BITRATE_takeThis.csv', function (data) {

    var dateFormat = d3.time.format('%m/%d/%Y');

    //some other options for date format

    var axisTimeFormat = d3.time.format.multi([

    [".%L", function (d) { return d.getMilliseconds(); }],

    [":%S", function (d) { return d.getSeconds(); }],

    ["%H:%M", function (d) { return d.getMinutes(); }],

    ["%H:%M", function (d) { return d.getHours(); }],

    ["%a %d", function (d) { return d.getDay() && d.getDate() != 1; }],

    ["%b %d", function (d) { return d.getDate() != 1; }],

    ["%B", function (d) { return d.getMonth(); }],

    ["%Y", function () { return true; }],

    ["%I:%M", function (d) { return d.getMinutes(); }],

    ["%I %p", function (d) { return d.getHours(); }]

    ]);

    var iso = d3.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ");

    var dateAndTime = d3.time.format.utc("%Y-%m-%d");

    var dtgFormat = d3.time.format("%Y-%m-%dT%H:%M:%S");

    var numberFormat = d3.format('.2f');

    data.forEach(function (d) {

       d.dd = dateAndTime.parse(d.DATETIME);

     //  alert(dateAndTime.parse(d.DATETIME) + " d.dd");

       d.month = d3.time.month(d.dd); // pre-calculate month for better performance

       d.hour = d3.time.hour(d.dd);

    

       d.minute = d3.time.minute(d.dd);

     //  alert(d.dd.getFullYear());

        d.CHANNEL_ID = d.CHANNEL_ID;

        d.BITRATE = +d.BITRATE;

        d.DATETIME = dateFormat.parse(d.DATETIME);

      //  alert(d3.time.year(d.dd).getFullYear());

    

    });

 

    //### Create Crossfilter Dimensions and Groups

        var ndx = crossfilter(data);

        var all = ndx.groupAll();

        // Dimension by year

        var yearlyDimension = ndx.dimension(function (d) {

                        

            return d3.time.year(d.dd).getFullYear();

        });

        //Dimension by month

        var monthlyDimension = ndx.dimension(function (d){

            return d3.time.month(d.dd).getMonth();

        });

        var yearlyBitrateByChannelGroup = yearlyDimension.group().reduce(

        /* callback for when data is added to the current filter results */

        //showing table rows

        function (p, v) {

            ++p.count;

            d3.nest()

            .key(function (d) { return d.CHANNEL_ID; })

            .rollup(function (v) {

                 p.length = v.length,

                 p.total = d3.sum(v, function (d) { return d.BITRATE; }),

                 p.avg = d3.mean(v, function (d) { return d.BITRATE; })

             })

            return p;

        },

        /* callback for when data is removed from the current filter results */

        //updating table rows

        function (p, v) {

            --p.count;

            d3.nest()

            .key(function (d) { return d.CHANNEL_ID; })

            .rollup(function (v) {

                p.length = v.length,

                p.total = d3.sum(v, function (d) { return d.BITRATE; }),

                p.avg = d3.mean(v, function (d) { return d.BITRATE; })

            })

            return p;

        },

        /* initialize p */

        function () {

            return {

                BITRATE: 0,

                CHANNEL_ID: 0

            };

        }

 

    ); 

           

    // Dimension by full date

     var dateDimension = ndx.dimension(function (d) {

        return d.dd;

     });

           

 

    // Dimension by month

    var moveMonths = ndx.dimension(function (d) {

         return d.month;

    });

    // Group by total bitrate within month

    var monthlyBitrateGroup = moveMonths.group().reduceSum(function (d) {

         return +d.BITRATE;

    });

    moveChart /* dc.lineChart('#monthly-move-chart', 'chartGroup') */

                    .renderArea(false)

                    .width(990)

                    .height(200)

                    .transitionDuration(1000)

                    .margins({top: 30, right: 50, bottom: 25, left: 40})

                    .dimension(moveMonths)

                    .mouseZoomable(true)

                   //Accessor functions are applied to each value returned by the grouping

                   // `.colorAccessor` - the returned value will be passed to the `.colors()` scale to determine a color

                   .colorAccessor(function (d) {

                       return d.value.BITRATE;

                   })

                   //  `.keyAccessor` - the `X` value will be passed to the `.x()` scale to determine pixel location

                   .keyAccessor(function (p) {

                      return p.value.BITRATE;

                    })

                   //  `.valueAccessor` - the `Y` value will be passed to the `.y()` scale to determine pixel location

                   .valueAccessor(function (p) {

                        return p.value.BITRATE;

                    })

                   //  .radiusValueAccessor` - the value will be passed to the `.r()` scale to determine radius size;by default this maps linearly to [0,100]

                    .radiusValueAccessor(function (p) {

                       return p.value.BITRATE;

                    })

 

                   //  `.elasticY` and `.elasticX` determine whether the chart should rescale each axis to fit the data.

                    .elasticY(true)

                    .elasticX(true)

                   // `.yAxisPadding` and `.xAxisPadding` add padding to data above and below their max values in the same unit

                   // domains as the Accessors.

                    .yAxisPadding(100)

                   .xAxisPadding(500)

                   //  (_optional_) render horizontal grid lines, `default=false`

                    .renderHorizontalGridLines(true)

                   //  (_optional_) render vertical grid lines, `default=false`

                    .renderVerticalGridLines(true)

                   //  (_optional_) render an axis label below the x axis

                   // .xAxisLabel('Index Gain')

                   //  (_optional_) render a vertical axis lable left of the y axis

                   // .yAxisLabel('Index Gain %')

                   // ##### Labels and  Titles

 

                   // Labels are displayed on the chart for each bubble. Titles displayed on mouseover.

                   //  (_optional_) whether chart should render labels, `default = true`

                    .renderLabel(true)

                    .label(function (p) {

                        return p.key;

                    })

                   //  (_optional_) whether chart should render titles, `default = false`

                   // .renderTitle(true)

                   // .title(function (p) {

                   //     return [

                   //         p.key,

                   //         'Index Gain: ' + numberFormat(p.value.absGain),

                   //         'Index Gain in Percentage: ' + numberFormat(p.value.percentageGain) + '%',

                   //         'Fluctuation / Index Ratio: ' + numberFormat(p.value.fluctuationPercentage) + '%'

                   //     ].join('\n');

                   // })

                   // #### Customize Axes

                   //  Set a custom tick format. Both `.yAxis()` and `.xAxis()` return an axis object,

                   //  so any additional method chaining applies to the axis, not the chart.

                    .yAxis().tickFormat(function (v) {

                        return v + '%';

                    });

 

    nasdaqTable /* dc.dataTable('.dc-data-table', 'chartGroup') */

                    .dimension(dateDimension)

            //        // Data table does not use crossfilter group but rather a closure

            //        // as a grouping function

                    .group(function (d) {

                        var format = d3.format('02d');

                        return d.dd.getFullYear() + '/' + format((d.dd.getMonth() + 1));

                    })           

 

 

        // (_optional_) max number of records to be shown, `default = 25`

                    .size(10)

                    // There are several ways to specify the columns; see the data-table documentation.

                    // This code demonstrates generating the column header automatically based on the columns.

                    .columns([

                        // Use the `d.DATETIME` field; capitalized automatically

                        'DATETIME',

                        // Use `d.open`, `d.BITRATE`

                        'CHANNEL_ID',

                        'BITRATE',

                        {

                            // Specify a custom format for column 'Change' by using a label with a function.

                            label: 'BITRATE',

                            format: function (d) {

                                return numberFormat(BITRATE);

                            }

                        },

                      

                    ])

 

                    // (_optional_) sort using the given field, `default = function(d){return d;}`

                    .sortBy(function (d) {

                        return d.dd;

                    })

                    // (_optional_) sort order, `default = d3.ascending`

                    .order(d3.ascending)

                    // (_optional_) custom renderlet to post-process chart using [D3](http://d3js.org)

                    .on('renderlet', function (table) {

                        table.selectAll('.dc-table-group').classed('info', true);

                    });

 

           

            //    //#### Rendering

 

            //    //simply call `.renderAll()` to render all charts on the page

    dc.renderAll();

            //    /*

            //    // Or you can render charts belonging to a specific chart group

            //    dc.renderAll('group');

            //    // Once rendered you can call `.redrawAll()` to update charts incrementally when the data

            //    // changes, without re-rendering everything

               dc.redrawAll();

            //    // Or you can choose to redraw only those charts associated with a specific chart group

            //    dc.redrawAll('group');

            //    */

 

            //});

 

            //#### Versions

 

            //Determine the current version of dc with `dc.version`

    d3.selectAll('#version').text(dc.version);

 

            // Determine latest stable version in the repo via Github API

    d3.json('https://api.github.com/repos/dc-js/dc.js/releases/latest', function (error, latestRelease) {

        /*jshint camelcase: false */

        d3.selectAll('#latest').text(latestRelease.tag_name); /* jscs:disable */

    });

        });

 

 

 

Here is the CSV data:

 

CLUSTER_ID,CLUSTER_DESC,CHANNEL_ID,CHANNEL_CODE,CHANNEL_DESC,DATETIME,BITRATE

1,Cluster #1,1,Cl:1 Ch:1,Channel #1,2016-06-14 0:00,30

1,Cluster #1,1,Cl:1 Ch:1,Channel #1,2016-06-14 0:05,30

1,Cluster #1,1,Cl:1 Ch:1,Channel #1,2016-06-14 0:10,30

1,Cluster #1,1,Cl:1 Ch:1,Channel #1,2016-06-14 0:15,30

1,Cluster #1,1,Cl:1 Ch:1,Channel #1,2016-06-14 0:20,30

1,Cluster #1,1,Cl:1 Ch:1,Channel #1,2016-06-14 0:25,30

1,Cluster #1,1,Cl:1 Ch:1,Channel #1,2016-06-14 0:30,30

1,Cluster #1,1,Cl:1 Ch:1,Channel #1,2016-06-14 0:35,30

2,Cluster #2,5,Cl:2 Ch:5,Channel #5,2016-06-14 13:50,27

2,Cluster #2,5,Cl:2 Ch:5,Channel #5,2016-06-14 13:55,27

2,Cluster #2,5,Cl:2 Ch:5,Channel #5,2016-06-14 14:00,27

2,Cluster #2,5,Cl:2 Ch:5,Channel #5,2016-06-14 14:05,27

2,Cluster #2,5,Cl:2 Ch:5,Channel #5,2016-06-14 14:10,27

2,Cluster #2,5,Cl:2 Ch:5,Channel #5,2016-06-14 14:15,27

2,Cluster #2,5,Cl:2 Ch:5,Channel #5,2016-06-14 14:20,27


Any ideas to solve the getFullYear error? Any other insights of the code ?


Thanks,


Dani

 


--
You received this message because you are subscribed to the Google Groups "dc-js user group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dc-js-user-gro...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dc-js-user-group/f7d8cb74-10cb-4b69-8008-23a823d38763%40googlegroups.com.

DanielaB

unread,
Aug 3, 2016, 2:58:14 PM8/3/16
to dc-js user group
Hi Gordon,

I will check the filtering example and the links which you mentioned - thank you. However, didn't I create a yearly dimension ( var yearlyDimension ) and grouped summing bitrates (d3.nest...p.total) in my code already? :

var ndx = crossfilter(data);

        var all = ndx.groupAll();

        // Dimension by year

        var yearlyDimension = ndx.dimension(function (d) {

                        

            return d3.time.year(d.dd).getFullYear();

        });

var yearlyBitrateByChannelGroup = yearlyDimension.group().reduce(


Thank you for your help,

Daniela 

Gordon Woodhull

unread,
Aug 3, 2016, 3:09:47 PM8/3/16
to dc.js user group
Hi Daniela,

I see, you added your code to stock.js? I didn't see it there. That's really intended to be an example and not so much a starting point. And it adds quite a few pages of noise for anyone trying to help you.

Next I'd suggest checking the results of each stage of your computation. Did your dates parse correctly, for example? The error is telling you that one of d, d.dd, or d3.time.year(d.dd) is null. So you could the results to the browser console to see what those values are, or set a breakpoint on that line to explore what is wrong interactively.

Cheers,
Gordon


DanielaB

unread,
Aug 3, 2016, 3:46:18 PM8/3/16
to dc-js user group
Hi Gordon,

Firstly - thank you for your quick responses - not obvious -appreciate this. Secondly - yes, I did use the stock.js as a frame for my code - will create my own file as you suggested. Regarding the error "cannot read property getFullYear of null" I've already tried to eliminate the null value of d.dd , d,date etc. by handling format(string) and parse(date object) , creating new Date, checking my dates etc., and still receive the error coming from the d3.js. Oh well - will figure it out (unless someone has any insight on this one....)

Thank you and cheers,

Daniela

Gordon Woodhull

unread,
Aug 3, 2016, 4:23:45 PM8/3/16
to dc.js user group
Hi Daniela,

Again, if you log the results you are getting, you will get to the bottom of this pretty quickly.

Just add 

console.log(d.dd)

once after parsing the date, and once before calling d3.time.year(d.dd). 

Then look in the browser log. Or even better, put a breakpoint on that line in the developer tools and inspect the values.

You'll see the problem right away, rather than having to guess what the code is doing.

Cheers,
Gordon


DanielaB

unread,
Aug 7, 2016, 10:20:31 PM8/7/16
to dc-js user group
Thank you.
Hi Daniela,

To unsubscribe from this group and stop receiving emails from it, send an email to dc-js-user-group+unsub...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages