[Plot] Separate out plot axis

Separate plot axis (as prepared for the plot's
Angular template) into its own script. WTD-533
This commit is contained in:
Victor Woeltjen 2014-12-01 16:35:38 -08:00
parent bb708e9a05
commit e1298db760
6 changed files with 89 additions and 72 deletions

View File

@ -24,9 +24,9 @@
{{axes[1].active.name}}
</div>
<div ng-repeat="tick in axes[1].ticks"
<div ng-repeat="tick in rangeTicks"
class="gl-plot-tick gl-plot-y-tick-label"
ng-style="{ bottom: (100 * $index / (axes[1].ticks.length - 1)) + '%' }">
ng-style="{ bottom: (100 * $index / (rangeTicks.length - 1)) + '%' }">
{{tick.label}}
</div>
@ -48,14 +48,14 @@
<div class="gl-plot-hash hash-v"
ng-repeat="tick in axes[0].ticks"
ng-style="{ left: (100 * $index / (axes[0].ticks.length - 1)) + '%', height: '100%' }"
ng-show="$index > 0 && $index < (axes[0].ticks.length - 1)">
ng-repeat="tick in domainTicks"
ng-style="{ left: (100 * $index / (domainTicks.length - 1)) + '%', height: '100%' }"
ng-show="$index > 0 && $index < (domainTicks.length - 1)">
</div>
<div class="gl-plot-hash hash-h"
ng-repeat="tick in axes[1].ticks"
ng-style="{ bottom: (100 * $index / (axes[1].ticks.length - 1)) + '%', width: '100%' }"
ng-show="$index > 0 && $index < (axes[1].ticks.length - 1)">
ng-repeat="tick in rangeTicks"
ng-style="{ bottom: (100 * $index / (rangeTicks.length - 1)) + '%', width: '100%' }"
ng-show="$index > 0 && $index < (rangeTicks.length - 1)">
</div>
<mct-chart draw="draw"
@ -92,10 +92,10 @@
<div class="gl-plot-axis-area gl-plot-x">
<div ng-repeat="tick in axes[0].ticks"
<div ng-repeat="tick in domainTicks"
class="gl-plot-tick gl-plot-x-tick-label"
ng-show="$index > 0 && $index < (axes[0].ticks.length - 1)"
ng-style="{ left: (100 * $index / (axes[0].ticks.length - 1)) + '%' }">
ng-show="$index > 0 && $index < (domainTicks.length - 1)"
ng-style="{ left: (100 * $index / (domainTicks.length - 1)) + '%' }">
{{tick.label}}
</div>

View 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;
}
);

View File

