pramod24
pramod24

Reputation: 1116

Monthwise average linechart is not displayed

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/

Upvotes: 0

Views: 113

Answers (1)

Gordon
Gordon

Reputation: 20150

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?

Upvotes: 2

Related Questions