mirror of
https://github.com/nasa/openmct.git
synced 2025-06-12 20:28:14 +00:00
[Plot] Organize plot elements
Place elements of the PlotController into a separate directory inside of the source folder for the plot plug-in, in preparation for review and integration. Part of ongoing plot transition to Angular, WTD-533.
This commit is contained in:
35
platform/features/plot/src/elements/PlotAxis.js
Normal file
35
platform/features/plot/src/elements/PlotAxis.js
Normal file
@ -0,0 +1,35 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
function PlotAxis(axisType, metadatas, defaultValue) {
|
||||
var keys = {},
|
||||
options = [];
|
||||
|
||||
function buildOptionsForMetadata(m) {
|
||||
(m[axisType] || []).forEach(function (option) {
|
||||
if (!keys[option.key]) {
|
||||
keys[option.key] = true;
|
||||
options.push(option);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
(metadatas || []).forEach(buildOptionsForMetadata);
|
||||
|
||||
// Plot axis will be used directly from the Angular
|
||||
// template, so expose properties directly to facilitate
|
||||
// two-way data binding (for drop-down menus)
|
||||
return {
|
||||
options: options,
|
||||
active: options[0] || defaultValue
|
||||
};
|
||||
}
|
||||
|
||||
return PlotAxis;
|
||||
|
||||
}
|
||||
);
|
28
platform/features/plot/src/elements/PlotFormatter.js
Normal file
28
platform/features/plot/src/elements/PlotFormatter.js
Normal file
@ -0,0 +1,28 @@
|
||||
/*global define,moment*/
|
||||
|
||||
define(
|
||||
["../../lib/moment.min"],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
var DATE_FORMAT = "YYYY-DDD HH:mm:ss";
|
||||
|
||||
function PlotFormatter() {
|
||||
function formatDomainValue(v) {
|
||||
return moment.utc(v).format(DATE_FORMAT);
|
||||
}
|
||||
|
||||
function formatRangeValue(v) {
|
||||
return v.toFixed(1);
|
||||
}
|
||||
|
||||
return {
|
||||
formatDomainValue: formatDomainValue,
|
||||
formatRangeValue: formatRangeValue
|
||||
};
|
||||
}
|
||||
|
||||
return PlotFormatter;
|
||||
|
||||
}
|
||||
);
|
74
platform/features/plot/src/elements/PlotPalette.js
Normal file
74
platform/features/plot/src/elements/PlotPalette.js
Normal file
@ -0,0 +1,74 @@
|
||||
/*global define*/
|
||||
|
||||
/**
|
||||
* Plot palette. Defines colors for various plot lines.
|
||||
*/
|
||||
define(
|
||||
function () {
|
||||
'use strict';
|
||||
|
||||
// Prepare different forms of the palette, since we wish to
|
||||
// describe colors in several ways (as RGB 0-255, as
|
||||
// RGB 0.0-1.0, or as stylesheet-appropriate #-prefixed colors).
|
||||
var integerPalette = [
|
||||
[ 0x20, 0xB2, 0xAA ],
|
||||
[ 0x9A, 0xCD, 0x32 ],
|
||||
[ 0xFF, 0x8C, 0x00 ],
|
||||
[ 0xD2, 0xB4, 0x8C ],
|
||||
[ 0x40, 0xE0, 0xD0 ],
|
||||
[ 0x41, 0x69, 0xFF ],
|
||||
[ 0xFF, 0xD7, 0x00 ],
|
||||
[ 0x6A, 0x5A, 0xCD ],
|
||||
[ 0xEE, 0x82, 0xEE ],
|
||||
[ 0xCC, 0x99, 0x66 ],
|
||||
[ 0x99, 0xCC, 0xCC ],
|
||||
[ 0x66, 0xCC, 0x33 ],
|
||||
[ 0xFF, 0xCC, 0x00 ],
|
||||
[ 0xFF, 0x66, 0x33 ],
|
||||
[ 0xCC, 0x66, 0xFF ],
|
||||
[ 0xFF, 0x00, 0x66 ],
|
||||
[ 0xFF, 0xFF, 0x00 ],
|
||||
[ 0x80, 0x00, 0x80 ],
|
||||
[ 0x00, 0x86, 0x8B ],
|
||||
[ 0x00, 0x8A, 0x00 ],
|
||||
[ 0xFF, 0x00, 0x00 ],
|
||||
[ 0x00, 0x00, 0xFF ],
|
||||
[ 0xF5, 0xDE, 0xB3 ],
|
||||
[ 0xBC, 0x8F, 0x8F ],
|
||||
[ 0x46, 0x82, 0xB4 ],
|
||||
[ 0xFF, 0xAF, 0xAF ],
|
||||
[ 0x43, 0xCD, 0x80 ],
|
||||
[ 0xCD, 0xC1, 0xC5 ],
|
||||
[ 0xA0, 0x52, 0x2D ],
|
||||
[ 0x64, 0x95, 0xED ]
|
||||
], stringPalette = integerPalette.map(function (arr) {
|
||||
// Convert to # notation for use in styles
|
||||
return '#' + arr.map(function (c) {
|
||||
return (c < 16 ? '0' : '') + c.toString(16);
|
||||
}).join('');
|
||||
}), floatPalette = integerPalette.map(function (arr) {
|
||||
return arr.map(function (c) {
|
||||
return c / 255.0;
|
||||
}).concat([1]); // RGBA
|
||||
});
|
||||
|
||||
function PlotPalette() {
|
||||
return PlotPalette;
|
||||
}
|
||||
|
||||
PlotPalette.getIntegerColor = function (i) {
|
||||
return integerPalette[Math.floor(i) % integerPalette.length];
|
||||
};
|
||||
|
||||
PlotPalette.getFloatColor = function (i) {
|
||||
return floatPalette[Math.floor(i) % floatPalette.length];
|
||||
};
|
||||
|
||||
PlotPalette.getStringColor = function (i) {
|
||||
return stringPalette[Math.floor(i) % stringPalette.length];
|
||||
};
|
||||
|
||||
return PlotPalette;
|
||||
|
||||
}
|
||||
);
|
59
platform/features/plot/src/elements/PlotPanZoomStack.js
Normal file
59
platform/features/plot/src/elements/PlotPanZoomStack.js
Normal file
@ -0,0 +1,59 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
function PlotPanZoomStack(origin, dimensions) {
|
||||
var stack = [{ origin: origin, dimensions: dimensions }];
|
||||
|
||||
function getDepth() {
|
||||
return stack.length;
|
||||
}
|
||||
|
||||
function pushPanZoom(origin, dimensions) {
|
||||
stack.push({ origin: origin, dimensions: dimensions });
|
||||
}
|
||||
|
||||
function popPanZoom() {
|
||||
if (stack.length > 1) {
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
function clearPanZoom() {
|
||||
stack = [stack[0]];
|
||||
}
|
||||
|
||||
function setBasePanZoom(origin, dimensions) {
|
||||
stack[0] = { origin: origin, dimensions: dimensions };
|
||||
}
|
||||
|
||||
function getPanZoom() {
|
||||
return stack[stack.length - 1];
|
||||
}
|
||||
|
||||
function getOrigin() {
|
||||
return getPanZoom().origin;
|
||||
}
|
||||
|
||||
function getDimensions() {
|
||||
return getPanZoom().dimensions;
|
||||
}
|
||||
|
||||
return {
|
||||
getDepth: getDepth,
|
||||
pushPanZoom: pushPanZoom,
|
||||
popPanZoom: popPanZoom,
|
||||
setBasePanZoom: setBasePanZoom,
|
||||
clearPanZoom: clearPanZoom,
|
||||
getPanZoom: getPanZoom,
|
||||
getOrigin: getOrigin,
|
||||
getDimensions: getDimensions
|
||||
};
|
||||
}
|
||||
|
||||
return PlotPanZoomStack;
|
||||
}
|
||||
);
|
38
platform/features/plot/src/elements/PlotPosition.js
Normal file
38
platform/features/plot/src/elements/PlotPosition.js
Normal file
@ -0,0 +1,38 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
function PlotPosition(x, y, width, height, panZoomStack) {
|
||||
var panZoom = panZoomStack.getPanZoom(),
|
||||
origin = panZoom.origin,
|
||||
dimensions = panZoom.dimensions,
|
||||
position;
|
||||
|
||||
if (!dimensions || !origin) {
|
||||
position = [];
|
||||
} else {
|
||||
position = [ x / width, (height - y) / height ].map(function (v, i) {
|
||||
return v * dimensions[i] + origin[i];
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
getDomain: function () {
|
||||
return position[0];
|
||||
},
|
||||
getRange: function () {
|
||||
return position[1];
|
||||
},
|
||||
getPosition: function () {
|
||||
return position;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
return PlotPosition;
|
||||
}
|
||||
);
|
92
platform/features/plot/src/elements/PlotPreparer.js
Normal file
92
platform/features/plot/src/elements/PlotPreparer.js
Normal file
@ -0,0 +1,92 @@
|
||||
/*global define,Float32Array*/
|
||||
|
||||
/**
|
||||
* Prepares data to be rendered in a GL Plot. Handles
|
||||
* the conversion from data API to displayable buffers.
|
||||
*/
|
||||
define(
|
||||
function () {
|
||||
'use strict';
|
||||
|
||||
function identity(x) { return x; }
|
||||
|
||||
function PlotPreparer(datas, domain, range) {
|
||||
var index,
|
||||
vertices = [],
|
||||
max = [Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY],
|
||||
min = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY],
|
||||
x,
|
||||
y,
|
||||
xLabels = {},
|
||||
yLabels = {},
|
||||
yUnits = {},
|
||||
domainOffset = Number.POSITIVE_INFINITY,
|
||||
buffers;
|
||||
|
||||
datas = datas || [];
|
||||
|
||||
datas.filter(identity).forEach(function (data) {
|
||||
domainOffset = Math.min(data.getDomainValue(0, domain), domainOffset);
|
||||
});
|
||||
|
||||
datas.forEach(function (data, i) {
|
||||
if (!data) {
|
||||
return; // skip null data
|
||||
}
|
||||
|
||||
vertices.push([]);
|
||||
for (index = 0; index < data.getPointCount(); index = index + 1) {
|
||||
x = data.getDomainValue(index, domain);
|
||||
y = data.getRangeValue(index, range);
|
||||
vertices[i].push(x - domainOffset);
|
||||
vertices[i].push(y);
|
||||
min[0] = Math.min(min[0], x);
|
||||
min[1] = Math.min(min[1], y);
|
||||
max[0] = Math.max(max[0], x);
|
||||
max[1] = Math.max(max[1], y);
|
||||
}
|
||||
|
||||
if (data.getDomainLabel) {
|
||||
xLabels[data.getDomainLabel(domain)] = true;
|
||||
}
|
||||
|
||||
if (data.getRangeLabel) {
|
||||
yLabels[data.getRangeLabel(range)] = true;
|
||||
}
|
||||
|
||||
if (data.getRangeUnits) {
|
||||
yUnits[data.getRangeUnits(range)] = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (max[1] === min[1]) {
|
||||
max[1] = max[1] + 1.0;
|
||||
min[1] = min[1] - 1.0;
|
||||
}
|
||||
|
||||
xLabels = Object.keys(xLabels).sort();
|
||||
yLabels = Object.keys(yLabels).sort();
|
||||
yUnits = Object.keys(yUnits).sort();
|
||||
|
||||
buffers = vertices.map(function (v) { return new Float32Array(v); });
|
||||
|
||||
return {
|
||||
getDimensions: function () {
|
||||
return [max[0] - min[0], max[1] - min[1]];
|
||||
},
|
||||
getOrigin: function () {
|
||||
return min;
|
||||
},
|
||||
getDomainOffset: function () {
|
||||
return domainOffset;
|
||||
},
|
||||
getBuffers: function () {
|
||||
return buffers;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return PlotPreparer;
|
||||
|
||||
}
|
||||
);
|
50
platform/features/plot/src/elements/PlotTickGenerator.js
Normal file
50
platform/features/plot/src/elements/PlotTickGenerator.js
Normal file
@ -0,0 +1,50 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
function PlotTickGenerator(panZoomStack, formatter) {
|
||||
|
||||
function generateTicks(start, span, count, format) {
|
||||
var step = span / (count - 1),
|
||||
result = [],
|
||||
i;
|
||||
|
||||
for (i = 0; i < count; i += 1) {
|
||||
result.push({
|
||||
label: format(i * step + start)
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
generateDomainTicks: function (count) {
|
||||
var panZoom = panZoomStack.getPanZoom();
|
||||
return generateTicks(
|
||||
panZoom.origin[0],
|
||||
panZoom.dimensions[0],
|
||||
count,
|
||||
formatter.formatDomainValue
|
||||
);
|
||||
},
|
||||
generateRangeTicks: function (count) {
|
||||
var panZoom = panZoomStack.getPanZoom();
|
||||
return generateTicks(
|
||||
panZoom.origin[1],
|
||||
panZoom.dimensions[1],
|
||||
count,
|
||||
formatter.formatRangeValue
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
return PlotTickGenerator;
|
||||
}
|
||||
);
|
Reference in New Issue
Block a user