@ -10,9 +10,10 @@ define(
"./PlotPanZoomStack",
"./PlotPosition",
"./PlotTickGenerator",
"./PlotFormatter"
"./PlotFormatter",
"./PlotAxis"
],
function (PlotPreparer, PlotPalette, PlotPanZoomStack, PlotPosition, PlotTickGenerator, PlotFormatter) {
function (PlotPreparer, PlotPalette, PlotPanZoomStack, PlotPosition, PlotTickGenerator, PlotFormatter, PlotAxis) {
"use strict";
var AXIS_DEFAULTS = [
@ -41,22 +42,25 @@ define(
formatter.formatDomainValue)(v);
}
function mousePositionToDomainRange(mousePosition, domainOffset) {
function mousePositionToDomainRange(mousePosition) {
return new PlotPosition(
mousePosition.x,
mousePosition.y,
mousePosition.width,
mousePosition.height,
panZoomStack,
domainOffset
panZoomStack
).getPosition();
}
function toDisplayable(position) {
return [ position[0] - domainOffset, position[1] ];
}
function updateMarqueeBox() {
$scope.draw.boxes = marqueeStart ?
[{
start: mousePositionToDomainRange(marqueeStart),
end: mousePositionToDomainRange(mousePosition),
start: toDisplayable(mousePositionToDomainRange(marqueeStart)),
end: toDisplayable(mousePositionToDomainRange(mousePosition)),
color: [1, 1, 1, 0.5 ]
}] : undefined;
}
@ -65,11 +69,23 @@ define(
var panZoom = panZoomStack.getPanZoom();
$scope.draw.dimensions = panZoom.dimensions;
$scope.draw.origin = panZoom.origin;
$scope.draw.origin = [
panZoom.origin[0] - domainOffset,
panZoom.origin[1]
];
}
function updateTicks() {
var tickGenerator = new PlotTickGenerator(panZoomStack, formatter);
$scope.domainTicks =
tickGenerator.generateDomainTicks(DOMAIN_TICKS);
$scope.rangeTicks =
tickGenerator.generateRangeTicks(RANGE_TICKS);
}
function plotTelemetry() {
var telemetry, prepared, tickGenerator, data;
var telemetry, prepared, data;
telemetry = $scope.telemetry;
@ -85,13 +101,6 @@ define(
($scope.axes[1].active || {}).key
);
tickGenerator = new PlotTickGenerator(prepared, formatter);
$scope.axes[0].ticks =
tickGenerator.generateDomainTicks(DOMAIN_TICKS);
$scope.axes[1].ticks =
tickGenerator.generateRangeTicks(RANGE_TICKS);
panZoomStack.setBasePanZoom(
prepared.getOrigin(),
prepared.getDimensions()
@ -109,41 +118,14 @@ define(
updateDrawingBounds();
updateMarqueeBox();
updateTicks();
}
function setupAxes(metadatas) {
var domainKeys = {},
rangeKeys = {},
domains = [],
ranges = [];
function buildOptionsForMetadata(m) {
(m.domains || []).forEach(function (domain) {
if (!domainKeys[domain.key]) {
domainKeys[domain.key] = true;
domains.push(domain);
}
});
(m.ranges || []).forEach(function (range) {
if (!rangeKeys[range.key]) {
rangeKeys[range.key] = true;
ranges.push(range);
}
});
}
(metadatas || []).
forEach(buildOptionsForMetadata);
[domains, ranges].forEach(function (options, i) {
var active = $scope.axes[i].active;
$scope.axes[i].options = options;
if (!active || !active.key) {
$scope.axes[i].active =
options[0] || AXIS_DEFAULTS[i];
}
});
$scope.axes = [
new PlotAxis("domain", metadatas, AXIS_DEFAULTS[0]),
new PlotAxis("range", metadatas, AXIS_DEFAULTS[1])
];
}
function toMousePosition($event) {
@ -171,9 +153,9 @@ define(
];
panZoomStack.pushPanZoom(origin, dimensions);
updateTicks();
}
$scope.axes = [ {}, {} ];
$scope.$watch("telemetry.getMetadata()", setupAxes);
$scope.$on("telemetryUpdate", plotTelemetry);
$scope.draw = {};
@ -185,8 +167,7 @@ define(
getHoverCoordinates: function () {
return mousePosition ?
mousePositionToDomainRange(
mousePosition,
domainOffset
mousePosition
).map(formatValue) : [];
},
hover: function ($event) {

View File

@ -5,9 +5,8 @@ define(
function () {
"use strict";
function PlotPosition(x, y, width, height, panZoomStack, domainOffset) {
function PlotPosition(x, y, width, height, panZoomStack) {
var panZoom = panZoomStack.getPanZoom(),
offset = [ domainOffset || 0, 0 ],
origin = panZoom.origin,
dimensions = panZoom.dimensions,
position;
@ -16,7 +15,7 @@ define(
position = [];
} else {
position = [ x / width, (height - y) / height ].map(function (v, i) {
return v * dimensions[i] + origin[i] + offset[i];
return v * dimensions[i] + origin[i];
});
}

View File

@ -36,9 +36,9 @@ define(
vertices.push([]);
for (index = 0; index < data.getPointCount(); index = index + 1) {
x = data.getDomainValue(index, domain) - domainOffset;
x = data.getDomainValue(index, domain);
y = data.getRangeValue(index, range);
vertices[i].push(x);
vertices[i].push(x - domainOffset);
vertices[i].push(y);
min[0] = Math.min(min[0], x);
min[1] = Math.min(min[1], y);

View File

@ -5,7 +5,7 @@ define(
function () {
"use strict";
function PlotTickGenerator(preparer, formatter) {
function PlotTickGenerator(panZoomStack, formatter) {
function generateTicks(start, span, count, format) {
var step = span / (count - 1),
@ -24,17 +24,19 @@ define(
return {
generateDomainTicks: function (count) {
var panZoom = panZoomStack.getPanZoom();
return generateTicks(
preparer.getOrigin()[0] + preparer.getDomainOffset(),
preparer.getDimensions()[0],
panZoom.origin[0],
panZoom.dimensions[0],
count,
formatter.formatDomainValue
);
},
generateRangeTicks: function (count) {
var panZoom = panZoomStack.getPanZoom();
return generateTicks(
preparer.getOrigin()[1],
preparer.getDimensions()[1],
panZoom.origin[1],
panZoom.dimensions[1],
count,
formatter.formatRangeValue
);