0

I've created a linechart showing averages using Dimensional Charting javascript library dc.js. I'm displaying a rowchart, linechart, and barchart.

When I select one category then year wise average line chart and month wise average line chart display. But when I select one particular year and one category the time month wise average line chart does not display.

skuRowChart = dc.rowChart("#chart-row-spenders");
     yearPieChart = dc.pieChart("#chart-pie-year");
    yearLineChart = dc.lineChart('#Yearly-move-chart');        
    spendHistChart22 = dc.barChart("#chart-hist-spend22");
    moveChart1 = dc.lineChart('#monthly-move-chart1');        
        function reduceAdd(p, v) {
                ++p.count;
                p.total += v.sr;
                p.average = p.total / p.count
                return p;
            }

            function reduceRemove(p, v) {
                --p.count;
                p.total -= v.sr;
                p.average = p.total / p.count
                return p;
            }

            function reduceInitial() {
                return {count: 0, total: 0, average: 0};
            }

          var parseDate = d3.time.format("%m/%d/%Y").parse;
            var yearFormat = d3.time.format('%Y');
            var monthFormat = d3.time.format("%m");
            //var monthNameFormat = d3.time.format("%b");
            var monthNameFormat = d3.time.format('%m.%b');

            var 

spendData = [ 
{ct:'KF', kw:'Amazon', sr: '35978',sd:'12/29/2016'},
{ct:'KF', kw:'Amazon', sr: '32178',sd:'11/2/2016'},
{ct:'KF', kw:'Amazon', sr: '30978',sd:'1/2/2017'},
{ct:'KF', kw:'Amazon', sr: '28978',sd:'1/15/2017'}, 
{ct:'KF',kw:'Build',sr:'28343',sd:'12/29/2016'},
{ct:'KF',kw:'Build',sr:'29653',sd:'11/29/2016'},
{ct:'KF',kw:'Build',sr:'26343',sd:'10/29/2016'},
{ct:'KF',kw:'Build',sr:'28343',sd:'2/2/2017'},
{ct:'KF',kw:'Build',sr:'28343',sd:'3/26/2017'},
{ct:'KF',kw:'Homedepot',sr:'221206',sd:'12/29/2016'},
{ct:'KF',kw:'Homedepot',sr:'203206',sd:'11/27/2016'},
{ct:'KF',kw:'Homedepot',sr:'193206',sd:'10/2/2016'},
{ct:'KF',kw:'wayfair',sr:'77794',sd:'12/29/2016'},
{ct:'KF',kw:'wayfair',sr:'71794',sd:'11/9/2016'},
{ct:'KF',kw:'wayfair',sr:'70794',sd:'1/9/2017'},
{ct:'KF',kw:'wayfair',sr:'74794',sd:'2/19/2017'},
{ct:'KF',kw:'wayfair',sr:'74794',sd:'3/21/2017'},
{ct:'KF',kw:'Houzz',sr:'408684',sd:'12/29/2016'},
{ct:'KF',kw:'Houzz',sr:'42684',sd:'11/22/2016'},
{ct:'KF',kw:'Houzz',sr:'46684',sd:'10/2/2016'},
{ct:'KF',kw:'Houzz',sr:'496684',sd:'1/2/2017'},
{ct:'KF',kw:'Houzz',sr:'49684',sd:'2/2/2017'},
{ct:'KF',kw:'Houzz',sr:'49664',sd:'3/2/2017'},
{ct:'KF',kw:'express',sr:'32004',sd:'12/29/2016'},
{ct:'KF',kw:'express',sr:'30004',sd:'11/2/2016'},
{ct:'KF',kw:'express',sr:'35004',sd:'10/2/2016'},
{ct:'KF',kw:'express',sr:'35004',sd:'12/2/2016'},
{ct:'KF',kw:'yahoo',sr:'115618',sd:'12/29/2016'},
{ct:'KF',kw:'yahoo',sr:'12546',sd:'10/2/2016'},
{ct:'KF',kw:'yahoo',sr:'65423',sd:'11/29/2016'},
{ct:'KF',kw:'yahoo',sr:'25698',sd:'10/29/2016'},
{ct:'KF',kw:'google',sr:'404991',sd:'1/29/2017'},
{ct:'KF',kw:'google',sr:'404991',sd:'2/2/2017'},
{ct:'KF',kw:'google',sr:'404991',sd:'3/12/2017'},
{ct:'KF',kw:'google',sr:'404991',sd:'3/3/2017'},
{ct:'KF',kw:'pingserach',sr:'273944',sd:'12/29/2016'}
];
     // d3.csv("hhh.csv", function (error, salesrank) { 
         spendData.forEach(function (d) {
                     d.sr = +d.sr;
                    d.Date = parseDate(d.sd);
                    d.Year = yearFormat(d.Date);
                   d.Month = monthNameFormat(d.Date);
                });
         var ndx = crossfilter(spendData);
         var all = ndx.groupAll();
        SkuDim = ndx.dimension(function (d) {return d.kw; });
        spendPerSku = SkuDim.group().reduceCount();
        yearDim = ndx.dimension(function (d) {return d.Year; });
        year_total = yearDim.group().reduceCount(function (d) {return d.sr;});
        exptAvgGroup = yearDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);
        monthDim = ndx.dimension(function (d) {return d.Month; });
        exptAvgGroup11 = monthDim.group().reduce(reduceAdd, reduceRemove, reduceInitial);
        month_total = monthDim.group().reduceCount(function (d) { return d.sr;});            

        skuRowChart
            .width(350)
            .height(300)
            .dimension(SkuDim)
            .group(spendPerSku)
            .elasticX(true)
            .x(d3.scale.linear().domain([6, 20]))
            .ordering(function (d) {
                return -d.value
            })
           // .cap(40)
            //.margins({top: -30, left: 0, right: 0, bottom: 0})
            .controlsUseVisibility(true);
        skuRowChart.data(function (group) {
            return group.top(50);
        });



        yearPieChart
            .width(250).height(250)
            .dimension(yearDim)
            .group(year_total)
            .innerRadius(60)
            .controlsUseVisibility(true);



        yearLineChart
            .width(380)
            .height(280)
            .x(d3.scale.ordinal())
            .xUnits(dc.units.ordinal)
            .renderHorizontalGridLines(true)
            .renderVerticalGridLines(true)
            .renderArea(true)
            .valueAccessor(function (p) {
                            //console.log("p.value.average: ", p.value.average) //displays the avg fine
                            return d3.round(p.value.average, 0);
                        })
            //.brushOn(true)
            .elasticY(true)
            .xAxisLabel('Years')
            .yAxisLabel('Review Count')
            //.dimension(moveMonths)
            .dimension(yearDim)
            .group(exptAvgGroup)
            //.margins({ top: 10, left: 60, right:40, bottom: 60 }) 
            .margins({top: 0, left: 60, right: 30, bottom: 60})


            spendHistChart22
                .width(400).height(280)
                .dimension(monthDim)
                //.dimension(dateeddim)
               // .group(dateeddimGroup)
                .group(month_total)
               .xAxisLabel('Months')
                .yAxisLabel('')
                .x(d3.scale.ordinal())
                .xUnits(dc.units.ordinal)
                 .ordering(function(d) { return d.key })
                .elasticX(true)

                .elasticY(true)
                .margins({ top: 10, left: 60, right: 40, bottom: 60 }) 

                .controlsUseVisibility(true)
                spendHistChart22.xAxis().tickFormat(d => d.substr(3))




        moveChart1
        .width(380)
        .height(310)
        //.x(d3.scale.ordinal().domain(map(function (d) {return d.Month;})))
        .x(d3.scale.ordinal())
        .xUnits(dc.units.ordinal)
        .valueAccessor(function (p) {
                            //console.log("p.value.average: ", p.value.average) //displays the avg fine
                            return d3.round(p.value.average, 0);
                        })
        .renderHorizontalGridLines(true)
        .renderVerticalGridLines(true)
        .renderArea(true)
        //.clipPadding(10)
        //.brushOn(false)
        .elasticY(true)
        .xAxisLabel('Months')
        .yAxisLabel('')
        .dimension(monthDim)
        .group(exptAvgGroup11)

        .margins({top: 40, left: 60, right: 30, bottom: 60})
        moveChart1.xAxis().tickFormat(d => d.substr(3))




        dc.renderAll();

