Cumulative Chart

  • 4
  • Question
  • Updated 1 year ago
  • Answered
Is it possible to create cumulative charts with Skuid?

Example: Revenue Chart grouped by purchase month, I want January to show January's revenue and then February to show January + February, etc

Thanks!
Photo of Adam Johnson

Adam Johnson

  • 1,020 Points 1k badge 2x thumb

Posted 5 years ago

  • 4
Photo of Pat Vachon

Pat Vachon, Champion

  • 44,656 Points 20k badge 2x thumb
In theory you could loop through the value in the series accumulating and updating the each in the series as you go.

I'll try this for later as I'd like to have this capability.
Photo of Pat Vachon

Pat Vachon, Champion

  • 44,656 Points 20k badge 2x thumb
Ran out of steam. :S
Maybe tomorrow.
Hi Pat. Did you find anything out about how this could be achieved?
Photo of Pat Vachon

Pat Vachon, Champion

  • 44,656 Points 20k badge 2x thumb
I did manage to do this once. I used a snippet to accumulate the current value with the previous value(s). Looking for the code I wrote.
Photo of Pat Vachon

Pat Vachon, Champion

  • 44,656 Points 20k badge 2x thumb
Et voila! Enjoy!

var chart = arguments[0],
    $ = skuid.$;
    
    
    if (chart.series.length > 0){
        $.each(chart.series, function(cs,cSeries){
            var cSeriesData =  cSeries.data,
            cumulative = 0;
            
            $.each(cSeriesData,function(s,currentSeries){
                cumulative = cumulative + currentSeries;
                chart.series[cs].data[s] = cumulative;
            });
        });

    }
Photo of Rob Hatch

Rob Hatch, Official Rep

  • 44,908 Points 20k badge 2x thumb
Thanks Pat - you found it even while you were at Dreamforce.  That's awesome. 
Photo of Pat Vachon

Pat Vachon, Champion

  • 44,656 Points 20k badge 2x thumb
Nope. 30,000 ft up. Decided to cut my trip short.
Wow, HUGE thanks!! Amazing. I'll check it out :)
Photo of Jack Sanford

Jack Sanford, Champion

  • 10,050 Points 10k badge 2x thumb
Can you explain this just a little more? What do you replace with your own series names?

I'm trying to make a Pareto chart, which is a mash up of a column chart sorted by prevalence left to right (h/t to this thread) and a line chart that shows the cumulative percent of the total 
Photo of Jack Sanford

Jack Sanford, Champion

  • 10,050 Points 10k badge 2x thumb
Can you explain this just a little more? What do you replace with your own series names?

I'm trying to make a Pareto chart, which is a mash up of a column chart sorted by prevalence left to right (h/t to this thread) and a line chart that shows the cumulative percent of the total 
Photo of Pat Vachon

Pat Vachon, Champion

  • 44,656 Points 20k badge 2x thumb
Here you go.

You'll have to introduce the same data as two series. Once for the column and another as the line chart. Done it before and here's what it looks like. Not a great illustration but works well with certain data sets.





var chart = arguments[0],
    $ = skuid.$;
    
    
    if (chart.series.length > 0){
        $.each(chart.series, function(cs,cSeries){
            var cSeriesData =  cSeries.data,
            cumulative = 0;
            if (cs == chart.series.length - 1){
                $.each(cSeriesData,function(s,currentSeries){
                    
                    cumulative = cumulative + currentSeries;
                    chart.series[cs].data[s] = cumulative;    
                    
                    
                });
            }
        });

    }
    
Pat, thanks a millIon for this!

Now Skuidify team, in my opinion, this would be a hugely useful addition to the declarative toolset. We get asked for these Pareto charts all the time.
Oh, and it's times like this, that "like" button needs relabelled to "Love"...
Photo of Chelsea Curtis

Chelsea Curtis

  • 1,300 Points 1k badge 2x thumb
I attempted to use Pat's first snippet, but the chart does not show any data... I copied and pasted the snippet and placed the name of the snippet in the Before Render Snippet. Am I missing anything?

Thanks!
Photo of Chelsea Curtis

Chelsea Curtis

  • 1,300 Points 1k badge 2x thumb
I attempted to use Pat's first snippet, but the chart does not show any data... I copied and pasted the snippet and placed the name of the snippet in the Before Render Snippet. Am I missing anything?

Thanks!
Photo of Henry Goddard

Henry Goddard

  • 776 Points 500 badge 2x thumb
Better late than never,

I too have tried Pat's script to no avail. However, I have managed to locate where it seems to be going wrong. It seems that the data arrays for each series that Skuid pumps into the highcharts constructor are objects, and not integers. The above snippet assumes 'currentSeries' is an array of integers, when it is actually an array of objects of a format similar to:

{
  y: 0,
  name: "Feb 2016",
  sk_rows: undefined
}
 

Therefore Line 12, or:

cumulative = cumulative + currentSeries;

attempts to cumulate objects, not the y values of each point. To fix that, simply change the line to:

cumulative = cumulative + currentSeries.y;

Further, the snippet only seems to only be interested in the last series and ignores all others with line 10, or:

if (cs == chart.series.length - 1){

removing that will cumulate all the series in the chart.

Since I'm already on the topic, it's worth noting that Skuid will execute the 'Before Render Script' should alternate chart types be selected. This means that already cumulated data will be cumulated once again. To overcome this, I've added a flag to the series to prevent that from happening, here is my version:

var chartObj = arguments[0],
    series = !!chartObj.series ? chartObj.series : [], //catch the empty series case
	$ = skuid.$;

//doit
main();	

//call the cumulator and add tooltips
function main() {
    if (series.length > 0) {
        //cumulate all the series
        $.each( series, function (i, elem) {
            //only cumulate the data if hasn't already been done so
            if( !elem.cum ) {
                cumulate(elem.data);
                elem['cum'] = true; //mark as cumulated
            }
        });
    }
}

//cumulate the array
function cumulate(r) {
    var curSum = 0,
        result = r;
    $.each( r , function (i, data) {
        curSum += data.y; //add the current y value
        result[i].y = curSum; //set the data of the output
    });
    return result
}
(Edited)
Photo of Michael Schniepp

Michael Schniepp

  • 1,878 Points 1k badge 2x thumb
Wow, worked perfectly Henry, Thanks! How could one go about learning how to manipulate skuid components with javascript? Would love to know how to make these modifications from scratch for future customizations. 
Photo of Michael L Barnes

Michael L Barnes

  • 196 Points 100 badge 2x thumb
Henry, you rock!  Your snippet worked perfectly for me as well.  Thank you so much!!  Sadly I am a javascript novice at best.  Thanks for the links above as well, as I have some skills that need development on this end.
Photo of Michael L Barnes

Michael L Barnes

  • 196 Points 100 badge 2x thumb
Henry, you rock!  Your snippet worked perfectly for me as well.  Thank you so much!!  Sadly I am a javascript novice at best.  Thanks for the links above as well, as I have some skills that need development on this end.
Photo of Rob Hatch

Rob Hatch, Official Rep

  • 44,908 Points 20k badge 2x thumb
Check out this forum discussion for some good ideas. 

https://community.skuidify.com/skuid/topics/display-chart-series-diff
Photo of Ben Murray

Ben Murray

  • 1,134 Points 1k badge 2x thumb
Henry,

a brief thank you. This worked beautifully...

Cheers,

Ben