diff --git a/andrewbmchugh-flow-panel-1.0.0.zip b/andrewbmchugh-flow-panel-1.0.0.zip new file mode 100644 index 0000000..dcf0dbc Binary files /dev/null and b/andrewbmchugh-flow-panel-1.0.0.zip differ diff --git a/provisioning/dashboards/dashboard.json b/provisioning/dashboards/dashboard.json deleted file mode 100644 index 2bb5721..0000000 --- a/provisioning/dashboards/dashboard.json +++ /dev/null @@ -1,227 +0,0 @@ -{ - "annotations": { - "list": [ - { - "builtIn": 1, - "datasource": { - "type": "grafana", - "uid": "-- Grafana --" - }, - "enable": true, - "hide": true, - "iconColor": "rgba(0, 211, 255, 1)", - "name": "Annotations & Alerts", - "type": "dashboard" - } - ] - }, - "editable": true, - "fiscalYearStartMonth": 0, - "graphTooltip": 0, - "id": 5, - "links": [], - "liveNow": false, - "panels": [ - { - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 0 - }, - "id": 123125, - "options": { - "panelConfig": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/panelConfigGrafanaVariables.yaml", - "siteConfig": "", - "svg": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/darkThemeSvg1.svg", - "testDataEnabled": true, - "timeSliderEnabled": true, - "troubleshootingCtr": { - "dataCtr": 0, - "mappingsCtr": 0 - } - }, - "title": "Example 1 - ${site} - ${environment}", - "type": "andrewbmchugh-flow-panel" - }, - { - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "gridPos": { - "h": 13, - "w": 24, - "x": 0, - "y": 8 - }, - "id": 123126, - "options": { - "panelConfig": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/panelConfig2.yaml", - "siteConfig": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/siteConfig.yaml", - "svg": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/darkThemeSvg2.svg", - "testDataEnabled": true, - "timeSliderEnabled": true, - "troubleshootingCtr": { - "dataCtr": 0, - "mappingsCtr": 0 - } - }, - "title": "Example 2", - "type": "andrewbmchugh-flow-panel" - }, - { - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "description": "This example shows panels displaying the Random Walk Time Series.\n\nTime Series A is shown on 'Inbox Depth' and 'Active Workers'\n\nTime Series B is shown on 'start rate' and 'Transactions'.", - "gridPos": { - "h": 8, - "w": 24, - "x": 0, - "y": 21 - }, - "id": 123127, - "options": { - "panelConfig": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/panelConfigRandomWalk.yaml", - "siteConfig": "", - "svg": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/darkThemeSvg1.svg", - "testDataEnabled": true, - "timeSliderEnabled": true, - "troubleshootingCtr": { - "dataCtr": 2, - "mappingsCtr": 0 - } - }, - "targets": [ - { - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "queryType": "randomWalk", - "refId": "A" - }, - { - "datasource": { - "type": "datasource", - "uid": "grafana" - }, - "hide": false, - "queryType": "randomWalk", - "refId": "B" - } - ], - "title": "Example 3 - Random Walk", - "type": "andrewbmchugh-flow-panel" - } - ], - "refresh": "", - "schemaVersion": 38, - "style": "dark", - "tags": [], - "templating": { - "list": [ - { - "current": { - "selected": true, - "text": "prod", - "value": "prod" - }, - "hide": 0, - "includeAll": false, - "multi": false, - "name": "environment", - "options": [ - { - "selected": false, - "text": "dev", - "value": "dev" - }, - { - "selected": false, - "text": "beta", - "value": "beta" - }, - { - "selected": true, - "text": "prod", - "value": "prod" - } - ], - "query": "dev,beta,prod", - "queryValue": "", - "skipUrlSync": false, - "type": "custom" - }, - { - "current": { - "selected": true, - "text": "Cicely", - "value": "Cicely" - }, - "hide": 0, - "includeAll": false, - "multi": false, - "name": "site", - "options": [ - { - "selected": true, - "text": "Cicely", - "value": "Cicely" - }, - { - "selected": false, - "text": "Twin Peaks", - "value": "Twin Peaks" - } - ], - "query": "Cicely, Twin Peaks", - "queryValue": "", - "skipUrlSync": false, - "type": "custom" - } - ] - }, - "time": { - "from": "now-6h", - "to": "now" - }, - "timepicker": { - "hidden": true, - "refresh_intervals": [ - "5s", - "10s", - "30s", - "1m", - "5m", - "15m", - "30m", - "1h", - "2h", - "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ], - "type": "timepicker" - }, - "timezone": "browser", - "title": "Flow Panel Example", - "uid": "e986cc62-d29a-46f4-9e60-b0e4cd07ff98", - "version": 8, - "weekStart": "" -} \ No newline at end of file diff --git a/provisioning/dashboards/dashboard1_FlowPanel.json b/provisioning/dashboards/dashboard1_FlowPanel.json new file mode 100644 index 0000000..8b8ec7c --- /dev/null +++ b/provisioning/dashboards/dashboard1_FlowPanel.json @@ -0,0 +1,143 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 10, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "gridPos": { + "h": 12, + "w": 9, + "x": 0, + "y": 0 + }, + "id": 123127, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# The Flow Panel\n\nThis dashboard along with the two companion dashboards demonstrate the core functionality of the Flow panel:\n|Features|Features|Features|Features|\n|--------|--------|--------|--------|\n|label content|panel config|units|time-slider|\n|label color|site config|tooltips|url links|\n|fill color|variable config overrides|auto-scaling|hue gradient|\n\n\nThe first panel is what you get out-the-box when you create a FLow panel. A basic SVG driven\nfrom test data via sample config. It shows everything working and is the starting point\nfor someone to go exploring. How they should explore is explained in the\n[Docs](https://github.com/andymchugh/andrewbmchugh-flow-panel-docs/blob/main/README.md) which are\nreachable from the SVG widget as well as the 'Docs' button in the Troubleshooting section of\nthe editor.\n\nThe second panel shows a more typical usage to give a sense of the range of widget support\nyou get from using a product like draw.io. It's more aspirational, helping them reason\nabout how to apply it to their own architecture and see the benefits of a shared siteConfig\nin terms of data maintenance.\n", + "mode": "markdown" + }, + "pluginVersion": "10.0.3", + "type": "text" + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "gridPos": { + "h": 12, + "w": 15, + "x": 9, + "y": 0 + }, + "id": 123125, + "options": { + "panelConfig": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/panelConfig1.yaml", + "siteConfig": "", + "svg": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/darkThemeSvg1.svg", + "testDataEnabled": true, + "timeSliderEnabled": true, + "troubleshootingCtr": { + "dataCtr": 0, + "mappingsCtr": 0 + } + }, + "type": "andrewbmchugh-flow-panel" + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "gridPos": { + "h": 13, + "w": 24, + "x": 0, + "y": 12 + }, + "id": 123126, + "options": { + "panelConfig": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/panelConfig2.yaml", + "siteConfig": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/siteConfig.yaml", + "svg": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/darkThemeSvg2.svg", + "testDataEnabled": true, + "timeSliderEnabled": true, + "troubleshootingCtr": { + "dataCtr": 0, + "mappingsCtr": 0 + } + }, + "title": "Example Middleware Bus", + "type": "andrewbmchugh-flow-panel" + } + ], + "refresh": "", + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-3h", + "to": "now" + }, + "timepicker": { + "hidden": false, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ], + "type": "timepicker" + }, + "timezone": "browser", + "title": "The Flow Panel", + "version": 2, + "weekStart": "" +} \ No newline at end of file diff --git a/provisioning/dashboards/dashboard2_GrafanaVariables.json b/provisioning/dashboards/dashboard2_GrafanaVariables.json new file mode 100644 index 0000000..22e5524 --- /dev/null +++ b/provisioning/dashboards/dashboard2_GrafanaVariables.json @@ -0,0 +1,184 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 8, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 123128, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Variable Scalars\n\nThis dashboard demonstrates how threshold levels can be scaled based off of grafana variables. Note that\nthis needs the variables to be relevant to the time series queries, which isn't possible with test data.\nTo work around that we put the variables in the panel title. That gives us the refresh cycle we need\nto re-render the SVG. Normally we'd get this for free virtue of updated time-series based off of the new\nvariable values.\n\nAll the widgets are being driven from the same time series but the 'Inbox Depth' in configured to have\nadjusted thresholds given certain variable values. The thresholds in the config are set as follows:\n\n- Green = under 400\n- Amber = 400 to 800\n- Red = 800 and over\n\nBut with environment set to 'prod' those levels will half on the 'Inbox Depth'. With the site\nset to 'Cicely', the thresholds will again half. With both 'prod' and 'Cicely' the scaling accumulates\nso the thresholds are a quarter of the other widgets.\n\nMove the time-sider up and down exploring the transitions with the variable values in the \ndifferent configurations.\n", + "mode": "markdown" + }, + "pluginVersion": "10.0.3", + "title": "Variable Scalars for ${site} ${environment}", + "type": "text" + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "gridPos": { + "h": 13, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 123125, + "options": { + "panelConfig": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/panelConfigGrafanaVariables.yaml", + "siteConfig": "", + "svg": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/darkThemeSvg1.svg", + "testDataEnabled": true, + "timeSliderEnabled": true, + "troubleshootingCtr": { + "dataCtr": 0, + "mappingsCtr": 0 + } + }, + "title": "Example 1 - ${site} - ${environment}", + "type": "andrewbmchugh-flow-panel" + } + ], + "refresh": "", + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "prod", + "value": "prod" + }, + "hide": 0, + "includeAll": false, + "multi": false, + "name": "environment", + "options": [ + { + "selected": false, + "text": "dev", + "value": "dev" + }, + { + "selected": false, + "text": "beta", + "value": "beta" + }, + { + "selected": true, + "text": "prod", + "value": "prod" + } + ], + "query": "dev,beta,prod", + "queryValue": "", + "skipUrlSync": false, + "type": "custom" + }, + { + "current": { + "selected": false, + "text": "New York", + "value": "New York" + }, + "hide": 0, + "includeAll": false, + "multi": false, + "name": "site", + "options": [ + { + "selected": false, + "text": "London", + "value": "London" + }, + { + "selected": true, + "text": "New York", + "value": "New York" + }, + { + "selected": false, + "text": "Cicely", + "value": "Cicely" + } + ], + "query": "London, New York, Cicely", + "queryValue": "", + "skipUrlSync": false, + "type": "custom" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "hidden": true, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ], + "type": "timepicker" + }, + "timezone": "browser", + "title": "Grafana Variables", + "version": 9, + "weekStart": "" + } \ No newline at end of file diff --git a/provisioning/dashboards/dashboard3_RandomWalk.json b/provisioning/dashboards/dashboard3_RandomWalk.json new file mode 100644 index 0000000..df0c64e --- /dev/null +++ b/provisioning/dashboards/dashboard3_RandomWalk.json @@ -0,0 +1,213 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": 6, + "links": [], + "liveNow": false, + "panels": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 123130, + "options": { + "code": { + "language": "plaintext", + "showLineNumbers": false, + "showMiniMap": false + }, + "content": "# Random Walk Data Feed\n\nThis dashboard shows our default SVG hooked into Grafanas Random Walk time series.\n\nThere's no way to seed this data to get a predictable range so it's not that useful for demonstrating the\nfeature set of colors and thresholds. But is useful for showing how the panel accepts normal Grafana time series.\n\nThe first panel hooks the A series into the two depth widgets and the B series into the two rate widgets.\n\nThe second panel only has one of the two time series present so you see a functional panel but with half\nthe widgets not being driven.\n\nThe third panel shows the behaviour where there's no relevant data. The panel renders correctly but there's\nnothing to drive.\n\nIn all three panels, move the time-slider back and forth to see the widgets respond. Click on the time-picker 'refresh'\nand see the time-slider time readout update and the new time-series values be rendered.\n\n", + "mode": "markdown" + }, + "pluginVersion": "10.0.3", + "type": "text" + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "description": "This example shows panels displaying the Random Walk Time Series.\n\nTime Series A is shown on 'Inbox Depth' and 'Active Workers'\n\nTime Series B is shown on 'start rate' and 'Transactions'.", + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 123127, + "options": { + "panelConfig": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/panelConfigRandomWalk.yaml", + "siteConfig": "", + "svg": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/darkThemeSvg1.svg", + "testDataEnabled": true, + "timeSliderEnabled": true, + "troubleshootingCtr": { + "dataCtr": 2, + "mappingsCtr": 0 + } + }, + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "queryType": "randomWalk", + "refId": "A" + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "hide": false, + "queryType": "randomWalk", + "refId": "B" + } + ], + "title": "Random Walk - A & B Time Series in place", + "type": "andrewbmchugh-flow-panel" + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "description": "This example shows panels displaying the Random Walk Time Series.\n\nTime Series A is shown on 'Inbox Depth' and 'Active Workers'\n\nTime Series B is shown on 'start rate' and 'Transactions'.", + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 16 + }, + "id": 123129, + "options": { + "panelConfig": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/panelConfigRandomWalk.yaml", + "siteConfig": "", + "svg": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/darkThemeSvg1.svg", + "testDataEnabled": false, + "timeSliderEnabled": true, + "troubleshootingCtr": { + "dataCtr": 2, + "mappingsCtr": 0 + } + }, + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "hide": false, + "queryType": "randomWalk", + "refId": "B" + } + ], + "title": "Random Walk - Time Series A missing", + "type": "andrewbmchugh-flow-panel" + }, + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "description": "This example shows panels displaying the Random Walk Time Series.\n\nTime Series A is shown on 'Inbox Depth' and 'Active Workers'\n\nTime Series B is shown on 'start rate' and 'Transactions'.", + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 24 + }, + "id": 123128, + "options": { + "panelConfig": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/panelConfigRandomWalk.yaml", + "siteConfig": "", + "svg": "https://raw.githubusercontent.com/andymchugh/andrewbmchugh-flow-panel-docs/main/examples/darkThemeSvg1.svg", + "testDataEnabled": false, + "timeSliderEnabled": true, + "troubleshootingCtr": { + "dataCtr": 2, + "mappingsCtr": 0 + } + }, + "targets": [ + { + "datasource": { + "type": "datasource", + "uid": "grafana" + }, + "queryType": "randomWalk", + "refId": "C" + } + ], + "title": "Random Walk - Time Series A & B missing", + "type": "andrewbmchugh-flow-panel" + } + ], + "refresh": "", + "schemaVersion": 38, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "hidden": false, + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ], + "type": "timepicker" + }, + "timezone": "browser", + "title": "Random Walk", + "version": 8, + "weekStart": "" + } \ No newline at end of file diff --git a/src/components/Config.tsx b/src/components/Config.tsx index 75f107a..e232c65 100644 --- a/src/components/Config.tsx +++ b/src/components/Config.tsx @@ -1,4 +1,4 @@ -export type ColorMode = 'step' | 'gradient'; +export type ColorGradientMode = 'none' | 'hue'; export type LabelSeparator = 'cr' | 'colon' | 'space' | 'replace'; export type LinkUrlParams = 'none' | 'time' | 'all'; @@ -25,7 +25,7 @@ export type PanelConfigCellLabel = { } export type PanelConfigCellColor = { - mode: ColorMode | undefined; + gradientMode: ColorGradientMode | undefined; thresholdsRef: string | undefined; thresholds: Threshold[] | undefined; } @@ -48,7 +48,7 @@ export type SiteConfig = { export type PanelConfig = { variableThresholdScalars: Map; - colorMode: ColorMode; + gradientMode: ColorGradientMode; cellIdPreamble: string; cellIdExtender: string; cells: Map; @@ -58,7 +58,7 @@ export function panelConfigFactory(config: any) { config = config || {}; return { variableThresholdScalars: new Map(Object.entries(config.variableThresholdScalars || {})), - colorMode: config.colorMode || 'step', + gradientMode: config.gradientMode || 'none', cellIdPreamble: config.cellIdPreamble || '', cellIdExtender: config.cellIdExtender || '@flowrpt', cells: new Map(Object.entries(config.cells || {})), @@ -86,7 +86,7 @@ function siteConfigDereference(siteConfig: SiteConfig) { function panelConfigDereference(siteConfig: SiteConfig, panelConfig: PanelConfig) { function colorDeref(color: PanelConfigCellColor | undefined) { if (color) { - color.mode = color.mode || panelConfig.colorMode; + color.gradientMode = color.gradientMode || panelConfig.gradientMode; if (color.thresholds) { color.thresholds.forEach(function(threshold) { threshold.color = siteConfig.colors.get(threshold.color) || threshold.color; diff --git a/src/components/TimeSeries.tsx b/src/components/TimeSeries.tsx index 619c29b..9be5fe8 100644 --- a/src/components/TimeSeries.tsx +++ b/src/components/TimeSeries.tsx @@ -88,14 +88,13 @@ export function seriesTransform(series: any, timeMin: number, timeMax: number): }; } -// This transforms the data so we have name-indexable sets of time and value. -// i.e.: -// - series: [fields: [{name, values}]] => -// - {name: {time: {timeIndex, values}, values}} +// This receives the timeSlider position and uses it to interpolate the time-series +// data. export function seriesInterpolate(tsData: TimeSeriesData, timeSliderScalar: number) { const targetTime = sliderTime(tsData, timeSliderScalar); tsData.ts.forEach((ts) => { + // ts.time can be shared across series so we only have to interpolate it once. if (!ts.time.valuesIndex) { let closestDeltaTime = null; let closestIndex = null; diff --git a/src/components/Utils.tsx b/src/components/Utils.tsx index 3c08ddc..a2cbc47 100644 --- a/src/components/Utils.tsx +++ b/src/components/Utils.tsx @@ -202,13 +202,13 @@ export function getColor(cellColorData: PanelConfigCellColor, value: number) { threshold = thresholds[i]; if (value < threshold.level) { const thresholdLwr = thresholds[i - 1]; - if (cellColorData.mode === 'gradient') { + if (cellColorData.gradientMode === 'hue') { const scalar = (value - thresholdLwr.level) / (threshold.level - thresholdLwr.level); const color = colorGradient(thresholdLwr.color, threshold.color, scalar); return color; } else { - // The only other mode is 'step' + // The only other mode is 'none' return colorLookup(thresholdLwr.color); } } diff --git a/src/test/TimeSeries.test.tsx b/src/test/TimeSeries.test.tsx new file mode 100644 index 0000000..d24a306 --- /dev/null +++ b/src/test/TimeSeries.test.tsx @@ -0,0 +1,36 @@ +import { seriesInterpolate, TimeSeries, TimeSeriesData } from 'components/TimeSeries' + +test('interpolate1', () => { + const tsd: TimeSeriesData = { + timeMin: 1000, + timeMax: 3000, + timeRange: 2000, + ts: new Map(), + }; + + const timeVals = [1000, 1010, 1020, 1030, 1540, 1942, 2006, 2572, 2798, 3000]; + + const timeSeries1: TimeSeries = { + time: {values: timeVals}, + values: Array(1000).fill(0), + }; + + tsd.ts.set('data1', timeSeries1); + + // When we interpolate we lock in a timeValues index, so we need to clear this + // between interpolations, as happens naturally when we receive new data. The + // expected index is going to be the index of the closest time value to the + // slider position where the slider is a linear (0-1) position on the time range. + const check = (timeSliderVal: number, expectedTimeIndex: number) => { + seriesInterpolate(tsd, timeSliderVal); + expect(timeSeries1.time.valuesIndex).toEqual(expectedTimeIndex); + timeSeries1.time.valuesIndex = null; + } + check(-0.1, 0); + check(0, 0); + check(1, 9); + check(1.1, 9); + check(0.5, 6); + check(0.1, 3); +}); +