Transforming Data To Screen Coordinates
Solution 1:
This is how to take your data values and scale them to fit onto the screen. It uses a mapping function to calculate a desired screen value given a specific data value.
functionmapRange(value, dataLow, dataHigh, screenLow, screenHigh) {
return screenLow +
(value - dataLow) * (screenHigh - screenLow) / (dataHigh - dataLow);
}
How it works
At its essence, you must scale the incoming data range to fit inside the any range of screen coordinates that are dedicated to displaying the data.
You are scaling one range into another range. You might think of the scaling factor as a percentage of the data range versus the screen range.
// calculate the scaling factor required to fit the data inside the screenvar scalingFactor = screenRange / dataRange;
All data points fall inside the data range which is calculated like this:
// calculate the min/maxrange of all data
var dataRange= maximumDataValue – minimumDataValue;
All screen coordinates fall inside the screen range which is calculated like this:
// calculate the min/max range of all screen coordinates// that are dedicated to displaying the datavar screenRange = maximumScreenCoordinateValue – minimumScreenCoordinateValue;
If you want to use the full screen then the screenRange
becomes the screen width.
The next step is to calculate the relative position of a specific data-point inside the full data range:
// calculate any one specified data-point's relative position within// the full data rangevar thisDatumPositionInDataRange = thisDataValue – minimumDataValue;
Finally, use the scalingFactor
to map (==scale) a specific data value onto the available screen coordinate.
// calculate the screen coordinate where the specified dataum// will be displayedvar screenCoordinate = minimumScreenValue + thisDatumPositionInDataRange * scalingFactor;
In words, this calculation means:
• Start at the minimum (==leftmost) screen coordinate.
• Move righward on the screen by the specified datum’s relative position (in its data range) scaled by the scalingFactor
.
Here's example annotated code:
// supply a data value (value)// and supply the min & max of the datum and the screen size// return value mapped to fit onto the screenfunctionmapRange(value, dataLow, dataHigh, screenLow, screenHigh) {
return screenLow + (screenHigh - screenLow) * (value - dataLow) / (dataHigh - dataLow);
}
// calculate the max & min of a given arrayfunctioncalcDataMinMax(a){
var min=1000000;
var max=-1000000;
for(var i=0;i<a.length;i++){
var value=a[i];
if(value<min){min=value;}
if(value>max){max=value;}
}
return({min:min,max:max});
}
// Usage:// example datavar data=[5,10,-3,20,0,2];
// example screen widthvar screenWidthMin=0;
var screenWidthMax=640;
// calc the min and max of values in your datavar dataRange=calcDataMinMax(data);
// map the data value 8 to fit onto the screenWidthvar map8=mapRange(8,dataRange.min,dataRange.max,0,100);
Solution 2:
functioncreateTransform(domain, range) {
var domain_min = domain[0];
var domain_max = domain[1];
var range_min = range[0];
var range_max = range[1];
var beta = (range_max / domain_max - range_min / domain_min) * (domain_min * domain_max) / (domain_min - domain_max);
var alpha = (range_min - beta) / domain_min;
returnfunction(x) {
return alpha * x + beta;
};
}
functioncreateTransform(domain, range) {
var domain_min = domain[0];
var domain_max = domain[1];
var range_min = range[0];
var range_max = range[1];
var beta = (range_max / domain_max - range_min / domain_min) * (domain_min * domain_max) / (domain_min - domain_max);
var alpha = (range_min - beta) / domain_min;
returnfunction(x) {
return alpha * x + beta;
};
}
var calculateButton = document.querySelector('.calculate');
var domain_minInput = document.querySelector('.domain_min');
var domain_maxInput = document.querySelector('.domain_max');
var range_minInput = document.querySelector('.range_min');
var range_maxInput = document.querySelector('.range_max');
var xInput = document.querySelector('.x');
var resultBox = document.querySelector('.result');
calculateButton.addEventListener('click', function() {
var domain_min = parseInt(domain_minInput.value);
var domain_max = parseInt(domain_maxInput.value);
var range_min = parseInt(range_minInput.value);
var range_max = parseInt(range_maxInput.value);
var x = parseInt(xInput.value);
var transform = createTransform([domain_min, domain_max], [range_min, range_max]);
resultBox.textContent = transform(x);
});
input {
display: block;
}
domain_min
<inputclass="domain_min">domain_max
<inputclass="domain_max">range_min
<inputclass="range_min">range_max
<inputclass="range_max">x
<inputclass="x"><buttonclass="calculate">Calculate</button><h3>result:</h3><divclass="result"></div>
Post a Comment for "Transforming Data To Screen Coordinates"