-
+
{{ xAxisLabel }}
@@ -65,7 +65,8 @@ export default {
xKeyOptions: [],
xAxis: {},
loaded: false,
- xAxisLabel: ''
+ xAxisLabel: '',
+ isUtc: this.openmct.time.getTimeSystem().isUTCBased
};
},
mounted() {
@@ -119,6 +120,7 @@ export default {
this.xAxis.resetSeries();
this.setUpXAxisOptions();
}
+ this.isUtc = timeSystem.isUTCBased;
},
setUpXAxisOptions() {
const xAxisKey = this.xAxis.get('key');
diff --git a/src/plugins/plot/chart/MCTChartSeriesElement.js b/src/plugins/plot/chart/MCTChartSeriesElement.js
index 7a318433ecb..002c8b48095 100644
--- a/src/plugins/plot/chart/MCTChartSeriesElement.js
+++ b/src/plugins/plot/chart/MCTChartSeriesElement.js
@@ -97,6 +97,7 @@ export default class MCTChartSeriesElement {
this.chart.setOffset(point, undefined, series);
}
+ // Here x,y are the offsets of the current point from the first data point.
return {
x: this.offset.xVal(point, series),
y: this.offset.yVal(point, series)
@@ -130,6 +131,7 @@ export default class MCTChartSeriesElement {
reset() {
this.buffer = new Float32Array(20000);
this.count = 0;
+ //TODO: Should we call resetYOffsetAndSeriesDataForYAxis here?
if (this.offset.x) {
this.series.getSeriesData().forEach(function (point, index) {
this.append(point, index, this.series);
diff --git a/src/plugins/plot/draw/DrawWebGL.js b/src/plugins/plot/draw/DrawWebGL.js
index 17784198f46..45161d69ff0 100644
--- a/src/plugins/plot/draw/DrawWebGL.js
+++ b/src/plugins/plot/draw/DrawWebGL.js
@@ -26,6 +26,7 @@ import eventHelpers from '../lib/eventHelpers.js';
import { MARKER_SHAPES } from './MarkerShapes.js';
// WebGL shader sources (for drawing plain colors)
+// discard; stops the pixel from being drawn
const FRAGMENT_SHADER = `
precision mediump float;
uniform vec4 uColor;
@@ -64,6 +65,12 @@ const FRAGMENT_SHADER = `
}
`;
+/* This code is taking a 2D vertex position (aVertexPosition) and transforming it into a clip-space coordinate system (where x and y range from -1 to 1)
+ 1. (aVertexPosition - uOrigin): effectively translates the aVertexPosition so that the uOrigin becomes the new (0,0). It shifts the coordinate system.
+ 2. (aVertexPosition - uOrigin) / uDimensions: performs a normalization step. If uDimensions represents the full width and height, this scales the coordinates so that they fall within the range [0, 1] for both x and y, relative to the uOrigin and uDimensions bounding box
+ 3. 2.0 * ((aVertexPosition - uOrigin) / uDimensions): scales the coordinates to be in the range [0, 2]
+ 4. 2.0 * ((aVertexPosition - uOrigin) / uDimensions) - vec2(1,1): shifts the range from [0, 2] to [-1, 1]
+*/
const VERTEX_SHADER = `
attribute vec2 aVertexPosition;
uniform vec2 uDimensions;
@@ -132,20 +139,27 @@ class DrawWebGL extends EventEmitter {
// Get locations for attribs/uniforms from the
// shader programs (to pass values into shaders at draw-time)
+
+ // only available to the vertex shader - this returns an INDEX into the list of attributes maintained by the GPU
this.aVertexPosition = this.gl.getAttribLocation(this.program, 'aVertexPosition');
+
+ // available to both vertex and fragment shaders
this.uColor = this.gl.getUniformLocation(this.program, 'uColor');
this.uMarkerShape = this.gl.getUniformLocation(this.program, 'uMarkerShape');
this.uDimensions = this.gl.getUniformLocation(this.program, 'uDimensions');
this.uOrigin = this.gl.getUniformLocation(this.program, 'uOrigin');
this.uPointSize = this.gl.getUniformLocation(this.program, 'uPointSize');
+ // enable the attribute to that it can be used / accessed
this.gl.enableVertexAttribArray(this.aVertexPosition);
- // Create a buffer to holds points which will be drawn
+ // Create a buffer to hold points which will be drawn
this.buffer = this.gl.createBuffer();
// Enable blending, for smoothness
this.gl.enable(this.gl.BLEND);
+ // sfactor is the source alpha value, dfactor is one minus source alpha value
+ // conceptually, color(RGBA) = (sourceColor * sfactor) + (destinationColor * dfactor)
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
}
destroy() {
diff --git a/src/plugins/plot/pluginSpec.js b/src/plugins/plot/pluginSpec.js
index a7e33ce2d68..23b1980cba7 100644
--- a/src/plugins/plot/pluginSpec.js
+++ b/src/plugins/plot/pluginSpec.js
@@ -422,7 +422,7 @@ describe('the plugin', function () {
expect(xAxisElement.length).toBe(1);
let ticks = xAxisElement[0].querySelectorAll('.gl-plot-tick');
- expect(ticks.length).toBe(9);
+ expect(ticks.length).toBe(5);
done();
});
diff --git a/src/plugins/plot/stackedPlot/pluginSpec.js b/src/plugins/plot/stackedPlot/pluginSpec.js
index e8455880013..77a92c548d5 100644
--- a/src/plugins/plot/stackedPlot/pluginSpec.js
+++ b/src/plugins/plot/stackedPlot/pluginSpec.js
@@ -400,7 +400,7 @@ describe('the plugin', function () {
);
expect(yAxisElement.length).toBe(1);
let ticks = yAxisElement[0].querySelectorAll('.gl-plot-tick');
- expect(ticks.length).toBe(6);
+ expect(ticks.length).toBe(11);
});
it('Renders Y-axis options for the telemetry object', () => {
diff --git a/src/plugins/plot/tickUtils.js b/src/plugins/plot/tickUtils.js
index fff48cb546b..8282d982bd1 100644
--- a/src/plugins/plot/tickUtils.js
+++ b/src/plugins/plot/tickUtils.js
@@ -4,6 +4,18 @@ const e10 = Math.sqrt(50);
const e5 = Math.sqrt(10);
const e2 = Math.sqrt(2);
+// A complete list of time units and their duration in milliseconds - UTC
+const TIME_UNITS_UTC = [
+ { unit: 'millisecond', duration: 1 },
+ { unit: 'second', duration: 1000 },
+ { unit: 'minute', duration: 1000 * 60 },
+ { unit: 'hour', duration: 1000 * 60 * 60 },
+ { unit: 'day', duration: 1000 * 60 * 60 * 24 },
+ { unit: 'week', duration: 1000 * 60 * 60 * 24 * 7 },
+ { unit: 'month', duration: 1000 * 60 * 60 * 24 * 30.4375 }, // Average month
+ { unit: 'year', duration: 1000 * 60 * 60 * 24 * 365.25 } // Average year
+];
+
/**
* Nicely formatted tick steps from d3-array.
*/
@@ -22,6 +34,91 @@ function tickStep(start, stop, count) {
return stop < start ? -step1 : step1;
}
+/**
+ * Generate time ticks based on a start and stop time, and a desired count of ticks.
+ * @param start beginning timestamp in Ms
+ * @param stop ending timestamp in Ms
+ * @param count desired number of ticks
+ * @returns {*[]} Array of timestamps in Ms
+ */
+export function getTimeTicks(start, stop, count) {
+ const duration = stop - start;
+ let bestUnit = TIME_UNITS_UTC[0];
+ let bestStepSize = 1;
+
+ // Find the most appropriate time unit
+ for (const unit of TIME_UNITS_UTC) {
+ const numTicks = duration / unit.duration;
+ if (numTicks >= count / 2) {
+ // Find the unit that gives at least half the desired ticks
+ bestUnit = unit;
+ bestStepSize = Math.ceil(numTicks / count) || 1;
+ } else {
+ break; // Stop when the unit is too large
+ }
+ }
+
+ // Handle month/year to avoid incorrect step sizes due to varying durations
+ if (bestUnit.unit === 'month' || bestUnit.unit === 'year') {
+ return generateMonthYearTicks(start, stop, bestUnit.unit, bestStepSize);
+ } else {
+ // For smaller, fixed-duration units
+ return generateFixedIntervalTicks(start, stop, bestUnit.duration * bestStepSize);
+ }
+}
+
+// Helper for variable-duration units (months, years)
+/**
+ * Generate ticks for month/year intervals - these are variable due to leap years etc.
+ * @param start beginning timestamp in Ms
+ * @param stop ending timestamp in Ms
+ * @param unit 'month' or 'year'
+ * @param stepSize number of months/years to step
+ * @returns {*[]} Array of timestamps in Ms
+ */
+function generateMonthYearTicks(start, stop, unit, stepSize) {
+ const resultingTicks = [];
+ let currentDate = new Date(start);
+
+ // Set to the beginning of the interval (e.g., beginning of the month/year)
+ if (unit === 'month') {
+ currentDate.setDate(1);
+ } else if (unit === 'year') {
+ currentDate.setMonth(0, 1);
+ }
+
+ while (currentDate.getTime() <= stop) {
+ resultingTicks.push(currentDate.getTime());
+ if (unit === 'month') {
+ currentDate.setMonth(currentDate.getMonth() + stepSize);
+ } else {
+ // unit is 'year'
+ currentDate.setFullYear(currentDate.getFullYear() + stepSize);
+ }
+ }
+
+ return resultingTicks;
+}
+
+// Helper for fixed-duration units (seconds, days)
+/**
+ * Generate ticks for fixed-duration intervals (seconds, minutes, hours, etc.)
+ * @param start beginning timestamp in Ms
+ * @param stop ending timestamp in Ms
+ * @param interval duration of each tick in Ms
+ * @returns {*[]} Array of timestamps in Ms
+ */
+function generateFixedIntervalTicks(start, stop, interval) {
+ const fixedIntervalTicks = [];
+ const firstTick = Math.ceil(start / interval) * interval;
+
+ for (let i = firstTick; i <= stop; i += interval) {
+ fixedIntervalTicks.push(i);
+ }
+
+ return fixedIntervalTicks;
+}
+
/**
* Find the precision (number of decimals) of a step. Used to round
* ticks to precise values.