[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:
Victor Woeltjen
2014-12-01 18:21:51 -08:00
parent ad802e674e
commit 86711735b7
8 changed files with 17 additions and 9 deletions

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

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

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

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

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

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

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