Dear all,

I want to share a solution for a feature that I am really missing on the new InfoChart component: dynamic axis ranges based on a data source. I ran into this problem on a dashboard overview page with 12 line charts each showing actual and target values over 12 month (up to 288 data points). The values of some charts are in a very tight range (e.g. between 94% and 96% over the whole year).

The InfoChart component will always set the y-axis-range from 0 to a somehow dynamic max value. That leads to charts like this:

My solution changes the chart to this:

How to do it:

1. We need to find the highest and lowest value for each key figure in a chart.

My first try was to loop over all values with datasource.getdata() and find the min and max values in the Application itself. However, for my 288 data points I needed 288 getdata-calls and it took almost 10 seconds to find all relevant values and change the charts.

I then switched to my current solution: I copied the relevant data source providing me all key figures two times and changed the totals calculation to MIN and MAX. The OLAP engine calculated this values way faster as it would be possible in DesignStudio.

2. We need to calculate “nice” ranges for the retrieved min and max values. I wrote a function for that.

It currently has parameters for two key figures and two InfoCharts, as I update a detailed chart in another area of the application at the same time. You could easily remove parameters or replace them with arrays to even process more key figures / charts.

After retrieving the values the function adds / subtracts 3% of the min / max values and then calculated the next “nice to the eyes” value below / above them.

I don’t want to see a axis with values from 41 to 47, so the function returns 40 and 50 for this example. Values with more than two digits will be “beautified” in the first two digits, so 123456 is calculated to 120000 as min or 130000 as max value.

**var** vMin = 0;

**var** vMax = 0;

**var** vMinT = 0;

**var** vMaxT = 0;

**var** vDigits = 0;

// get min actual and target value

vMin = Math.round(DS_ALL_KPI_MIN_VALUES.getData(iActual, {}).value);

vMinT = Math.round(DS_ALL_KPI_MIN_VALUES.getData(iTarget, {}).value);

// keep lower value of both min values

**if** (vMin > vMinT && vMinT != 0){

vMin = vMinT;

}

// get max actual and target value

vMax = Math.round(DS_ALL_KPI_MAX_VALUES.getData(iActual, {}).value);

vMaxT = Math.round(DS_ALL_KPI_MAX_VALUES.getData(iTarget, {}).value);

// keep higher value of both max values

**if** (vMax < vMaxT && vMaxT != 0){

vMax = vMaxT;

}

// process min value: decrease by 3%, calculate next “nice” value for presentation

vMin = Math.floor(vMin * 0.97);

vDigits = (vMin + “”).length;

**if** (vDigits > 2) {

vMin = Math.round(Math.floor(vMin / Math.pow(10, vDigits – 2)) * Math.pow(10, vDigits – 2));

} **else** **if** (vDigits == 2) {

vMin = Math.floor(vMin / 10) * 10;

}

// process max value: increase by 3%, calculate next “nice” value for presentation

vMax = Math.ceil(vMax*1.03);

vDigits = (vMax + “”).length;

**if** (vDigits > 2) {

vMax = Math.round(Math.ceil(vMax / Math.pow(10, vDigits – 2)) * Math.pow(10, vDigits – 2));

} **else** **if** (vDigits == 2) {

vMax = Math.ceil(vMax / 10) * 10;

}

// set scale for chart

iChart.setAxisScaling(InfoChartAxisScaling.AXIS_1, vMin, vMax);

iChart2.setAxisScaling(InfoChartAxisScaling.AXIS_1, vMin, vMax);

3. Finally you just call the function using the relevant key figures and charts

GLOBAL_SCRIPTS_1.GS_OVERVIEW_AXIS_SCALE(“009ZVKHCE8ZTUZ0ODSSBLGL38”,“009ZVKHCE8ZTUZPNRQ3OC0AK4”,INFOCHART_DP_CHART, INFOCHART_DP_ACT_TG);

That’s it. For my dashboard overview page this reduced the load and calculation time from over 10 to under 1 seconds. I am pretty sure that this will be a standard feature sometime in the future. But for now I did not find any other way to solve this issue.

Best regards,

Robert

Younes HasbaGreat Post Thanks Robert!