This JavaScript program demonstrates how to generate and graph a uniform distribution. The uniform distribution is generated in the range [0,1].
<!DOCTYPE html> <html> <head> <title>XoaX.net's Javascript</title> <script type="text/javascript" src="GraphingAUniformDistribution.js"></script> </head> <body onload="Initialize()"> <div style="width:858px;height:430px;"> <canvas id="idCanvas" width="800" height ="400" style="background-color: #F0F0F0;float:left;"></canvas> <div style="width:58px;height:400px;float:right;"> <input id="idHighY" type="text" size="9" style="width:50px;height:16px;"/> <div style="width:58px;height:356px;"></div> <input id="idLowY" type="text" size="9" style="width:50px;height:16px;"/> </div> <div style="width:800px;height:22px;float:left;"> <input id="idLowX" type="text" size="9" style="width:50px;height:16px;float:left;"/> <div style="width:684px;height:22px;float:left;"></div> <input id="idHighX" type="text" size="1" value="1.2" style="width:50px;height:16px;float:left;"/> </div> </div> </body> </html>
class CUniformDistribution { #mdaX; #mdGraphWidth = 1.2; constructor(iCount) { // This generates a sorted array of the sample values of the distribution // This is a uniform distribution from 0 to 1 this.#mdaX = new Array(iCount); for (let i = 0; i < iCount; ++i) { this.#mdaX[i] = Math.random(); // Insertion sort each point after it is added let j = i; while (j > 0 && this.#mdaX[j] < this.#mdaX[j - 1]) { let dSwap = this.#mdaX[j]; this.#mdaX[j] = this.#mdaX[j - 1]; this.#mdaX[j - 1] = dSwap; --j; } } } Mean() { let dMean = 0; for (let i = 0; i < this.#mdaX.length; ++i) { dMean += this.#mdaX[i]/this.#mdaX.length; } return dMean; } StandardDeviation() { return Math.sqrt(this.Variance()); } Variance() { let dMean = this.Mean(); let dVariance = 0; for (let i = 0; i < this.#mdaX.length; ++i) { dVariance += Math.pow(this.#mdaX[i] - dMean, 2)/this.#mdaX.length; } return dVariance; } PixelXToGraphX(dPixelX, iCanvasWidth) { // Half the size should map to the mean let dHalfWidth = this.#mdGraphWidth/2; let dMean = this.Mean(); let dT = ((dPixelX + .5)/iCanvasWidth)*this.#mdGraphWidth - dHalfWidth + dMean; return dT; } Graph(qContext, dBarWidthInPixels) { qContext.fillStyle = "#606060"; // Outline properties qContext.strokeStyle = "#F0F0F0"; qContext.lineWidth = "1"; // This is the basic transformation to flip the y-axis qContext.transform(1, 0, 0, -1, 0, qContext.canvas.height); // The canvas width and height in pixels or pixels per canvas let iW = qContext.canvas.width; let iH = qContext.canvas.height; // The canvas graph width: 1.2 let dGraphW = this.#mdGraphWidth; // Pixel width in graph units = graph width / pixels per canvas width let dPixW = dGraphW/iW; // Bar width in pixels / pixels per canvas width let dBarsPerWidth = iW/dBarWidthInPixels; // The width of a bar in values let dBarWidth = dBarWidthInPixels*dPixW; // The middle bar is centered on zero // Find the start of the first bar and continue from there until all of them are drawn let dStartOfFirstBarPix = iW/2 - dBarWidthInPixels/2 - dBarWidthInPixels*Math.ceil(dBarsPerWidth/2); let dStartOfCurrBarPix = dStartOfFirstBarPix; let dStartOfCurrBarValue = this.PixelXToGraphX(dStartOfCurrBarPix, iW); let iIndexOfNextPoint = 0; // Get to the first point that is in the range of the first bar. while (iIndexOfNextPoint < this.#mdaX.length && dStartOfCurrBarValue > this.#mdaX[iIndexOfNextPoint]) { ++iIndexOfNextPoint; } let iaBins = new Array(); while (iIndexOfNextPoint < this.#mdaX.length && dStartOfCurrBarPix < iW) { let dEndOfCurrBarPix = dStartOfCurrBarPix + dBarWidthInPixels; let dEndOfCurrBarValue = this.PixelXToGraphX(dEndOfCurrBarPix, iW); let iIndexOfEnd = iIndexOfNextPoint; while (iIndexOfEnd < this.#mdaX.length && dEndOfCurrBarValue > this.#mdaX[iIndexOfEnd]) { ++iIndexOfEnd; } // The number of points in the bin iaBins.push(iIndexOfEnd - iIndexOfNextPoint); // The increment for the bar dStartOfCurrBarPix = dEndOfCurrBarPix; // Increment for the points iIndexOfNextPoint = iIndexOfEnd; } // Get the size of the largest bin let iLargestBinSize = 0; for (let i = 0; i < iaBins.length; ++i) { if (iLargestBinSize < iaBins[i]) { iLargestBinSize = iaBins[i]; } } // Make the height of the graph 20% higher than the largest bin size. let dMaxY = iLargestBinSize*1.2; let iBinIndex = 0; dStartOfCurrBarPix = dStartOfFirstBarPix; // Draw the bars of the graph while (iBinIndex < iaBins.length && dStartOfCurrBarPix < iW) { let dEndOfCurrBarPix = dStartOfCurrBarPix + dBarWidthInPixels; let dRectHeight = iaBins[iBinIndex]; qContext.fillRect(dStartOfCurrBarPix, 0, dBarWidthInPixels, (dRectHeight/dMaxY)*iH); // Draw the half pixel width outline in the background color to frame the bars qContext.strokeRect(dStartOfCurrBarPix, 0, dBarWidthInPixels, (dRectHeight/dMaxY)*iH); // The increment for the bar dStartOfCurrBarPix = dEndOfCurrBarPix; ++iBinIndex; } // Fill in the bounds let qLowYElement = document.getElementById("idLowY"); qLowYElement.value = 0; let qHighYElement = document.getElementById("idHighY"); qHighYElement.value = dMaxY.toFixed(1); let qLowXElement = document.getElementById("idLowX"); qLowXElement.value = this.PixelXToGraphX(-.5, iW).toFixed(3); let qHighXElement = document.getElementById("idHighX"); qHighXElement.value = this.PixelXToGraphX(iW-.5, iW).toFixed(3); } } function Initialize() { var qCanvas = document.getElementById("idCanvas"); var qContext = qCanvas.getContext("2d"); var qDist = new CUniformDistribution(10000); qDist.Graph(qContext, 5); }
© 20072025 XoaX.net LLC. All rights reserved.