mirror of
https://github.com/nasa/openmct.git
synced 2025-06-02 07:30:49 +00:00
[Plot] Begin refactoring for stacked plots
Begin refactoring Plot view to support stacked plots; separate out behavior which needs to occur per-plot from area which should occur per-view, and add a handler for the Overlay mode. WTD-625.
This commit is contained in:
parent
1c3d2d923f
commit
784b2b6186
@ -6,7 +6,7 @@
|
|||||||
<span ng-repeat="subplot in plot.getSubPlots()">
|
<span ng-repeat="subplot in plot.getSubPlots()">
|
||||||
<div class="gl-plot-legend">
|
<div class="gl-plot-legend">
|
||||||
<span class='plot-legend-item'
|
<span class='plot-legend-item'
|
||||||
ng-repeat="telemetryObject in subplot.telemetryObjects">
|
ng-repeat="telemetryObject in subplot.getTelemetryObjects()">
|
||||||
<span class='plot-color-swatch'
|
<span class='plot-color-swatch'
|
||||||
ng-style="{ 'background-color': plot.getColor($index) }">
|
ng-style="{ 'background-color': plot.getColor($index) }">
|
||||||
</span>
|
</span>
|
||||||
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
<div class="gl-plot-coords"
|
<div class="gl-plot-coords"
|
||||||
ng-if="representation.showControls">
|
ng-if="representation.showControls">
|
||||||
{{plot.getHoverCoordinates().join(', ')}}
|
{{subplot.getHoverCoordinates().join(', ')}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="gl-plot-axis-area gl-plot-y">
|
<div class="gl-plot-axis-area gl-plot-y">
|
||||||
@ -48,17 +48,17 @@
|
|||||||
ng-mouseenter="representation.showControls = true">
|
ng-mouseenter="representation.showControls = true">
|
||||||
|
|
||||||
<div class="gl-plot-hash hash-v"
|
<div class="gl-plot-hash hash-v"
|
||||||
ng-repeat="tick in subplot.domainTicks"
|
ng-repeat="tick in subplot.getDomainTicks()"
|
||||||
ng-style="{ left: (100 * $index / (subplot.domainTicks.length - 1)) + '%', height: '100%' }"
|
ng-style="{ left: (100 * $index / (subplot.getDomainTicks().length - 1)) + '%', height: '100%' }"
|
||||||
ng-show="$index > 0 && $index < (subplot.domainTicks.length - 1)">
|
ng-show="$index > 0 && $index < (subplot.getDomainTicks().length - 1)">
|
||||||
</div>
|
</div>
|
||||||
<div class="gl-plot-hash hash-h"
|
<div class="gl-plot-hash hash-h"
|
||||||
ng-repeat="tick in rangeTicks"
|
ng-repeat="tick in subplot.getRangeTicks()"
|
||||||
ng-style="{ bottom: (100 * $index / (subplot.rangeTicks.length - 1)) + '%', width: '100%' }"
|
ng-style="{ bottom: (100 * $index / (subplot.getRangeTicks().length - 1)) + '%', width: '100%' }"
|
||||||
ng-show="$index > 0 && $index < (subplot.rangeTicks.length - 1)">
|
ng-show="$index > 0 && $index < (subplot.getRangeTicks().length - 1)">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<mct-chart draw="subplot.draw"
|
<mct-chart draw="subplot.getDrawingObject()"
|
||||||
ng-mousemove="subplot.hover($event)"
|
ng-mousemove="subplot.hover($event)"
|
||||||
ng-mousedown="subplot.startMarquee($event)"
|
ng-mousedown="subplot.startMarquee($event)"
|
||||||
ng-mouseup="subplot.endMarquee($event)">
|
ng-mouseup="subplot.endMarquee($event)">
|
||||||
@ -117,10 +117,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div ng-if="$last" class="gl-plot-axis-area gl-plot-x">
|
<div ng-if="$last" class="gl-plot-axis-area gl-plot-x">
|
||||||
|
|
||||||
<div ng-repeat="tick in domainTicks"
|
<div ng-repeat="tick in subplot.getDomainTicks()"
|
||||||
class="gl-plot-tick gl-plot-x-tick-label"
|
class="gl-plot-tick gl-plot-x-tick-label"
|
||||||
ng-show="$index > 0 && $index < (domainTicks.length - 1)"
|
ng-show="$index > 0 && $index < (subplot.getDomainTicks().length - 1)"
|
||||||
ng-style="{ left: (100 * $index / (domainTicks.length - 1)) + '%' }">
|
ng-style="{ left: (100 * $index / (subplot.getDomainTicks().length - 1)) + '%' }">
|
||||||
{{tick.label}}
|
{{tick.label}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -45,94 +45,10 @@ define(
|
|||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function PlotController($scope) {
|
function PlotController($scope) {
|
||||||
var mousePosition,
|
var modeOptions = new PlotModeOptions([]),
|
||||||
marqueeStart,
|
subplots = [],
|
||||||
panZoomStack = new PlotPanZoomStack([], []),
|
|
||||||
formatter = new PlotFormatter(),
|
|
||||||
modeOptions,
|
|
||||||
domainOffset;
|
domainOffset;
|
||||||
|
|
||||||
// Utility, for map/forEach loops. Index 0 is domain,
|
|
||||||
// index 1 is range.
|
|
||||||
function formatValue(v, i) {
|
|
||||||
return (i ?
|
|
||||||
formatter.formatRangeValue :
|
|
||||||
formatter.formatDomainValue)(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts from pixel coordinates to domain-range,
|
|
||||||
// to interpret mouse gestures.
|
|
||||||
function mousePositionToDomainRange(mousePosition) {
|
|
||||||
return new PlotPosition(
|
|
||||||
mousePosition.x,
|
|
||||||
mousePosition.y,
|
|
||||||
mousePosition.width,
|
|
||||||
mousePosition.height,
|
|
||||||
panZoomStack
|
|
||||||
).getPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility function to get the mouse position (in x,y
|
|
||||||
// pixel coordinates in the canvas area) from a mouse
|
|
||||||
// event object.
|
|
||||||
function toMousePosition($event) {
|
|
||||||
var target = $event.target,
|
|
||||||
bounds = target.getBoundingClientRect();
|
|
||||||
|
|
||||||
return {
|
|
||||||
x: $event.clientX - bounds.left,
|
|
||||||
y: $event.clientY - bounds.top,
|
|
||||||
width: bounds.width,
|
|
||||||
height: bounds.height
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert a domain-range position to a displayable
|
|
||||||
// position. This will subtract the domain offset, which
|
|
||||||
// is used to bias domain values to minimize loss-of-precision
|
|
||||||
// associated with conversion to a 32-bit floating point
|
|
||||||
// format (which is needed in the chart area itself, by WebGL.)
|
|
||||||
function toDisplayable(position) {
|
|
||||||
return [ position[0] - domainOffset, position[1] ];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the drawable marquee area to reflect current
|
|
||||||
// mouse position (or don't show it at all, if no marquee
|
|
||||||
// zoom is in progress)
|
|
||||||
function updateMarqueeBox() {
|
|
||||||
// Express this as a box in the draw object, which
|
|
||||||
// is passed to an mct-chart in the template for rendering.
|
|
||||||
$scope.draw.boxes = marqueeStart ?
|
|
||||||
[{
|
|
||||||
start: toDisplayable(mousePositionToDomainRange(marqueeStart)),
|
|
||||||
end: toDisplayable(mousePositionToDomainRange(mousePosition)),
|
|
||||||
color: [1, 1, 1, 0.5 ]
|
|
||||||
}] : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the bounds (origin and dimensions) of the drawing area.
|
|
||||||
function updateDrawingBounds() {
|
|
||||||
var panZoom = panZoomStack.getPanZoom();
|
|
||||||
|
|
||||||
// Communicate pan-zoom state from stack to the draw object
|
|
||||||
// which is passed to mct-chart in the template.
|
|
||||||
$scope.draw.dimensions = panZoom.dimensions;
|
|
||||||
$scope.draw.origin = [
|
|
||||||
panZoom.origin[0] - domainOffset,
|
|
||||||
panZoom.origin[1]
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update tick marks in scope.
|
|
||||||
function updateTicks() {
|
|
||||||
var tickGenerator = new PlotTickGenerator(panZoomStack, formatter);
|
|
||||||
|
|
||||||
$scope.domainTicks =
|
|
||||||
tickGenerator.generateDomainTicks(DOMAIN_TICKS);
|
|
||||||
$scope.rangeTicks =
|
|
||||||
tickGenerator.generateRangeTicks(RANGE_TICKS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate the scope with axis information (specifically, options
|
// Populate the scope with axis information (specifically, options
|
||||||
// available for each axis.)
|
// available for each axis.)
|
||||||
function setupAxes(metadatas) {
|
function setupAxes(metadatas) {
|
||||||
@ -171,63 +87,16 @@ define(
|
|||||||
($scope.axes[1].active || {}).key
|
($scope.axes[1].active || {}).key
|
||||||
);
|
);
|
||||||
|
|
||||||
// Fit to the boundaries of the data, but don't
|
modeOptions.getModeHandler().plotTelemetry(prepared);
|
||||||
// override any user-initiated pan-zoom changes.
|
|
||||||
panZoomStack.setBasePanZoom(
|
|
||||||
prepared.getOrigin(),
|
|
||||||
prepared.getDimensions()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Track the domain offset, used to bias domain values
|
|
||||||
// to minimize loss of precision when converted to 32-bit
|
|
||||||
// floating point values for display.
|
|
||||||
domainOffset = prepared.getDomainOffset();
|
|
||||||
|
|
||||||
// Draw the buffers. Select color by index.
|
|
||||||
$scope.draw.lines = prepared.getBuffers().map(function (buf, i) {
|
|
||||||
return {
|
|
||||||
buffer: buf,
|
|
||||||
color: PlotPalette.getFloatColor(i),
|
|
||||||
points: buf.length / 2
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
updateDrawingBounds();
|
|
||||||
updateMarqueeBox();
|
|
||||||
updateTicks();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform a marquee zoom.
|
|
||||||
function marqueeZoom(start, end) {
|
|
||||||
// Determine what boundary is described by the marquee,
|
|
||||||
// in domain-range values. Use the minima for origin, so that
|
|
||||||
// it doesn't matter what direction the user marqueed in.
|
|
||||||
var a = mousePositionToDomainRange(start),
|
|
||||||
b = mousePositionToDomainRange(end),
|
|
||||||
origin = [
|
|
||||||
Math.min(a[0], b[0]),
|
|
||||||
Math.min(a[1], b[1])
|
|
||||||
],
|
|
||||||
dimensions = [
|
|
||||||
Math.max(a[0], b[0]) - origin[0],
|
|
||||||
Math.max(a[1], b[1]) - origin[1]
|
|
||||||
];
|
|
||||||
|
|
||||||
// Push the new state onto the pan-zoom stack
|
|
||||||
panZoomStack.pushPanZoom(origin, dimensions);
|
|
||||||
|
|
||||||
// Make sure tick marks reflect new bounds
|
|
||||||
updateTicks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupModes(telemetryObjects) {
|
function setupModes(telemetryObjects) {
|
||||||
modeOptions = new PlotModeOptions(telemetryObjects);
|
modeOptions = new PlotModeOptions(telemetryObjects || []);
|
||||||
}
|
}
|
||||||
|
|
||||||
$scope.$watch("telemetry.getTelemetryObjects()", setupModes);
|
$scope.$watch("telemetry.getTelemetryObjects()", setupModes);
|
||||||
$scope.$watch("telemetry.getMetadata()", setupAxes);
|
$scope.$watch("telemetry.getMetadata()", setupAxes);
|
||||||
$scope.$on("telemetryUpdate", plotTelemetry);
|
$scope.$on("telemetryUpdate", plotTelemetry);
|
||||||
$scope.draw = {};
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
/**
|
/**
|
||||||
@ -239,49 +108,6 @@ define(
|
|||||||
getColor: function (index) {
|
getColor: function (index) {
|
||||||
return PlotPalette.getStringColor(index);
|
return PlotPalette.getStringColor(index);
|
||||||
},
|
},
|
||||||
/**
|
|
||||||
* Get the coordinates (as displayable text) for the
|
|
||||||
* current mouse position.
|
|
||||||
* @returns {string[]} the displayable domain and range
|
|
||||||
* coordinates over which the mouse is hovered
|
|
||||||
*/
|
|
||||||
getHoverCoordinates: function () {
|
|
||||||
return mousePosition ?
|
|
||||||
mousePositionToDomainRange(
|
|
||||||
mousePosition
|
|
||||||
).map(formatValue) : [];
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Handle mouse movement over the chart area.
|
|
||||||
* @param $event the mouse event
|
|
||||||
*/
|
|
||||||
hover: function ($event) {
|
|
||||||
mousePosition = toMousePosition($event);
|
|
||||||
if (marqueeStart) {
|
|
||||||
updateMarqueeBox();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Initiate a marquee zoom action.
|
|
||||||
* @param $event the mouse event
|
|
||||||
*/
|
|
||||||
startMarquee: function ($event) {
|
|
||||||
mousePosition = marqueeStart = toMousePosition($event);
|
|
||||||
updateMarqueeBox();
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Complete a marquee zoom action.
|
|
||||||
* @param $event the mouse event
|
|
||||||
*/
|
|
||||||
endMarquee: function ($event) {
|
|
||||||
mousePosition = toMousePosition($event);
|
|
||||||
if (marqueeStart) {
|
|
||||||
marqueeZoom(marqueeStart, mousePosition);
|
|
||||||
marqueeStart = undefined;
|
|
||||||
updateMarqueeBox();
|
|
||||||
updateDrawingBounds();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
/**
|
||||||
* Check if the plot is zoomed or panned out
|
* Check if the plot is zoomed or panned out
|
||||||
* of its default state (to determine whether back/unzoom
|
* of its default state (to determine whether back/unzoom
|
||||||
@ -289,36 +115,34 @@ define(
|
|||||||
* @returns {boolean} true if not in default state
|
* @returns {boolean} true if not in default state
|
||||||
*/
|
*/
|
||||||
isZoomed: function () {
|
isZoomed: function () {
|
||||||
return panZoomStack.getDepth() > 1;
|
return modeOptions.getModeHandler().isZoomed();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Undo the most recent pan/zoom change and restore
|
* Undo the most recent pan/zoom change and restore
|
||||||
* the prior state.
|
* the prior state.
|
||||||
*/
|
*/
|
||||||
stepBackPanZoom: function () {
|
stepBackPanZoom: function () {
|
||||||
panZoomStack.popPanZoom();
|
return modeOptions.getModeHandler().stepBackPanZoom();
|
||||||
updateDrawingBounds();
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Undo all pan/zoom changes and restore the initial state.
|
* Undo all pan/zoom changes and restore the initial state.
|
||||||
*/
|
*/
|
||||||
unzoom: function () {
|
unzoom: function () {
|
||||||
panZoomStack.clearPanZoom();
|
return modeOptions.getModeHandler().unzoom();
|
||||||
updateDrawingBounds();
|
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Get the mode options (Stacked/Overlaid) that are applicable
|
* Get the mode options (Stacked/Overlaid) that are applicable
|
||||||
* for this plot.
|
* for this plot.
|
||||||
*/
|
*/
|
||||||
getModeOptions: function () {
|
getModeOptions: function () {
|
||||||
return modeOptions && modeOptions.getModeOptions();
|
return modeOptions.getModeOptions();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Get the current mode that is applicable to this plot. This
|
* Get the current mode that is applicable to this plot. This
|
||||||
* will include key, name, and glyph fields.
|
* will include key, name, and glyph fields.
|
||||||
*/
|
*/
|
||||||
getMode: function () {
|
getMode: function () {
|
||||||
return modeOptions && modeOptions.getMode();
|
return modeOptions.getMode();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Set the mode which should be active in this plot.
|
* Set the mode which should be active in this plot.
|
||||||
@ -326,7 +150,15 @@ define(
|
|||||||
* getModeOptions()
|
* getModeOptions()
|
||||||
*/
|
*/
|
||||||
setMode: function (mode) {
|
setMode: function (mode) {
|
||||||
return modeOptions && modeOptions.setMode(mode);
|
return modeOptions.setMode(mode);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Get all individual plots contained within this Plot view.
|
||||||
|
* (Multiple may be contained when in Stacked mode).
|
||||||
|
* @returns {SubPlot[]} all subplots in this Plot view
|
||||||
|
*/
|
||||||
|
getSubPlots: function () {
|
||||||
|
return modeOptions.getModeHandler().getSubPlots();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
201
platform/features/plot/src/SubPlot.js
Normal file
201
platform/features/plot/src/SubPlot.js
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
/*global define*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
['elements/PlotPosition', 'elements/PlotFormatter', 'elements/PlotTickGenerator'],
|
||||||
|
function (PlotPosition, PlotFormatter, PlotTickGenerator) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var AXIS_DEFAULTS = [
|
||||||
|
{ "name": "Time" },
|
||||||
|
{ "name": "Value" }
|
||||||
|
],
|
||||||
|
DOMAIN_TICKS = 5,
|
||||||
|
RANGE_TICKS = 7;
|
||||||
|
|
||||||
|
function SubPlot(telemetryObjects, panZoomStack) {
|
||||||
|
var draw = {},
|
||||||
|
rangeTicks = [],
|
||||||
|
domainTicks = [],
|
||||||
|
formatter = new PlotFormatter(),
|
||||||
|
domainOffset,
|
||||||
|
mousePosition,
|
||||||
|
marqueeStart;
|
||||||
|
|
||||||
|
// Utility, for map/forEach loops. Index 0 is domain,
|
||||||
|
// index 1 is range.
|
||||||
|
function formatValue(v, i) {
|
||||||
|
return (i ?
|
||||||
|
formatter.formatRangeValue :
|
||||||
|
formatter.formatDomainValue)(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Converts from pixel coordinates to domain-range,
|
||||||
|
// to interpret mouse gestures.
|
||||||
|
function mousePositionToDomainRange(mousePosition) {
|
||||||
|
return new PlotPosition(
|
||||||
|
mousePosition.x,
|
||||||
|
mousePosition.y,
|
||||||
|
mousePosition.width,
|
||||||
|
mousePosition.height,
|
||||||
|
panZoomStack
|
||||||
|
).getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility function to get the mouse position (in x,y
|
||||||
|
// pixel coordinates in the canvas area) from a mouse
|
||||||
|
// event object.
|
||||||
|
function toMousePosition($event) {
|
||||||
|
var target = $event.target,
|
||||||
|
bounds = target.getBoundingClientRect();
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: $event.clientX - bounds.left,
|
||||||
|
y: $event.clientY - bounds.top,
|
||||||
|
width: bounds.width,
|
||||||
|
height: bounds.height
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert a domain-range position to a displayable
|
||||||
|
// position. This will subtract the domain offset, which
|
||||||
|
// is used to bias domain values to minimize loss-of-precision
|
||||||
|
// associated with conversion to a 32-bit floating point
|
||||||
|
// format (which is needed in the chart area itself, by WebGL.)
|
||||||
|
function toDisplayable(position) {
|
||||||
|
return [ position[0] - domainOffset, position[1] ];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the drawable marquee area to reflect current
|
||||||
|
// mouse position (or don't show it at all, if no marquee
|
||||||
|
// zoom is in progress)
|
||||||
|
function updateMarqueeBox() {
|
||||||
|
// Express this as a box in the draw object, which
|
||||||
|
// is passed to an mct-chart in the template for rendering.
|
||||||
|
draw.boxes = marqueeStart ?
|
||||||
|
[{
|
||||||
|
start: toDisplayable(mousePositionToDomainRange(marqueeStart)),
|
||||||
|
end: toDisplayable(mousePositionToDomainRange(mousePosition)),
|
||||||
|
color: [1, 1, 1, 0.5 ]
|
||||||
|
}] : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the bounds (origin and dimensions) of the drawing area.
|
||||||
|
function updateDrawingBounds() {
|
||||||
|
var panZoom = panZoomStack.getPanZoom();
|
||||||
|
|
||||||
|
// Communicate pan-zoom state from stack to the draw object
|
||||||
|
// which is passed to mct-chart in the template.
|
||||||
|
draw.dimensions = panZoom.dimensions;
|
||||||
|
draw.origin = [
|
||||||
|
panZoom.origin[0] - domainOffset,
|
||||||
|
panZoom.origin[1]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update tick marks in scope.
|
||||||
|
function updateTicks() {
|
||||||
|
var tickGenerator = new PlotTickGenerator(panZoomStack, formatter);
|
||||||
|
|
||||||
|
domainTicks =
|
||||||
|
tickGenerator.generateDomainTicks(DOMAIN_TICKS);
|
||||||
|
rangeTicks =
|
||||||
|
tickGenerator.generateRangeTicks(RANGE_TICKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Perform a marquee zoom.
|
||||||
|
function marqueeZoom(start, end) {
|
||||||
|
// Determine what boundary is described by the marquee,
|
||||||
|
// in domain-range values. Use the minima for origin, so that
|
||||||
|
// it doesn't matter what direction the user marqueed in.
|
||||||
|
var a = mousePositionToDomainRange(start),
|
||||||
|
b = mousePositionToDomainRange(end),
|
||||||
|
origin = [
|
||||||
|
Math.min(a[0], b[0]),
|
||||||
|
Math.min(a[1], b[1])
|
||||||
|
],
|
||||||
|
dimensions = [
|
||||||
|
Math.max(a[0], b[0]) - origin[0],
|
||||||
|
Math.max(a[1], b[1]) - origin[1]
|
||||||
|
];
|
||||||
|
|
||||||
|
// Push the new state onto the pan-zoom stack
|
||||||
|
panZoomStack.pushPanZoom(origin, dimensions);
|
||||||
|
|
||||||
|
// Make sure tick marks reflect new bounds
|
||||||
|
updateTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
getTelemetryObjects: function () {
|
||||||
|
return telemetryObjects;
|
||||||
|
},
|
||||||
|
getDomainTicks: function () {
|
||||||
|
return domainTicks;
|
||||||
|
},
|
||||||
|
getRangeTicks: function () {
|
||||||
|
return rangeTicks;
|
||||||
|
},
|
||||||
|
getDrawingObject: function () {
|
||||||
|
return draw;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the coordinates (as displayable text) for the
|
||||||
|
* current mouse position.
|
||||||
|
* @returns {string[]} the displayable domain and range
|
||||||
|
* coordinates over which the mouse is hovered
|
||||||
|
*/
|
||||||
|
getHoverCoordinates: function () {
|
||||||
|
return mousePosition ?
|
||||||
|
mousePositionToDomainRange(
|
||||||
|
mousePosition
|
||||||
|
).map(formatValue) : [];
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Handle mouse movement over the chart area.
|
||||||
|
* @param $event the mouse event
|
||||||
|
*/
|
||||||
|
hover: function ($event) {
|
||||||
|
mousePosition = toMousePosition($event);
|
||||||
|
if (marqueeStart) {
|
||||||
|
updateMarqueeBox();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Initiate a marquee zoom action.
|
||||||
|
* @param $event the mouse event
|
||||||
|
*/
|
||||||
|
startMarquee: function ($event) {
|
||||||
|
mousePosition = marqueeStart = toMousePosition($event);
|
||||||
|
updateMarqueeBox();
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Complete a marquee zoom action.
|
||||||
|
* @param $event the mouse event
|
||||||
|
*/
|
||||||
|
endMarquee: function ($event) {
|
||||||
|
mousePosition = toMousePosition($event);
|
||||||
|
if (marqueeStart) {
|
||||||
|
marqueeZoom(marqueeStart, mousePosition);
|
||||||
|
marqueeStart = undefined;
|
||||||
|
updateMarqueeBox();
|
||||||
|
updateDrawingBounds();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* Update the drawing bounds, marquee box, and
|
||||||
|
* tick marks for this subplot.
|
||||||
|
*/
|
||||||
|
update: function () {
|
||||||
|
updateDrawingBounds();
|
||||||
|
updateMarqueeBox();
|
||||||
|
updateTicks();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return SubPlot;
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
@ -8,21 +8,30 @@ define(
|
|||||||
var STACKED = {
|
var STACKED = {
|
||||||
key: "stacked",
|
key: "stacked",
|
||||||
name: "Stacked",
|
name: "Stacked",
|
||||||
glyph: "8"
|
glyph: "8",
|
||||||
|
factory: PlotOverlayMode
|
||||||
},
|
},
|
||||||
OVERLAID = {
|
OVERLAID = {
|
||||||
key: "overlaid",
|
key: "overlaid",
|
||||||
name: "Overlaid",
|
name: "Overlaid",
|
||||||
glyph: "6"
|
glyph: "6",
|
||||||
|
factory: PlotStackedMode
|
||||||
};
|
};
|
||||||
|
|
||||||
function PlotModeOptions(telemetryObjects) {
|
function PlotModeOptions(telemetryObjects) {
|
||||||
var options = telemetryObjects.length > 1 ?
|
var options = telemetryObjects.length > 1 ?
|
||||||
[ OVERLAID, STACKED ] : [ OVERLAID ],
|
[ OVERLAID, STACKED ] : [ OVERLAID ],
|
||||||
mode = options[0];
|
mode = options[0],
|
||||||
|
modeHandler;
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
getModeHandler: function () {
|
||||||
|
if (!modeHandler) {
|
||||||
|
modeHandler = mode.factory(telemetryObjects);
|
||||||
|
}
|
||||||
|
return modeHandler;
|
||||||
|
},
|
||||||
getModeOptions: function () {
|
getModeOptions: function () {
|
||||||
return options;
|
return options;
|
||||||
},
|
},
|
||||||
@ -30,7 +39,10 @@ define(
|
|||||||
return mode;
|
return mode;
|
||||||
},
|
},
|
||||||
setMode: function (option) {
|
setMode: function (option) {
|
||||||
mode = option;
|
if (mode !== option) {
|
||||||
|
mode = option;
|
||||||
|
modeHandler = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
60
platform/features/plot/src/modes/PlotOverlayMode.js
Normal file
60
platform/features/plot/src/modes/PlotOverlayMode.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*global define*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
["../SubPlot", "../elements/PlotPalette", "../elements/PlotPanZoomStack"],
|
||||||
|
function (SubPlot, PlotPalette, PlotPanZoomStack) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
function PlotOverlayMode(telemetryObjects) {
|
||||||
|
var domainOffset,
|
||||||
|
panZoomStack = new PlotPanZoomStack([], []),
|
||||||
|
subplot = new SubPlot(telemetryObjects, panZoomStack),
|
||||||
|
subplots = [ subplot ];
|
||||||
|
|
||||||
|
function plotTelemetry(prepared) {
|
||||||
|
// Fit to the boundaries of the data, but don't
|
||||||
|
// override any user-initiated pan-zoom changes.
|
||||||
|
panZoomStack.setBasePanZoom(
|
||||||
|
prepared.getOrigin(),
|
||||||
|
prepared.getDimensions()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Track the domain offset, used to bias domain values
|
||||||
|
// to minimize loss of precision when converted to 32-bit
|
||||||
|
// floating point values for display.
|
||||||
|
domainOffset = prepared.getDomainOffset();
|
||||||
|
|
||||||
|
// Draw the buffers. Select color by index.
|
||||||
|
subplot.getDrawingObject().lines = prepared.getBuffers().map(function (buf, i) {
|
||||||
|
return {
|
||||||
|
buffer: buf,
|
||||||
|
color: PlotPalette.getFloatColor(i),
|
||||||
|
points: buf.length / 2
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
subplot.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
plotTelemetry: plotTelemetry,
|
||||||
|
getSubPlots: function () {
|
||||||
|
return subplots;
|
||||||
|
},
|
||||||
|
isZoomed: function () {
|
||||||
|
return panZoomStack.getDepth() > 1;
|
||||||
|
},
|
||||||
|
stepBackPanZoom: function () {
|
||||||
|
panZoomStack.pop();
|
||||||
|
subplot.update();
|
||||||
|
},
|
||||||
|
unzoom: function () {
|
||||||
|
panZoomStack.clearPanZoom();
|
||||||
|
subplot.update();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return PlotOverlayMode;
|
||||||
|
}
|
||||||
|
);
|
Loading…
x
Reference in New Issue
Block a user