https://jsfiddle.net/pramod24/kk4j0bzn/4/

Gordon
  • 19,811
  • 4
  • 36
  • 74
pramod24
  • 1,096
  • 4
  • 17
  • 38
  • 3
    Wow, did you really format your question as code in order to get around the rule against using jsfiddle.net without providing code? That's... brave. Anyway, I fixed it and I think it's a valid question. – Gordon Jan 11 '17 at 09:08

1 Answers1

2

You have to watch out whenever you divide by something that is potentially zero.

dc.js won't sanitize your data very much, so when you see a blank chart, it's probably bad data.

Without trying to debug anything, I tried fixing the first thing that stood out to me, those divisions by p.count that don't check if p.count is zero.

You probably want your averages to drop to zero when the count is zero. (Technically I guess there should be gaps in the line, but I won't get into that unless you're interested.)

This seems to fix the problem:

            function reduceAdd(p, v) {
                ++p.count;
                p.total += v.sr;
                p.average = p.count ? p.total / p.count : 0;
                return p;
            }

            function reduceRemove(p, v) {
                --p.count;
                p.total -= v.sr;
                p.average = p.count ? p.total / p.count : 0;
                return p;
            }

Fork of your fiddle: https://jsfiddle.net/gordonwoodhull/q4aquukz/1/

Would you be so kind as to point to the example where you got the bad code, so I can correct it or leave a comment?

Gordon
  • 19,811
  • 4
  • 36
  • 74
  • 1
    Great! If you got the bad code from SO or one of the dc.js examples could you please let me know where, so I can correct it? – Gordon Jan 12 '17 at 15:34