| OLD | NEW |
| (Empty) |
| 1 function mean(params) { | |
| 2 var datasetNr = params.datasetNr; | |
| 3 var data = params.data; | |
| 4 var mean = 0; | |
| 5 var nr = 0; | |
| 6 for (var j = 0; j < data.datasets[datasetNr].data.length; j++) { | |
| 7 // important to check because missing values are possible | |
| 8 if (!(typeof(data.datasets[datasetNr].data[j])=='undefined')){ | |
| 9 mean += 1*data.datasets[datasetNr].data[j]; | |
| 10 nr++; | |
| 11 } | |
| 12 } | |
| 13 mean /= nr; | |
| 14 return mean; | |
| 15 } | |
| 16 | |
| 17 function varianz(params) { | |
| 18 var data = params.data; | |
| 19 var datasetNr = params.datasetNr; | |
| 20 var meanVal = mean(params); | |
| 21 var varianz = 0; | |
| 22 var nr = 0; | |
| 23 for (var j = 0; j < data.datasets[datasetNr].data.length; j++) { | |
| 24 // important to check because missing values are possible | |
| 25 if (!(typeof(data.datasets[datasetNr].data[j])=='undefined')) { | |
| 26 varianz += Math.pow(1*data.datasets[datasetNr].data[j]-m
eanVal,2); | |
| 27 nr++; | |
| 28 } | |
| 29 } | |
| 30 return varianz/nr; | |
| 31 } | |
| 32 | |
| 33 function stddev(params) { | |
| 34 return Math.sqrt(varianz(params)); | |
| 35 } | |
| 36 | |
| 37 function cv(params) { | |
| 38 return stddev(params)/mean(params); | |
| 39 } | |
| 40 | |
| 41 function median(params) { | |
| 42 function numSort (a, b) { | |
| 43 return a - b; | |
| 44 } | |
| 45 // slice => copy array | |
| 46 var dataArray = params.data.datasets[params.datasetNr].data.slice(); | |
| 47 dataArray.sort(numSort); | |
| 48 // missing values are at the end | |
| 49 var dataArrayLength = dataArray.length; | |
| 50 j = dataArrayLength-1; | |
| 51 while (typeof(dataArray[j]) == "undefined" && j >= 0) { | |
| 52 j--; | |
| 53 } | |
| 54 dataArrayLength = j+1; | |
| 55 // odd | |
| 56 if (dataArrayLength % 2) { | |
| 57 return dataArray[Math.floor(dataArrayLength/2)]; | |
| 58 } else { // even | |
| 59 var lowerMiddle = dataArray[dataArrayLength/2-1]; | |
| 60 var higherMiddle = dataArray[dataArrayLength/2]; | |
| 61 return (higherMiddle+lowerMiddle)/2; | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 function drawMath(ctx,config,data,msr,vars) { | |
| 66 var xAxisPosY = vars.xAxisPosY; | |
| 67 var yAxisPosX = vars.yAxisPosX; | |
| 68 var valueHop = vars.valueHop; | |
| 69 var scaleHop = vars.scaleHop; | |
| 70 var zeroY = vars.zeroY; | |
| 71 var calculatedScale = vars.calculatedScale; | |
| 72 var calculateOffset = vars.calculateOffset; | |
| 73 var barWidth = vars.barWidth; | |
| 74 var barBool = !(typeof barWidth == "undefined") ? true : false; | |
| 75 | |
| 76 // check each dataset if a mathDraw function exists | |
| 77 for (var i = 0; i < data.datasets.length; i++) { | |
| 78 // get mathFctName (stddev|mean|...) | |
| 79 var deviationFct = data.datasets[i].drawMathDeviation; | |
| 80 if (deviationFct) { | |
| 81 drawMathDeviation(i,deviationFct); | |
| 82 } | |
| 83 var lineFct = data.datasets[i].drawMathLine; | |
| 84 if (lineFct) { | |
| 85 drawMathLine(i,lineFct); | |
| 86 } | |
| 87 } | |
| 88 | |
| 89 /** | |
| 90 * Draw a deviation vertical line (if needed with top and bottom horizon
tal lines) | |
| 91 * @param i {integer} dataset number | |
| 92 * @param deviationFct {string} math function name | |
| 93 */ | |
| 94 function drawMathDeviation(i,deviationFct) { | |
| 95 var deviation = 0; | |
| 96 // check if the math function exists | |
| 97 if (typeof eval(deviationFct) == "function") { | |
| 98 var parameter = {data:data,datasetNr: i}; | |
| 99 deviation = window[deviationFct](parameter); | |
| 100 } | |
| 101 if (isNumber(deviation)) { | |
| 102 ctx.strokeStyle= data.datasets[i].deviationStrokeColor ?
data.datasets[i].deviationStrokeColor : config.defaultStrokeColor; | |
| 103 ctx.lineWidth = config.datasetStrokeWidth; | |
| 104 ctx.beginPath(); | |
| 105 for (var j = 0; j < data.datasets[i].data.length; j++) { | |
| 106 // important to check because missing values are
possible | |
| 107 if (!(typeof(data.datasets[i].data[j])=='undefin
ed')) { | |
| 108 var deviationWidth = data.datasets[i].de
viationWidth; | |
| 109 // draw the top and the bottom of the ve
rtical line if a deviationWidth exists | |
| 110 if (deviationWidth) { | |
| 111 ctx.moveTo(xPos(j,i,barWidth,bar
Bool)-deviationWidth,yPos(i,j,-deviation,true)); | |
| 112 ctx.lineTo(xPos(j,i,barWidth,bar
Bool)+deviationWidth,yPos(i,j,-deviation,true)); | |
| 113 ctx.moveTo(xPos(j,i,barWidth,bar
Bool)-deviationWidth,yPos(i,j,deviation,true)); | |
| 114 ctx.lineTo(xPos(j,i,barWidth,bar
Bool)+deviationWidth,yPos(i,j,deviation,true)); | |
| 115 } | |
| 116 // draw the vertical line | |
| 117 ctx.moveTo(xPos(j,i,barWidth,barBool),yP
os(i,j,-deviation,true)); | |
| 118 ctx.lineTo(xPos(j,i,barWidth,barBool),yP
os(i,j,deviation,true)); | |
| 119 } | |
| 120 } | |
| 121 ctx.stroke(); | |
| 122 ctx.closePath(); | |
| 123 } | |
| 124 } | |
| 125 | |
| 126 /** | |
| 127 * Draw a horizontal line | |
| 128 * @param i {integer} numer of dataset | |
| 129 * @param lineFct {string} name of the mathfunctions => compute height | |
| 130 */ | |
| 131 function drawMathLine(i,lineFct) { | |
| 132 var line = 0; | |
| 133 // check if the math function exists | |
| 134 if (typeof eval(lineFct) == "function") { | |
| 135 var parameter = {data:data,datasetNr: i}; | |
| 136 line = window[lineFct](parameter); | |
| 137 } | |
| 138 if (!(typeof(line)=='undefined')) { | |
| 139 ctx.strokeStyle= data.datasets[i].mathLineStrokeColor ?
data.datasets[i].mathLineStrokeColor : config.defaultStrokeColor; | |
| 140 ctx.lineWidth = config.datasetStrokeWidth; | |
| 141 ctx.beginPath(); | |
| 142 ctx.moveTo(yAxisPosX,yPos(i,0,line,false)); | |
| 143 ctx.lineTo(yAxisPosX + msr.availableWidth,yPos(i,data.da
tasets[i].data.length-1,line,false)); | |
| 144 ctx.stroke(); | |
| 145 ctx.closePath(); | |
| 146 } | |
| 147 } | |
| 148 | |
| 149 /** | |
| 150 * Get a y position depending on the current values | |
| 151 * @param dataset {integer} number of dataset | |
| 152 * @param iteration {integer} number of value inside dataset.data | |
| 153 * @param add {float} add a value to the current value if value is true | |
| 154 * @param value {bool} true => value+add, false=>add | |
| 155 * @returns {float} position (px) | |
| 156 */ | |
| 157 function yPos(dataSet, iteration, add,value) { | |
| 158 value = value ? 1*data.datasets[dataSet].data[iteration] : 0; | |
| 159 return xAxisPosY - calculateOffset(config.logarithmic, value+add
, calculatedScale, scaleHop); | |
| 160 }; | |
| 161 function xPos(iteration,dataSet,barWidth,bar) { | |
| 162 if (bar) { | |
| 163 return yAxisPosX + config.barValueSpacing + valueHop * i
teration + barWidth * dataSet | |
| 164 + config.barDatasetSpacing * dataSet + config.bar
StrokeWidth * dataSet+barWidth/2; | |
| 165 } else { | |
| 166 return yAxisPosX + (valueHop * iteration); | |
| 167 } | |
| 168 | |
| 169 }; | |
| 170 } | |
| OLD | NEW |