mirror of
https://github.com/nasa/openmct.git
synced 2025-04-19 16:40:58 +00:00
MCTChart preserves precision of plot values
This commit is contained in:
parent
b40494ac95
commit
bb8c8a75ab
@ -11,10 +11,10 @@ define(
|
||||
function PlotController($scope) {
|
||||
var plotHistory = [];
|
||||
var isLive = true;
|
||||
var maxDomain = 0;
|
||||
var domainOffset = +new Date();
|
||||
var maxDomain = +new Date();
|
||||
var subscriptions = [];
|
||||
var setToDefaultViewport = function() {
|
||||
// TODO: We shouldn't set the viewport until we have received data or something has given us a reasonable viewport.
|
||||
$scope.viewport = {
|
||||
topLeft: {
|
||||
domain: maxDomain - DOMAIN_INTERVAL,
|
||||
@ -35,7 +35,7 @@ define(
|
||||
};
|
||||
$scope.displayableDomain = function(domainValue) {
|
||||
// TODO: Call format function provided by domain object.
|
||||
return new Date(domainValue + domainOffset).toUTCString();
|
||||
return new Date(domainValue).toUTCString();
|
||||
};
|
||||
|
||||
$scope.series = [];
|
||||
@ -43,10 +43,7 @@ define(
|
||||
$scope.rectangles = [];
|
||||
|
||||
var updateSeriesFromTelemetry = function(series, seriesIndex, telemetry) {
|
||||
if (typeof domainOffset === 'undefined') {
|
||||
domainOffset = telemetry.getDomainValue(telemetry.getPointCount() - 1);
|
||||
}
|
||||
var domainValue = telemetry.getDomainValue(telemetry.getPointCount() - 1) - domainOffset;
|
||||
var domainValue = telemetry.getDomainValue(telemetry.getPointCount() - 1);
|
||||
var rangeValue = telemetry.getRangeValue(telemetry.getPointCount() - 1);
|
||||
// Track the biggest domain we've seen for sticky-ness.
|
||||
maxDomain = Math.max(maxDomain, domainValue);
|
||||
|
@ -10,6 +10,26 @@ define(
|
||||
|
||||
var TEMPLATE = "<canvas style='position: absolute; background: none; width: 100%; height: 100%;'></canvas>";
|
||||
|
||||
/**
|
||||
* Offsetter adjusts domain and range values by a fixed amount,
|
||||
* generally increasing the precision of the 32 bit float representation
|
||||
* required for plotting.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function Offsetter(domainOffset, rangeOffset) {
|
||||
this.domainOffset = domainOffset;
|
||||
this.rangeOffset = rangeOffset;
|
||||
}
|
||||
|
||||
Offsetter.prototype.domain = function(dataDomain) {
|
||||
return dataDomain - this.domainOffset;
|
||||
};
|
||||
|
||||
Offsetter.prototype.range = function(dataRange) {
|
||||
return dataRange - this.rangeOffset;
|
||||
};
|
||||
|
||||
/**
|
||||
* MCTChart draws charts utilizing a drawAPI.
|
||||
*
|
||||
@ -22,7 +42,8 @@ define(
|
||||
isDestroyed = false,
|
||||
activeInterval,
|
||||
drawAPI,
|
||||
lines = [];
|
||||
lines = [],
|
||||
offset;
|
||||
|
||||
drawAPI = DrawLoader.getDrawAPI(canvas);
|
||||
|
||||
@ -34,15 +55,35 @@ define(
|
||||
if (isDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
requestAnimationFrame(redraw);
|
||||
canvas.width = canvas.offsetWidth;
|
||||
canvas.height = canvas.offsetHeight;
|
||||
drawAPI.clear();
|
||||
createOffset();
|
||||
if (!offset) {
|
||||
return;
|
||||
}
|
||||
updateViewport();
|
||||
drawSeries();
|
||||
drawRectangles();
|
||||
}
|
||||
|
||||
function createOffset() {
|
||||
if (offset) {
|
||||
return;
|
||||
}
|
||||
if (!$scope.viewport ||
|
||||
!$scope.viewport.topLeft ||
|
||||
!$scope.viewport.bottomRight) {
|
||||
return;
|
||||
}
|
||||
offset = new Offsetter(
|
||||
$scope.viewport.topLeft.domain,
|
||||
$scope.viewport.topLeft.range
|
||||
);
|
||||
}
|
||||
|
||||
function drawIfResized() {
|
||||
if (canvas.width !== canvas.offsetWidth ||
|
||||
canvas.height !== canvas.offsetHeight) {
|
||||
@ -59,6 +100,9 @@ define(
|
||||
|
||||
function drawSeries() {
|
||||
// TODO: Don't regenerate lines on each frame.
|
||||
if (!$scope.series || !$scope.series.length) {
|
||||
return;
|
||||
}
|
||||
lines = $scope.series.map(lineFromSeries);
|
||||
lines.forEach(function(line) {
|
||||
drawAPI.drawLine(
|
||||
@ -73,8 +117,14 @@ define(
|
||||
if ($scope.rectangles) {
|
||||
$scope.rectangles.forEach(function(rect) {
|
||||
drawAPI.drawSquare(
|
||||
[rect.start.domain, rect.start.range],
|
||||
[rect.end.domain, rect.end.range],
|
||||
[
|
||||
offset.domain(rect.start.domain),
|
||||
offset.range(rect.start.range)
|
||||
],
|
||||
[
|
||||
offset.domain(rect.end.domain),
|
||||
offset.range(rect.end.range)
|
||||
],
|
||||
rect.color
|
||||
);
|
||||
});
|
||||
@ -83,13 +133,23 @@ define(
|
||||
|
||||
function updateViewport() {
|
||||
var dimensions = [
|
||||
Math.abs($scope.viewport.topLeft.domain - $scope.viewport.bottomRight.domain),
|
||||
Math.abs($scope.viewport.topLeft.range - $scope.viewport.bottomRight.range)
|
||||
Math.abs(
|
||||
offset.domain($scope.viewport.topLeft.domain) -
|
||||
offset.domain($scope.viewport.bottomRight.domain)
|
||||
),
|
||||
Math.abs(
|
||||
offset.range($scope.viewport.topLeft.range) -
|
||||
offset.range($scope.viewport.bottomRight.range)
|
||||
)
|
||||
];
|
||||
|
||||
var origin = [
|
||||
$scope.viewport.topLeft.domain,
|
||||
$scope.viewport.bottomRight.range
|
||||
offset.domain(
|
||||
$scope.viewport.topLeft.domain
|
||||
),
|
||||
offset.range(
|
||||
$scope.viewport.bottomRight.range
|
||||
)
|
||||
];
|
||||
|
||||
drawAPI.setDimensions(
|
||||
@ -113,8 +173,8 @@ define(
|
||||
// appears minimal.
|
||||
var lineBuffer = new Float32Array(20000);
|
||||
for (var i = 0; i < series.data.length; i++) {
|
||||
lineBuffer[2*i] = series.data[i].domain;
|
||||
lineBuffer[2*i+1] = series.data[i].range;
|
||||
lineBuffer[2*i] = offset.domain(series.data[i].domain);
|
||||
lineBuffer[2*i+1] = offset.range(series.data[i].range);
|
||||
}
|
||||
return {
|
||||
color: series.color,
|
||||
@ -123,15 +183,11 @@ define(
|
||||
};
|
||||
}
|
||||
|
||||
function initializeLines() {
|
||||
lines = $scope.series.map(lineFromSeries);
|
||||
}
|
||||
|
||||
function onSeriesDataAdd(event, seriesIndex, points) {
|
||||
var line = lines[seriesIndex];
|
||||
points.forEach(function (point) {
|
||||
line.buffer[2*line.pointCount] = point.domain;
|
||||
line.buffer[2*line.pointCount+1] = point.range;
|
||||
line.buffer[2*line.pointCount] = offset.domain(point.domain);
|
||||
line.buffer[2*line.pointCount+1] = offset.range(point.range);
|
||||
line.pointCount += 1;
|
||||
});
|
||||
}
|
||||
@ -139,8 +195,6 @@ define(
|
||||
// Check for resize, on a timer
|
||||
activeInterval = $interval(drawIfResized, 1000);
|
||||
|
||||
// Initialize series
|
||||
$scope.$watch('series', initializeLines);
|
||||
$scope.$on('series:data:add', onSeriesDataAdd);
|
||||
redraw();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user