Forum Discussion

Silutions's avatar
11-22-2021
Solved

Bell Curves in Sisense

Anyone out there have a simple way to present Bell Curves?

I found this post, but have not been able to make it work.  Anyone have a better idea?

  • I was able to simplify the script.

    You no longer require the "Median" and "SD" values.
    Just configure the following variables:

    • dataLabel - Your data series name
    • sdLevels - The number of SD levels to display (1 means -1/+1 l 2 means -2/-1/+1/+2) | etc.)
    var debug = true;
    
    function getMedian(sorted) {
        const middle = Math.floor(sorted.length / 2);
    
        if (sorted.length % 2 === 0)
            return (sorted[middle - 1] + sorted[middle]) / 2;
        else
    		return sorted[middle];
    }
    
    function getStandardDeviation(numArray) {
      const mean = numArray.reduce((s, n) => s + n) / numArray.length;
      const variance = numArray.reduce((s, n) => s + (n - mean) ** 2, 0) / (numArray.length - 1);
      return Math.sqrt(variance);
    }
    
    function getAxisLocation(rangeArray,value) {
    	// Calculates the {value} relative location on the {rangeArray} axis
        for (let i=1 ; i< rangeArray.length; i++) {
            if (parseFloat(rangeArray[i-1]) <= value && value <= parseFloat(rangeArray[i])) {
    			// If within the range of the datapoints [i-1] and [i]
                return (i-1) + (value-parseFloat(rangeArray[i-1])) / parseFloat((rangeArray[i])-rangeArray[i-1]);
            }
        }
    	
    	// The value isn't within the axis range
        return -1;
    }
    
    
    widget.on('processresult',function(w,ev) {
    
    	var widgetID = w._id;
    	var sdLevels = 2;
    	var dataLabel = 'Frequency';
    	
    	//scan the "Values"
    	$.each(ev.result.series, function(i, v) {
    		switch(v.name) {
    			case dataLabel:
    				valueArray = [];
    				for (let i = 0 ; i< v.data.length ; i++) {for (let j = 0 ; j < v.data[i].y ; j++ ) {valueArray.push(parseFloat(ev.result.xAxis.categories[i]))}};
    				MedianVal = getMedian(valueArray);
    				if (debug) console.log (widgetID + ' - Found "Median" with a value of ' + MedianVal);
    				StdevPVal = getStandardDeviation(valueArray);
    				if (debug) console.log (widgetID + ' - Found "Population StDev" with a value of ' + StdevPVal);
    				break;
    		}
    	});
    	
    	// Fix highcharts bug that prevents showing vertical line labels
    	// Details: https://github.com/highcharts/highcharts/issues/8477
    	Highcharts.wrap(Highcharts.Axis.prototype, 'getPlotLinePath', function(proceed) {
    		var path = proceed.apply(this, Array.prototype.slice.call(arguments, 1));
    		if (path) {
    			path.flat = false;
    		}
    		return path;
    	});
    	
    	// Initialize the vertical lines array
    	ev.result.xAxis.plotLines = [];
    	
    	// Add the vertical lines
    	for (let i=-sdLevels;i<=sdLevels; i++) {
    		Value = MedianVal + i * StdevPVal
    		Position = getAxisLocation(ev.result.xAxis.categories,Value);
    		
    		if (debug) console.log (widgetID + ' - Handling i=' + i +' Value=' + Value + ' Position=' + Position)
    		
    		switch (Math.abs(i)) {
    			case 0:
    				Color = 'Red'
    				Text = 'Median (' + Value.toFixed(2) + ')'
    				break;
    			case 1:
    				Color = 'Blue'
    				Text = i + 'SD (' + Value.toFixed(2) + ')'
    				break;
    			case 2:
    				Color = 'Grey'
    				Text = i + 'SD'
    				break;
    		}
    			
    
    		if (Position != -1) ev.result.xAxis.plotLines.push(
    			{
    				color: Color,
    				width: 2,
    				dashStyle: "dash",
    				value: Position,
    				label: {
    					text: Text,
    					rotation:0,
    					textAlign: "center",
    					style:{fontFamily: "abelregular"},
    					y:15,
    					x:-3
    				}
    			})
    		else
    			if (debug) console.log (widgetID + ' - The "SD ' + i +'" line is out of the X Axis range (' + Value + ') - Skipping')
    	}
    })

     

31 Replies

Replies have been turned off for this discussion