@vuu-ui/vuu-chart 2.1.0-alpha.1 → 2.1.0-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cjs/Chart.js CHANGED
@@ -11,13 +11,14 @@ var Chart$1 = require('./Chart.css.js');
11
11
 
12
12
  const Chart = ({
13
13
  categoryColumnName,
14
- chartSettings = { useCoarsePointer: true },
14
+ chartSettings = { useCoarsePointer: true, renderer: "svg" },
15
15
  // enables clicking near a line and still highlighting it
16
16
  dataSource,
17
+ itemColorFunction,
17
18
  optionSettings = { notMerge: true },
18
19
  // don't merge two options together when updating option
20
+ palette,
19
21
  style = { width: "100%", height: "100%" },
20
- events = {},
21
22
  seriesColumnNames,
22
23
  ...htmlAttributes
23
24
  }) => {
@@ -30,17 +31,19 @@ const Chart = ({
30
31
  const chartRef = react.useRef(null);
31
32
  const option = useChartOptions.useChartOptions({
32
33
  categoryColumnName,
34
+ itemColorFunction,
35
+ palette,
33
36
  dataSource,
34
37
  seriesColumnNames
35
38
  });
36
- const onContextMenu = useChartContextMenu.useChartContextMenu({ categoryColumnName, dataSource });
39
+ const onContextMenu = useChartContextMenu.useChartContextMenu({ categoryColumnName });
37
40
  react.useEffect(() => {
38
41
  const chart = echarts.init(chartRef.current, null, chartSettings);
39
42
  chart.on("contextmenu", onContextMenu);
40
43
  return () => {
41
44
  chart?.dispose();
42
45
  };
43
- }, [chartSettings, events, onContextMenu]);
46
+ }, [chartSettings, onContextMenu]);
44
47
  react.useEffect(() => {
45
48
  if (chartRef.current) {
46
49
  const chart = echarts.getInstanceByDom(chartRef.current);
package/cjs/Chart.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Chart.js","sources":["../../../packages/vuu-chart/src/Chart.tsx"],"sourcesContent":["import { useRef, useEffect, HTMLAttributes } from \"react\";\nimport { init, getInstanceByDom } from \"echarts\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { ChartOptionsProps, useChartOptions } from \"./useChartOptions\";\nimport { useChartContextMenu } from \"./useChartContextMenu\";\n\nimport echartCss from \"./Chart.css\";\n\ntype OptionSettings = {\n notMerge: boolean;\n};\n\ntype ChartSettings = {\n useCoarsePointer: boolean;\n};\n\nexport interface ChartProps\n extends ChartOptionsProps,\n HTMLAttributes<HTMLDivElement> {\n chartSettings?: ChartSettings;\n events?: unknown;\n optionSettings?: OptionSettings;\n}\n\nexport const Chart = ({\n categoryColumnName,\n chartSettings = { useCoarsePointer: true }, // enables clicking near a line and still highlighting it\n dataSource,\n optionSettings = { notMerge: true }, // don't merge two options together when updating option\n style = { width: \"100%\", height: \"100%\" },\n events = {},\n seriesColumnNames,\n ...htmlAttributes\n}: ChartProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-toast-notification\",\n css: echartCss,\n window: targetWindow,\n });\n\n const chartRef = useRef<HTMLDivElement>(null);\n\n const option = useChartOptions({\n categoryColumnName,\n dataSource,\n seriesColumnNames,\n });\n\n const onContextMenu = useChartContextMenu({ categoryColumnName, dataSource });\n\n // Debounce resize event so it only fires periodically instead of constantly\n // const resizeChart = useMemo(\n // () =>\n // debounce(() => {\n // if (chartRef.current) {\n // const chart = getInstanceByDom(chartRef.current);\n // chart.resize();\n // }\n // }, 100),\n // [],\n // );\n\n useEffect(() => {\n // Initialize chart\n const chart = init(chartRef.current, null, chartSettings);\n\n chart.on(\"contextmenu\", onContextMenu);\n\n // Set up event listeners\n // for (const [key, handler] of Object.entries(events)) {\n // console.log(`register ${key} handler`);\n // chart.on(key, (param) => {\n // handler(param);\n // });\n // }\n\n // Resize event listener\n // const resizeObserver = new ResizeObserver(() => {\n // resizeChart();\n // });\n\n // resizeObserver.observe(chartRef.current);\n\n // Return cleanup function\n return () => {\n chart?.dispose();\n\n // if (chartRef.current) {\n // resizeObserver.unobserve(chartRef.current);\n // }\n // resizeObserver.disconnect();\n };\n }, [chartSettings, events, onContextMenu]);\n\n useEffect(() => {\n if (chartRef.current) {\n // Re-render chart when option changes\n const chart = getInstanceByDom(chartRef.current);\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n chart?.setOption(option, optionSettings);\n }\n }, [option, optionSettings]);\n\n return <div {...htmlAttributes} ref={chartRef} style={style} />;\n};\n"],"names":["useWindow","useComponentCssInjection","echartCss","useRef","useChartOptions","useChartContextMenu","useEffect","init","getInstanceByDom"],"mappings":";;;;;;;;;;;AAyBO,MAAM,QAAQ,CAAC;AAAA,EACpB,kBAAA;AAAA,EACA,aAAA,GAAgB,EAAE,gBAAA,EAAkB,IAAK,EAAA;AAAA;AAAA,EACzC,UAAA;AAAA,EACA,cAAA,GAAiB,EAAE,QAAA,EAAU,IAAK,EAAA;AAAA;AAAA,EAClC,KAAQ,GAAA,EAAE,KAAO,EAAA,MAAA,EAAQ,QAAQ,MAAO,EAAA;AAAA,EACxC,SAAS,EAAC;AAAA,EACV,iBAAA;AAAA,EACA,GAAG;AACL,CAAkB,KAAA;AAChB,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,wBAAA;AAAA,IACR,GAAK,EAAAC,OAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA,QAAA,GAAWC,aAAuB,IAAI,CAAA;AAE5C,EAAA,MAAM,SAASC,+BAAgB,CAAA;AAAA,IAC7B,kBAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,aAAgB,GAAAC,uCAAA,CAAoB,EAAE,kBAAA,EAAoB,YAAY,CAAA;AAc5E,EAAAC,eAAA,CAAU,MAAM;AAEd,IAAA,MAAM,KAAQ,GAAAC,YAAA,CAAK,QAAS,CAAA,OAAA,EAAS,MAAM,aAAa,CAAA;AAExD,IAAM,KAAA,CAAA,EAAA,CAAG,eAAe,aAAa,CAAA;AAkBrC,IAAA,OAAO,MAAM;AACX,MAAA,KAAA,EAAO,OAAQ,EAAA;AAAA,KAMjB;AAAA,GACC,EAAA,CAAC,aAAe,EAAA,MAAA,EAAQ,aAAa,CAAC,CAAA;AAEzC,EAAAD,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAS,OAAS,EAAA;AAEpB,MAAM,MAAA,KAAA,GAAQE,wBAAiB,CAAA,QAAA,CAAS,OAAO,CAAA;AAG/C,MAAO,KAAA,EAAA,SAAA,CAAU,QAAQ,cAAc,CAAA;AAAA;AACzC,GACC,EAAA,CAAC,MAAQ,EAAA,cAAc,CAAC,CAAA;AAE3B,EAAA,sCAAQ,KAAK,EAAA,EAAA,GAAG,cAAgB,EAAA,GAAA,EAAK,UAAU,KAAc,EAAA,CAAA;AAC/D;;;;"}
1
+ {"version":3,"file":"Chart.js","sources":["../../../packages/vuu-chart/src/Chart.tsx"],"sourcesContent":["import { useRef, useEffect, HTMLAttributes } from \"react\";\nimport { init, getInstanceByDom } from \"echarts\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { ChartOptionsProps, useChartOptions } from \"./useChartOptions\";\nimport { useChartContextMenu } from \"./useChartContextMenu\";\n\nimport echartCss from \"./Chart.css\";\nimport { ItemColorFunction } from \"./ChartSeries\";\n\ntype OptionSettings = {\n notMerge: boolean;\n};\n\ntype ChartSettings = {\n renderer: \"svg\" | \"canvas\";\n useCoarsePointer: boolean;\n};\n\nexport interface ChartProps\n extends ChartOptionsProps,\n HTMLAttributes<HTMLDivElement> {\n chartSettings?: ChartSettings;\n itemColorFunction?: ItemColorFunction;\n optionSettings?: OptionSettings;\n palette?: string[];\n}\n\nexport const Chart = ({\n categoryColumnName,\n chartSettings = { useCoarsePointer: true, renderer: \"svg\" }, // enables clicking near a line and still highlighting it\n dataSource,\n itemColorFunction,\n optionSettings = { notMerge: true }, // don't merge two options together when updating option\n palette,\n style = { width: \"100%\", height: \"100%\" },\n seriesColumnNames,\n ...htmlAttributes\n}: ChartProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-toast-notification\",\n css: echartCss,\n window: targetWindow,\n });\n\n const chartRef = useRef<HTMLDivElement>(null);\n\n const option = useChartOptions({\n categoryColumnName,\n itemColorFunction,\n palette,\n dataSource,\n seriesColumnNames,\n });\n\n const onContextMenu = useChartContextMenu({ categoryColumnName });\n\n // Debounce resize event so it only fires periodically instead of constantly\n // const resizeChart = useMemo(\n // () =>\n // debounce(() => {\n // if (chartRef.current) {\n // const chart = getInstanceByDom(chartRef.current);\n // chart.resize();\n // }\n // }, 100),\n // [],\n // );\n\n useEffect(() => {\n // Initialize chart\n const chart = init(chartRef.current, null, chartSettings);\n\n chart.on(\"contextmenu\", onContextMenu);\n\n // Resize event listener\n // const resizeObserver = new ResizeObserver(() => {\n // resizeChart();\n // });\n\n // resizeObserver.observe(chartRef.current);\n\n // Return cleanup function\n return () => {\n chart?.dispose();\n\n // if (chartRef.current) {\n // resizeObserver.unobserve(chartRef.current);\n // }\n // resizeObserver.disconnect();\n };\n }, [chartSettings, onContextMenu]);\n\n useEffect(() => {\n if (chartRef.current) {\n // Re-render chart when option changes\n const chart = getInstanceByDom(chartRef.current);\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n chart?.setOption(option, optionSettings);\n }\n }, [option, optionSettings]);\n\n return <div {...htmlAttributes} ref={chartRef} style={style} />;\n};\n"],"names":["useWindow","useComponentCssInjection","echartCss","useRef","useChartOptions","useChartContextMenu","useEffect","init","getInstanceByDom"],"mappings":";;;;;;;;;;;AA4BO,MAAM,QAAQ,CAAC;AAAA,EACpB,kBAAA;AAAA,EACA,aAAgB,GAAA,EAAE,gBAAkB,EAAA,IAAA,EAAM,UAAU,KAAM,EAAA;AAAA;AAAA,EAC1D,UAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA,GAAiB,EAAE,QAAA,EAAU,IAAK,EAAA;AAAA;AAAA,EAClC,OAAA;AAAA,EACA,KAAQ,GAAA,EAAE,KAAO,EAAA,MAAA,EAAQ,QAAQ,MAAO,EAAA;AAAA,EACxC,iBAAA;AAAA,EACA,GAAG;AACL,CAAkB,KAAA;AAChB,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,wBAAA;AAAA,IACR,GAAK,EAAAC,OAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA,QAAA,GAAWC,aAAuB,IAAI,CAAA;AAE5C,EAAA,MAAM,SAASC,+BAAgB,CAAA;AAAA,IAC7B,kBAAA;AAAA,IACA,iBAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,aAAgB,GAAAC,uCAAA,CAAoB,EAAE,kBAAA,EAAoB,CAAA;AAchE,EAAAC,eAAA,CAAU,MAAM;AAEd,IAAA,MAAM,KAAQ,GAAAC,YAAA,CAAK,QAAS,CAAA,OAAA,EAAS,MAAM,aAAa,CAAA;AAExD,IAAM,KAAA,CAAA,EAAA,CAAG,eAAe,aAAa,CAAA;AAUrC,IAAA,OAAO,MAAM;AACX,MAAA,KAAA,EAAO,OAAQ,EAAA;AAAA,KAMjB;AAAA,GACC,EAAA,CAAC,aAAe,EAAA,aAAa,CAAC,CAAA;AAEjC,EAAAD,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAS,OAAS,EAAA;AAEpB,MAAM,MAAA,KAAA,GAAQE,wBAAiB,CAAA,QAAA,CAAS,OAAO,CAAA;AAG/C,MAAO,KAAA,EAAA,SAAA,CAAU,QAAQ,cAAc,CAAA;AAAA;AACzC,GACC,EAAA,CAAC,MAAQ,EAAA,cAAc,CAAC,CAAA;AAE3B,EAAA,sCAAQ,KAAK,EAAA,EAAA,GAAG,cAAgB,EAAA,GAAA,EAAK,UAAU,KAAc,EAAA,CAAA;AAC/D;;;;"}
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var vuuUtils = require('@vuu-ui/vuu-utils');
4
+ var DataRowMovingWindow = require('./DataRowMovingWindow.js');
4
5
 
5
6
  var __defProp = Object.defineProperty;
6
7
  var __typeError = (msg) => {
@@ -12,8 +13,13 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
12
13
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
13
14
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
14
15
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
15
- var _categoryColumn, _columnMap, _dataSource, _categoryCount, _dates, _series, _seriesColumns;
16
- function getCategoriesAndSeries(columnMap, data, categoryColumn, seriesColumns) {
16
+ var _categoryColumn, _columnMap, _itemColorFunction, _dataWindow, _dates, _series, _seriesColumns;
17
+ const defaultItemColorFunction = ({ color }) => color;
18
+ const { KEY } = vuuUtils.metadataKeys;
19
+ function DataSourceValue(key, row, value) {
20
+ return { key, row, value };
21
+ }
22
+ function getCategoriesAndSeries(columnMap, data, categoryColumn, seriesColumns, itemColorFunction = defaultItemColorFunction) {
17
23
  const categoryValues = [];
18
24
  const seriesMap = /* @__PURE__ */ new Map();
19
25
  data.forEach((row) => {
@@ -23,54 +29,88 @@ function getCategoriesAndSeries(columnMap, data, categoryColumn, seriesColumns)
23
29
  let series = seriesMap.get(seriesColumn);
24
30
  if (!series) {
25
31
  series = {
26
- id: "test-1",
32
+ //any reason we can't simply use col name here ?
33
+ id: seriesColumn,
27
34
  name: seriesColumn,
28
35
  label: seriesColumn,
29
36
  data: [],
30
- type: "line"
37
+ type: "line",
38
+ itemStyle: {
39
+ color: itemColorFunction
40
+ },
41
+ lineStyle: {
42
+ width: 1.5
43
+ },
44
+ symbol: "circle"
31
45
  };
32
46
  seriesMap.set(seriesColumn, series);
33
47
  }
34
- series.data.push(row[columnMap[seriesColumn]]);
48
+ const key = row[KEY];
49
+ const value = row[columnMap[seriesColumn]];
50
+ series.data.push(DataSourceValue(key, row, value));
35
51
  }
36
52
  });
37
53
  return [categoryValues, Array.from(seriesMap.values())];
38
54
  }
39
55
  class ChartSeries extends vuuUtils.EventEmitter {
40
- constructor({ category, dataSource, series }) {
56
+ constructor({ dataSource, itemColorFunction }) {
41
57
  super();
42
- __privateAdd(this, _categoryColumn);
58
+ __privateAdd(this, _categoryColumn, "");
43
59
  __privateAdd(this, _columnMap, {});
44
- __privateAdd(this, _dataSource);
45
- __privateAdd(this, _categoryCount, 0);
60
+ __privateAdd(this, _itemColorFunction);
61
+ __privateAdd(this, _dataWindow, new DataRowMovingWindow.MovingDataRowWindow(vuuUtils.Range(0, 1e3)));
46
62
  __privateAdd(this, _dates, []);
47
63
  __privateAdd(this, _series, []);
48
- __privateAdd(this, _seriesColumns);
64
+ __privateAdd(this, _seriesColumns, []);
49
65
  __publicField(this, "handleData", (message) => {
50
66
  if (message.type === "subscribed") {
51
67
  __privateSet(this, _columnMap, vuuUtils.buildColumnMap(message.tableSchema.columns));
52
68
  } else if (message.type === "viewport-update") {
53
- if (message.mode === "size-only") {
54
- __privateSet(this, _categoryCount, message.size ?? 0);
55
- } else if (message.rows) {
56
- const [dates, series] = getCategoriesAndSeries(
57
- __privateGet(this, _columnMap),
58
- message.rows,
59
- __privateGet(this, _categoryColumn),
60
- __privateGet(this, _seriesColumns)
61
- );
62
- __privateSet(this, _dates, dates);
63
- __privateSet(this, _series, series);
69
+ if (message.mode === "size-only") ; else if (message.rows) {
70
+ for (const row of message.rows) {
71
+ __privateGet(this, _dataWindow).add(row);
72
+ }
73
+ this.buildCategoriesAndSeries();
64
74
  }
65
75
  } else {
66
76
  console.warn(JSON.stringify(message));
67
77
  }
68
78
  });
69
- __privateSet(this, _categoryColumn, category);
70
- __privateSet(this, _dataSource, dataSource);
71
- __privateSet(this, _seriesColumns, series);
79
+ __privateSet(this, _itemColorFunction, itemColorFunction);
72
80
  dataSource.subscribe({ range: vuuUtils.Range(0, 1e3) }, this.handleData);
73
81
  }
82
+ buildCategoriesAndSeries() {
83
+ if (__privateGet(this, _categoryColumn) && __privateGet(this, _seriesColumns).length > 0) {
84
+ const [dates, series] = getCategoriesAndSeries(
85
+ __privateGet(this, _columnMap),
86
+ __privateGet(this, _dataWindow).data,
87
+ __privateGet(this, _categoryColumn),
88
+ __privateGet(this, _seriesColumns),
89
+ __privateGet(this, _itemColorFunction)
90
+ );
91
+ __privateSet(this, _dates, dates);
92
+ __privateSet(this, _series, series);
93
+ this.emit("update");
94
+ }
95
+ }
96
+ get categoryColumn() {
97
+ return __privateGet(this, _categoryColumn);
98
+ }
99
+ set categoryColumn(categoryColumn) {
100
+ __privateSet(this, _categoryColumn, categoryColumn);
101
+ if (__privateGet(this, _seriesColumns).length > 0) {
102
+ this.buildCategoriesAndSeries();
103
+ }
104
+ }
105
+ get seriesColumnNames() {
106
+ return __privateGet(this, _seriesColumns);
107
+ }
108
+ set seriesColumnNames(seriesColumnNames) {
109
+ __privateSet(this, _seriesColumns, seriesColumnNames);
110
+ if (__privateGet(this, _categoryColumn)) {
111
+ this.buildCategoriesAndSeries();
112
+ }
113
+ }
74
114
  get categories() {
75
115
  return __privateGet(this, _dates);
76
116
  }
@@ -80,8 +120,8 @@ class ChartSeries extends vuuUtils.EventEmitter {
80
120
  }
81
121
  _categoryColumn = new WeakMap();
82
122
  _columnMap = new WeakMap();
83
- _dataSource = new WeakMap();
84
- _categoryCount = new WeakMap();
123
+ _itemColorFunction = new WeakMap();
124
+ _dataWindow = new WeakMap();
85
125
  _dates = new WeakMap();
86
126
  _series = new WeakMap();
87
127
  _seriesColumns = new WeakMap();
@@ -1 +1 @@
1
- {"version":3,"file":"ChartSeries.js","sources":["../../../packages/vuu-chart/src/ChartSeries.ts"],"sourcesContent":["import {\n DataSource,\n DataSourceRow,\n DataSourceSubscribeCallback,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n buildColumnMap,\n ColumnMap,\n EventEmitter,\n Range,\n} from \"@vuu-ui/vuu-utils\";\n\ntype Series = {\n id: string;\n name: string;\n label: string;\n data: number[];\n type: \"line\";\n};\n\nfunction getCategoriesAndSeries(\n columnMap: ColumnMap,\n data: DataSourceRow[],\n categoryColumn: string,\n seriesColumns: string[],\n): [string[], Series[]] {\n const categoryValues: string[] = [];\n const seriesMap = new Map<string, Series>();\n\n data.forEach((row) => {\n const categoryValue = row[columnMap[categoryColumn]] as string;\n categoryValues.push(categoryValue);\n\n for (const seriesColumn of seriesColumns) {\n let series = seriesMap.get(seriesColumn);\n if (!series) {\n series = {\n id: \"test-1\",\n name: seriesColumn,\n label: seriesColumn,\n data: [],\n type: \"line\",\n };\n seriesMap.set(seriesColumn, series);\n }\n series.data.push(row[columnMap[seriesColumn]] as number);\n }\n });\n\n return [categoryValues, Array.from(seriesMap.values())];\n}\n\nexport type ChartEvents = {\n update: () => void;\n};\nexport interface ChartSeriesConstructorProps {\n dataSource: DataSource;\n /**\n * The column name of the column that defines our category axis.\n * By default, these are the x axis values.\n */\n category: string;\n /**\n * The column names of the columns that define our data.\n * By default, these are the y axis values.\n */\n series: string[];\n}\n\nexport class ChartSeries extends EventEmitter<ChartEvents> {\n #categoryColumn: string;\n #columnMap: ColumnMap = {};\n #dataSource: DataSource;\n #categoryCount = 0;\n\n #dates: string[] = [];\n #series: Series[] = [];\n #seriesColumns: string[];\n\n handleData: DataSourceSubscribeCallback = (message) => {\n if (message.type === \"subscribed\") {\n this.#columnMap = buildColumnMap(message.tableSchema.columns);\n } else if (message.type === \"viewport-update\") {\n if (message.mode === \"size-only\") {\n this.#categoryCount = message.size ?? 0;\n } else if (message.rows) {\n const [dates, series] = getCategoriesAndSeries(\n this.#columnMap,\n message.rows,\n this.#categoryColumn,\n this.#seriesColumns,\n );\n this.#dates = dates;\n this.#series = series;\n }\n } else {\n console.warn(JSON.stringify(message));\n }\n };\n\n constructor({ category, dataSource, series }: ChartSeriesConstructorProps) {\n super();\n this.#categoryColumn = category;\n this.#dataSource = dataSource;\n this.#seriesColumns = series;\n\n dataSource.subscribe({ range: Range(0, 1000) }, this.handleData);\n }\n\n get categories() {\n return this.#dates;\n }\n\n get series() {\n return this.#series;\n }\n}\n"],"names":["EventEmitter","buildColumnMap","Range"],"mappings":"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"}
1
+ {"version":3,"file":"ChartSeries.js","sources":["../../../packages/vuu-chart/src/ChartSeries.ts"],"sourcesContent":["import {\n DataSource,\n DataSourceRow,\n DataSourceSubscribeCallback,\n} from \"@vuu-ui/vuu-data-types\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n buildColumnMap,\n ColumnMap,\n EventEmitter,\n Range,\n metadataKeys,\n} from \"@vuu-ui/vuu-utils\";\nimport { MovingDataRowWindow } from \"./DataRowMovingWindow\";\n\ntype Series = {\n id: string;\n name: string;\n label: string;\n data: DataSourceValue<number>[];\n lineStyle: {\n width: number;\n };\n itemStyle: {\n color: string | ItemColorFunction;\n };\n symbol: \"emptyCircle\" | \"circle\";\n type: \"line\";\n};\n\nexport type ItemColorFunction = (params: {\n color: string;\n data: DataSourceValue;\n dataIndex: number;\n name: string;\n seriesName: string;\n}) => string;\n\nconst defaultItemColorFunction: ItemColorFunction = ({ color }) => color;\n\nconst { KEY } = metadataKeys;\n\nexport type DataSourceValue<T extends VuuRowDataItemType = number> = {\n key: string;\n readonly row: DataSourceRow;\n value: T;\n};\n\nfunction DataSourceValue<T extends VuuRowDataItemType = number>(\n key: string,\n row: DataSourceRow,\n value: T,\n): DataSourceValue<T> {\n return { key, row, value };\n}\n\nfunction getCategoriesAndSeries(\n columnMap: ColumnMap,\n data: DataSourceRow[],\n categoryColumn: string,\n seriesColumns: string[],\n itemColorFunction = defaultItemColorFunction,\n): [string[], Series[]] {\n const categoryValues: string[] = [];\n const seriesMap = new Map<string, Series>();\n\n data.forEach((row) => {\n const categoryValue = row[columnMap[categoryColumn]] as string;\n categoryValues.push(categoryValue);\n\n for (const seriesColumn of seriesColumns) {\n let series = seriesMap.get(seriesColumn);\n if (!series) {\n series = {\n //any reason we can't simply use col name here ?\n id: seriesColumn,\n name: seriesColumn,\n label: seriesColumn,\n data: [],\n type: \"line\",\n itemStyle: {\n color: itemColorFunction,\n },\n lineStyle: {\n width: 1.5,\n },\n symbol: \"circle\",\n };\n seriesMap.set(seriesColumn, series);\n }\n\n const key = row[KEY] as string;\n const value = row[columnMap[seriesColumn]] as number;\n series.data.push(DataSourceValue(key, row, value));\n }\n });\n\n return [categoryValues, Array.from(seriesMap.values())];\n}\n\nexport type ChartEvents = {\n update: () => void;\n};\nexport interface ChartSeriesConstructorProps {\n dataSource: DataSource;\n itemColorFunction?: ItemColorFunction;\n}\n\nexport class ChartSeries extends EventEmitter<ChartEvents> {\n #categoryColumn = \"\";\n #columnMap: ColumnMap = {};\n #itemColorFunction: ItemColorFunction | undefined;\n #dataWindow = new MovingDataRowWindow(Range(0, 1000));\n\n #dates: string[] = [];\n #series: Series[] = [];\n #seriesColumns: string[] = [];\n\n handleData: DataSourceSubscribeCallback = (message) => {\n if (message.type === \"subscribed\") {\n this.#columnMap = buildColumnMap(message.tableSchema.columns);\n } else if (message.type === \"viewport-update\") {\n if (message.mode === \"size-only\") {\n // ???\n } else if (message.rows) {\n for (const row of message.rows) {\n this.#dataWindow.add(row);\n }\n this.buildCategoriesAndSeries();\n }\n } else {\n console.warn(JSON.stringify(message));\n }\n };\n\n buildCategoriesAndSeries() {\n if (this.#categoryColumn && this.#seriesColumns.length > 0) {\n const [dates, series] = getCategoriesAndSeries(\n this.#columnMap,\n this.#dataWindow.data,\n this.#categoryColumn,\n this.#seriesColumns,\n this.#itemColorFunction,\n );\n this.#dates = dates;\n this.#series = series;\n\n this.emit(\"update\");\n }\n }\n\n constructor({ dataSource, itemColorFunction }: ChartSeriesConstructorProps) {\n super();\n this.#itemColorFunction = itemColorFunction;\n dataSource.subscribe({ range: Range(0, 1000) }, this.handleData);\n }\n\n get categoryColumn() {\n return this.#categoryColumn;\n }\n\n set categoryColumn(categoryColumn: string) {\n this.#categoryColumn = categoryColumn;\n if (this.#seriesColumns.length > 0) {\n this.buildCategoriesAndSeries();\n }\n }\n\n get seriesColumnNames() {\n return this.#seriesColumns;\n }\n\n set seriesColumnNames(seriesColumnNames: string[]) {\n this.#seriesColumns = seriesColumnNames;\n if (this.#categoryColumn) {\n this.buildCategoriesAndSeries();\n }\n }\n\n get categories() {\n return this.#dates;\n }\n\n get series() {\n return this.#series;\n }\n}\n"],"names":["metadataKeys","EventEmitter","MovingDataRowWindow","Range","buildColumnMap"],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ 'use strict';
2
+
3
+ var vuuUtils = require('@vuu-ui/vuu-utils');
4
+
5
+ var __defProp = Object.defineProperty;
6
+ var __typeError = (msg) => {
7
+ throw TypeError(msg);
8
+ };
9
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
11
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
12
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
13
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
14
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
15
+ var _range;
16
+ const { IDX, KEY } = vuuUtils.metadataKeys;
17
+ class MovingDataRowWindow {
18
+ constructor({ from, to }) {
19
+ __publicField(this, "data");
20
+ __publicField(this, "rowCount", 0);
21
+ __privateAdd(this, _range);
22
+ __publicField(this, "setRowCount", (rowCount) => {
23
+ if (rowCount < this.data.length) {
24
+ this.data.length = rowCount;
25
+ }
26
+ this.rowCount = rowCount;
27
+ });
28
+ __privateSet(this, _range, new vuuUtils.WindowRange(from, to));
29
+ this.data = new Array(Math.max(0, to - from));
30
+ this.rowCount = 0;
31
+ }
32
+ add(data) {
33
+ const index = data[IDX];
34
+ if (this.isWithinRange(index)) {
35
+ const internalIndex = index - __privateGet(this, _range).from;
36
+ this.data[internalIndex] = data;
37
+ }
38
+ }
39
+ getAtIndex(index) {
40
+ return __privateGet(this, _range).isWithin(index) && this.data[index - __privateGet(this, _range).from] != null ? this.data[index - __privateGet(this, _range).from] : void 0;
41
+ }
42
+ getByKey(key) {
43
+ return this.data.find((row) => row[KEY] === key);
44
+ }
45
+ isWithinRange(index) {
46
+ return __privateGet(this, _range).isWithin(index);
47
+ }
48
+ setRange({ from, to }) {
49
+ if (from !== __privateGet(this, _range).from || to !== __privateGet(this, _range).to) {
50
+ const [overlapFrom, overlapTo] = __privateGet(this, _range).overlap(from, to);
51
+ const newData = new Array(Math.max(0, to - from));
52
+ for (let i = overlapFrom; i < overlapTo; i++) {
53
+ const data = this.getAtIndex(i);
54
+ if (data) {
55
+ const index = i - from;
56
+ newData[index] = data;
57
+ }
58
+ }
59
+ this.data = newData;
60
+ __privateGet(this, _range).from = from;
61
+ __privateGet(this, _range).to = to;
62
+ }
63
+ }
64
+ get hasData() {
65
+ return this.data.some((d) => d !== void 0);
66
+ }
67
+ /**
68
+ * This will throw if there is no data. Check `hasData` first
69
+ * to guard against this, if not certain.
70
+ */
71
+ get firstRow() {
72
+ for (let i = 0; i < this.data.length; i++) {
73
+ if (this.data[i]) {
74
+ return this.data[i];
75
+ }
76
+ }
77
+ throw Error(`[DataRowMovingWinddow] firstRow, no data`);
78
+ }
79
+ get range() {
80
+ return __privateGet(this, _range);
81
+ }
82
+ // TODO make this more performant, see implementation in
83
+ // array-backed-moving-window - use same implementation
84
+ get hasAllRowsWithinRange() {
85
+ const { from, to } = __privateGet(this, _range);
86
+ for (let i = from; i < to; i++) {
87
+ if (this.getAtIndex(i) === void 0) {
88
+ return false;
89
+ }
90
+ }
91
+ return true;
92
+ }
93
+ }
94
+ _range = new WeakMap();
95
+
96
+ exports.MovingDataRowWindow = MovingDataRowWindow;
97
+ //# sourceMappingURL=DataRowMovingWindow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataRowMovingWindow.js","sources":["../../../packages/vuu-chart/src/DataRowMovingWindow.ts"],"sourcesContent":["import { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { WindowRange } from \"@vuu-ui/vuu-utils\";\nimport { metadataKeys } from \"@vuu-ui/vuu-utils\";\n\nconst { IDX, KEY } = metadataKeys;\n\nexport class MovingDataRowWindow {\n public data: DataSourceRow[];\n public rowCount = 0;\n #range: WindowRange;\n\n constructor({ from, to }: VuuRange) {\n this.#range = new WindowRange(from, to);\n //internal data is always 0 based, we add range.from to determine an offset\n this.data = new Array(Math.max(0, to - from));\n this.rowCount = 0;\n }\n\n setRowCount = (rowCount: number) => {\n if (rowCount < this.data.length) {\n this.data.length = rowCount;\n }\n\n this.rowCount = rowCount;\n };\n\n add(data: DataSourceRow) {\n const index = data[IDX];\n if (this.isWithinRange(index)) {\n const internalIndex = index - this.#range.from;\n this.data[internalIndex] = data;\n }\n }\n\n getAtIndex(index: number) {\n return this.#range.isWithin(index) &&\n this.data[index - this.#range.from] != null\n ? this.data[index - this.#range.from]\n : undefined;\n }\n\n getByKey(key: string) {\n return this.data.find((row) => row[KEY] === key);\n }\n\n isWithinRange(index: number) {\n return this.#range.isWithin(index);\n }\n\n setRange({ from, to }: VuuRange) {\n if (from !== this.#range.from || to !== this.#range.to) {\n const [overlapFrom, overlapTo] = this.#range.overlap(from, to);\n const newData = new Array(Math.max(0, to - from));\n for (let i = overlapFrom; i < overlapTo; i++) {\n const data = this.getAtIndex(i);\n if (data) {\n const index = i - from;\n newData[index] = data;\n }\n }\n this.data = newData;\n this.#range.from = from;\n this.#range.to = to;\n }\n }\n\n get hasData() {\n return this.data.some((d) => d !== undefined);\n }\n\n /**\n * This will throw if there is no data. Check `hasData` first\n * to guard against this, if not certain.\n */\n get firstRow() {\n for (let i = 0; i < this.data.length; i++) {\n if (this.data[i]) {\n return this.data[i];\n }\n }\n throw Error(`[DataRowMovingWinddow] firstRow, no data`);\n }\n\n get range() {\n return this.#range;\n }\n\n // TODO make this more performant, see implementation in\n // array-backed-moving-window - use same implementation\n get hasAllRowsWithinRange(): boolean {\n const { from, to } = this.#range;\n\n for (let i = from; i < to; i++) {\n if (this.getAtIndex(i) === undefined) {\n return false;\n }\n }\n return true;\n }\n}\n"],"names":["metadataKeys","WindowRange"],"mappings":"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"}
@@ -9,22 +9,24 @@ const useChartContextMenu = ({
9
9
  const showContextMenu = vuuContextMenu.useContextMenu();
10
10
  const onContextMenu = react.useCallback(
11
11
  ({
12
- // dataIndex,
12
+ data,
13
13
  event,
14
14
  name: categoryValue,
15
- // seriesId,
16
15
  seriesName: valueColumn,
17
- value
18
- // ...params
16
+ value: keyedValue,
17
+ ...rest
19
18
  }) => {
20
19
  event.stop();
20
+ console.log({ rest });
21
+ const { row, value } = data;
21
22
  const menuOptions = {
22
23
  categoryColumn: categoryColumnName,
23
24
  categoryValue,
25
+ row,
24
26
  valueColumn,
25
27
  value
26
28
  };
27
- showContextMenu(event.event, "chart", menuOptions, {
29
+ showContextMenu(event.event, "series", menuOptions, {
28
30
  onOpenChange: (isOpen) => {
29
31
  console.log(`[useTableContextMenu] onOpenChange ${isOpen}`);
30
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useChartContextMenu.js","sources":["../../../packages/vuu-chart/src/useChartContextMenu.ts"],"sourcesContent":["import { useContextMenu } from \"@vuu-ui/vuu-context-menu\";\nimport { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { useCallback } from \"react\";\n\ntype EChartContextMenuEvent = {\n event: PointerEvent;\n offsetX: number;\n offsetY: number;\n stop: () => void;\n type: \"contextmenu\";\n};\n\nexport type ChartContextMenuOptions = {\n categoryColumn: string;\n categoryValue: VuuRowDataItemType;\n valueColumn: string;\n value: VuuRowDataItemType;\n};\n\ntype EChartContextMenuHandlerParams = {\n dataIndex: number;\n event: EChartContextMenuEvent;\n name: string;\n seriesId: string;\n seriesName: string;\n value: number;\n};\n\ninterface ChartContextMenuHookProps {\n allowContextMenu?: boolean;\n categoryColumnName: string;\n dataSource: DataSource;\n}\n\nexport const useChartContextMenu = ({\n categoryColumnName,\n}: ChartContextMenuHookProps) => {\n const showContextMenu = useContextMenu();\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n //@ts-ignore\n const onContextMenu = useCallback<any>(\n ({\n // dataIndex,\n event,\n name: categoryValue,\n // seriesId,\n seriesName: valueColumn,\n value,\n // ...params\n }: EChartContextMenuHandlerParams) => {\n event.stop();\n // console.log(\n // `on context menu [${dataIndex}] #${seriesId} ${categoryColumnName} = ${categoryValue}, ${valueColumn} = ${value}`,\n // {\n // params,\n // },\n // );\n const menuOptions: ChartContextMenuOptions = {\n categoryColumn: categoryColumnName,\n categoryValue,\n valueColumn,\n value,\n };\n\n showContextMenu(event.event, \"chart\", menuOptions, {\n onOpenChange: (isOpen: boolean) => {\n console.log(`[useTableContextMenu] onOpenChange ${isOpen}`);\n },\n });\n },\n [categoryColumnName, showContextMenu],\n );\n\n return onContextMenu;\n};\n"],"names":["useContextMenu","useCallback"],"mappings":";;;;;AAmCO,MAAM,sBAAsB,CAAC;AAAA,EAClC;AACF,CAAiC,KAAA;AAC/B,EAAA,MAAM,kBAAkBA,6BAAe,EAAA;AAIvC,EAAA,MAAM,aAAgB,GAAAC,iBAAA;AAAA,IACpB,CAAC;AAAA;AAAA,MAEC,KAAA;AAAA,MACA,IAAM,EAAA,aAAA;AAAA;AAAA,MAEN,UAAY,EAAA,WAAA;AAAA,MACZ;AAAA;AAAA,KAEoC,KAAA;AACpC,MAAA,KAAA,CAAM,IAAK,EAAA;AAOX,MAAA,MAAM,WAAuC,GAAA;AAAA,QAC3C,cAAgB,EAAA,kBAAA;AAAA,QAChB,aAAA;AAAA,QACA,WAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAgB,eAAA,CAAA,KAAA,CAAM,KAAO,EAAA,OAAA,EAAS,WAAa,EAAA;AAAA,QACjD,YAAA,EAAc,CAAC,MAAoB,KAAA;AACjC,UAAQ,OAAA,CAAA,GAAA,CAAI,CAAsC,mCAAA,EAAA,MAAM,CAAE,CAAA,CAAA;AAAA;AAC5D,OACD,CAAA;AAAA,KACH;AAAA,IACA,CAAC,oBAAoB,eAAe;AAAA,GACtC;AAEA,EAAO,OAAA,aAAA;AACT;;;;"}
1
+ {"version":3,"file":"useChartContextMenu.js","sources":["../../../packages/vuu-chart/src/useChartContextMenu.ts"],"sourcesContent":["import { useContextMenu } from \"@vuu-ui/vuu-context-menu\";\nimport { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { useCallback } from \"react\";\nimport { DataSourceValue } from \"./ChartSeries\";\n\nexport type ChartMenuLocation = \"canvas\" | \"series\";\n\ntype EChartContextMenuEvent = {\n event: PointerEvent;\n offsetX: number;\n offsetY: number;\n stop: () => void;\n type: \"contextmenu\";\n};\n\nexport type ChartContextMenuOptions = {\n categoryColumn: string;\n categoryValue: VuuRowDataItemType;\n row: DataSourceRow;\n valueColumn: string;\n value: VuuRowDataItemType;\n};\n\ntype EChartContextMenuHandlerParams = {\n data: DataSourceValue;\n dataIndex: number;\n event: EChartContextMenuEvent;\n name: string;\n seriesId: string;\n seriesName: string;\n value: DataSourceValue;\n};\n\ninterface ChartContextMenuHookProps {\n allowContextMenu?: boolean;\n categoryColumnName: string;\n}\n\nexport const useChartContextMenu = ({\n categoryColumnName,\n}: ChartContextMenuHookProps) => {\n const showContextMenu = useContextMenu();\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n //@ts-ignore\n const onContextMenu = useCallback<any>(\n ({\n data,\n event,\n name: categoryValue,\n seriesName: valueColumn,\n value: keyedValue,\n ...rest\n }: EChartContextMenuHandlerParams) => {\n event.stop();\n console.log({ rest });\n const { row, value } = data;\n\n const menuOptions: ChartContextMenuOptions = {\n categoryColumn: categoryColumnName,\n categoryValue,\n row,\n valueColumn,\n value,\n };\n\n showContextMenu(event.event, \"series\", menuOptions, {\n onOpenChange: (isOpen: boolean) => {\n console.log(`[useTableContextMenu] onOpenChange ${isOpen}`);\n },\n });\n },\n [categoryColumnName, showContextMenu],\n );\n\n return onContextMenu;\n};\n"],"names":["useContextMenu","useCallback"],"mappings":";;;;;AAuCO,MAAM,sBAAsB,CAAC;AAAA,EAClC;AACF,CAAiC,KAAA;AAC/B,EAAA,MAAM,kBAAkBA,6BAAe,EAAA;AAIvC,EAAA,MAAM,aAAgB,GAAAC,iBAAA;AAAA,IACpB,CAAC;AAAA,MACC,IAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAM,EAAA,aAAA;AAAA,MACN,UAAY,EAAA,WAAA;AAAA,MACZ,KAAO,EAAA,UAAA;AAAA,MACP,GAAG;AAAA,KACiC,KAAA;AACpC,MAAA,KAAA,CAAM,IAAK,EAAA;AACX,MAAQ,OAAA,CAAA,GAAA,CAAI,EAAE,IAAA,EAAM,CAAA;AACpB,MAAM,MAAA,EAAE,GAAK,EAAA,KAAA,EAAU,GAAA,IAAA;AAEvB,MAAA,MAAM,WAAuC,GAAA;AAAA,QAC3C,cAAgB,EAAA,kBAAA;AAAA,QAChB,aAAA;AAAA,QACA,GAAA;AAAA,QACA,WAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAgB,eAAA,CAAA,KAAA,CAAM,KAAO,EAAA,QAAA,EAAU,WAAa,EAAA;AAAA,QAClD,YAAA,EAAc,CAAC,MAAoB,KAAA;AACjC,UAAQ,OAAA,CAAA,GAAA,CAAI,CAAsC,mCAAA,EAAA,MAAM,CAAE,CAAA,CAAA;AAAA;AAC5D,OACD,CAAA;AAAA,KACH;AAAA,IACA,CAAC,oBAAoB,eAAe;AAAA,GACtC;AAEA,EAAO,OAAA,aAAA;AACT;;;;"}
@@ -2,24 +2,44 @@
2
2
 
3
3
  var react = require('react');
4
4
  var ChartSeries = require('./ChartSeries.js');
5
+ var vuuUtils = require('@vuu-ui/vuu-utils');
5
6
 
7
+ const defaultPalette = [
8
+ "#4676bf",
9
+ "#ab6528",
10
+ "#9f55c2",
11
+ "#2a8285",
12
+ "#697694",
13
+ "#B0549d"
14
+ ];
6
15
  const useChartOptions = ({
7
16
  categoryColumnName,
8
17
  dataSource,
18
+ itemColorFunction,
19
+ palette = defaultPalette,
9
20
  seriesColumnNames
10
21
  }) => {
11
22
  const [, forceRender] = react.useState({});
12
23
  const chartSeries = react.useMemo(() => {
24
+ console.log("new ChartSeries");
13
25
  const cs = new ChartSeries.ChartSeries({
14
- category: categoryColumnName,
15
- series: seriesColumnNames,
26
+ itemColorFunction,
16
27
  dataSource
17
28
  });
18
29
  cs.on("update", () => forceRender({}));
19
30
  return cs;
20
- }, [categoryColumnName, dataSource, seriesColumnNames]);
31
+ }, [dataSource, itemColorFunction]);
32
+ react.useMemo(() => {
33
+ if (categoryColumnName !== chartSeries.categoryColumn) {
34
+ chartSeries.categoryColumn = categoryColumnName;
35
+ }
36
+ if (vuuUtils.itemsChanged(seriesColumnNames, chartSeries.seriesColumnNames)) {
37
+ chartSeries.seriesColumnNames = seriesColumnNames;
38
+ }
39
+ }, [categoryColumnName, chartSeries, seriesColumnNames]);
21
40
  return {
22
41
  animation: false,
42
+ color: palette,
23
43
  dataZoom: [
24
44
  {
25
45
  type: "slider",
@@ -33,6 +53,9 @@ const useChartOptions = ({
33
53
  right: 5
34
54
  },
35
55
  series: chartSeries.series,
56
+ tooltip: {
57
+ trigger: "axis"
58
+ },
36
59
  xAxis: {
37
60
  data: chartSeries.categories
38
61
  },
@@ -1 +1 @@
1
- {"version":3,"file":"useChartOptions.js","sources":["../../../packages/vuu-chart/src/useChartOptions.ts"],"sourcesContent":["import { type EChartsCoreOption } from \"echarts\";\nimport { useMemo, useState } from \"react\";\nimport { ChartSeries } from \"./ChartSeries\";\nimport { DataSource } from \"@vuu-ui/vuu-data-types\";\n\nexport interface ChartOptionsProps {\n categoryColumnName: string;\n dataSource: DataSource;\n seriesColumnNames: string[];\n}\n\nexport const useChartOptions = ({\n categoryColumnName,\n dataSource,\n seriesColumnNames,\n}: ChartOptionsProps) => {\n const [, forceRender] = useState({});\n\n const chartSeries = useMemo(() => {\n const cs = new ChartSeries({\n category: categoryColumnName,\n series: seriesColumnNames,\n dataSource,\n });\n cs.on(\"update\", () => forceRender({}));\n return cs;\n }, [categoryColumnName, dataSource, seriesColumnNames]);\n\n return {\n animation: false,\n dataZoom: [\n {\n type: \"slider\",\n start: 0,\n end: 100,\n },\n ],\n grid: {\n left: \"0\",\n bottom: 0,\n right: 5,\n },\n series: chartSeries.series,\n xAxis: {\n data: chartSeries.categories,\n },\n yAxis: {},\n } as EChartsCoreOption;\n};\n"],"names":["useState","useMemo","ChartSeries"],"mappings":";;;;;AAWO,MAAM,kBAAkB,CAAC;AAAA,EAC9B,kBAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAyB,KAAA;AACvB,EAAA,MAAM,GAAG,WAAW,CAAI,GAAAA,cAAA,CAAS,EAAE,CAAA;AAEnC,EAAM,MAAA,WAAA,GAAcC,cAAQ,MAAM;AAChC,IAAM,MAAA,EAAA,GAAK,IAAIC,uBAAY,CAAA;AAAA,MACzB,QAAU,EAAA,kBAAA;AAAA,MACV,MAAQ,EAAA,iBAAA;AAAA,MACR;AAAA,KACD,CAAA;AACD,IAAA,EAAA,CAAG,GAAG,QAAU,EAAA,MAAM,WAAY,CAAA,EAAE,CAAC,CAAA;AACrC,IAAO,OAAA,EAAA;AAAA,GACN,EAAA,CAAC,kBAAoB,EAAA,UAAA,EAAY,iBAAiB,CAAC,CAAA;AAEtD,EAAO,OAAA;AAAA,IACL,SAAW,EAAA,KAAA;AAAA,IACX,QAAU,EAAA;AAAA,MACR;AAAA,QACE,IAAM,EAAA,QAAA;AAAA,QACN,KAAO,EAAA,CAAA;AAAA,QACP,GAAK,EAAA;AAAA;AACP,KACF;AAAA,IACA,IAAM,EAAA;AAAA,MACJ,IAAM,EAAA,GAAA;AAAA,MACN,MAAQ,EAAA,CAAA;AAAA,MACR,KAAO,EAAA;AAAA,KACT;AAAA,IACA,QAAQ,WAAY,CAAA,MAAA;AAAA,IACpB,KAAO,EAAA;AAAA,MACL,MAAM,WAAY,CAAA;AAAA,KACpB;AAAA,IACA,OAAO;AAAC,GACV;AACF;;;;"}
1
+ {"version":3,"file":"useChartOptions.js","sources":["../../../packages/vuu-chart/src/useChartOptions.ts"],"sourcesContent":["import { type EChartsCoreOption } from \"echarts\";\nimport { useMemo, useState } from \"react\";\nimport { ChartSeries, ItemColorFunction } from \"./ChartSeries\";\nimport { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport { itemsChanged } from \"@vuu-ui/vuu-utils\";\n\nconst defaultPalette = [\n \"#4676bf\",\n \"#ab6528\",\n \"#9f55c2\",\n \"#2a8285\",\n \"#697694\",\n \"#B0549d\",\n];\nexport interface ChartOptionsProps {\n categoryColumnName: string;\n dataSource: DataSource;\n itemColorFunction?: ItemColorFunction;\n palette?: string[];\n seriesColumnNames: string[];\n}\n\nexport const useChartOptions = ({\n categoryColumnName,\n dataSource,\n itemColorFunction,\n palette = defaultPalette,\n seriesColumnNames,\n}: ChartOptionsProps) => {\n const [, forceRender] = useState({});\n\n const chartSeries = useMemo(() => {\n console.log(\"new ChartSeries\");\n const cs = new ChartSeries({\n itemColorFunction,\n dataSource,\n });\n cs.on(\"update\", () => forceRender({}));\n return cs;\n }, [dataSource, itemColorFunction]);\n\n useMemo(() => {\n if (categoryColumnName !== chartSeries.categoryColumn) {\n chartSeries.categoryColumn = categoryColumnName;\n }\n if (itemsChanged(seriesColumnNames, chartSeries.seriesColumnNames)) {\n chartSeries.seriesColumnNames = seriesColumnNames;\n }\n }, [categoryColumnName, chartSeries, seriesColumnNames]);\n\n return {\n animation: false,\n color: palette,\n dataZoom: [\n {\n type: \"slider\",\n start: 0,\n end: 100,\n },\n ],\n grid: {\n left: \"0\",\n bottom: 0,\n right: 5,\n },\n series: chartSeries.series,\n tooltip: {\n trigger: \"axis\",\n },\n xAxis: {\n data: chartSeries.categories,\n },\n yAxis: {},\n } as EChartsCoreOption;\n};\n"],"names":["useState","useMemo","ChartSeries","itemsChanged"],"mappings":";;;;;;AAMA,MAAM,cAAiB,GAAA;AAAA,EACrB,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA;AASO,MAAM,kBAAkB,CAAC;AAAA,EAC9B,kBAAA;AAAA,EACA,UAAA;AAAA,EACA,iBAAA;AAAA,EACA,OAAU,GAAA,cAAA;AAAA,EACV;AACF,CAAyB,KAAA;AACvB,EAAA,MAAM,GAAG,WAAW,CAAI,GAAAA,cAAA,CAAS,EAAE,CAAA;AAEnC,EAAM,MAAA,WAAA,GAAcC,cAAQ,MAAM;AAChC,IAAA,OAAA,CAAQ,IAAI,iBAAiB,CAAA;AAC7B,IAAM,MAAA,EAAA,GAAK,IAAIC,uBAAY,CAAA;AAAA,MACzB,iBAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,EAAA,CAAG,GAAG,QAAU,EAAA,MAAM,WAAY,CAAA,EAAE,CAAC,CAAA;AACrC,IAAO,OAAA,EAAA;AAAA,GACN,EAAA,CAAC,UAAY,EAAA,iBAAiB,CAAC,CAAA;AAElC,EAAAD,aAAA,CAAQ,MAAM;AACZ,IAAI,IAAA,kBAAA,KAAuB,YAAY,cAAgB,EAAA;AACrD,MAAA,WAAA,CAAY,cAAiB,GAAA,kBAAA;AAAA;AAE/B,IAAA,IAAIE,qBAAa,CAAA,iBAAA,EAAmB,WAAY,CAAA,iBAAiB,CAAG,EAAA;AAClE,MAAA,WAAA,CAAY,iBAAoB,GAAA,iBAAA;AAAA;AAClC,GACC,EAAA,CAAC,kBAAoB,EAAA,WAAA,EAAa,iBAAiB,CAAC,CAAA;AAEvD,EAAO,OAAA;AAAA,IACL,SAAW,EAAA,KAAA;AAAA,IACX,KAAO,EAAA,OAAA;AAAA,IACP,QAAU,EAAA;AAAA,MACR;AAAA,QACE,IAAM,EAAA,QAAA;AAAA,QACN,KAAO,EAAA,CAAA;AAAA,QACP,GAAK,EAAA;AAAA;AACP,KACF;AAAA,IACA,IAAM,EAAA;AAAA,MACJ,IAAM,EAAA,GAAA;AAAA,MACN,MAAQ,EAAA,CAAA;AAAA,MACR,KAAO,EAAA;AAAA,KACT;AAAA,IACA,QAAQ,WAAY,CAAA,MAAA;AAAA,IACpB,OAAS,EAAA;AAAA,MACP,OAAS,EAAA;AAAA,KACX;AAAA,IACA,KAAO,EAAA;AAAA,MACL,MAAM,WAAY,CAAA;AAAA,KACpB;AAAA,IACA,OAAO;AAAC,GACV;AACF;;;;"}
package/esm/Chart.js CHANGED
@@ -9,13 +9,14 @@ import echartCss from './Chart.css.js';
9
9
 
10
10
  const Chart = ({
11
11
  categoryColumnName,
12
- chartSettings = { useCoarsePointer: true },
12
+ chartSettings = { useCoarsePointer: true, renderer: "svg" },
13
13
  // enables clicking near a line and still highlighting it
14
14
  dataSource,
15
+ itemColorFunction,
15
16
  optionSettings = { notMerge: true },
16
17
  // don't merge two options together when updating option
18
+ palette,
17
19
  style = { width: "100%", height: "100%" },
18
- events = {},
19
20
  seriesColumnNames,
20
21
  ...htmlAttributes
21
22
  }) => {
@@ -28,17 +29,19 @@ const Chart = ({
28
29
  const chartRef = useRef(null);
29
30
  const option = useChartOptions({
30
31
  categoryColumnName,
32
+ itemColorFunction,
33
+ palette,
31
34
  dataSource,
32
35
  seriesColumnNames
33
36
  });
34
- const onContextMenu = useChartContextMenu({ categoryColumnName, dataSource });
37
+ const onContextMenu = useChartContextMenu({ categoryColumnName });
35
38
  useEffect(() => {
36
39
  const chart = init(chartRef.current, null, chartSettings);
37
40
  chart.on("contextmenu", onContextMenu);
38
41
  return () => {
39
42
  chart?.dispose();
40
43
  };
41
- }, [chartSettings, events, onContextMenu]);
44
+ }, [chartSettings, onContextMenu]);
42
45
  useEffect(() => {
43
46
  if (chartRef.current) {
44
47
  const chart = getInstanceByDom(chartRef.current);
package/esm/Chart.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"Chart.js","sources":["../../../packages/vuu-chart/src/Chart.tsx"],"sourcesContent":["import { useRef, useEffect, HTMLAttributes } from \"react\";\nimport { init, getInstanceByDom } from \"echarts\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { ChartOptionsProps, useChartOptions } from \"./useChartOptions\";\nimport { useChartContextMenu } from \"./useChartContextMenu\";\n\nimport echartCss from \"./Chart.css\";\n\ntype OptionSettings = {\n notMerge: boolean;\n};\n\ntype ChartSettings = {\n useCoarsePointer: boolean;\n};\n\nexport interface ChartProps\n extends ChartOptionsProps,\n HTMLAttributes<HTMLDivElement> {\n chartSettings?: ChartSettings;\n events?: unknown;\n optionSettings?: OptionSettings;\n}\n\nexport const Chart = ({\n categoryColumnName,\n chartSettings = { useCoarsePointer: true }, // enables clicking near a line and still highlighting it\n dataSource,\n optionSettings = { notMerge: true }, // don't merge two options together when updating option\n style = { width: \"100%\", height: \"100%\" },\n events = {},\n seriesColumnNames,\n ...htmlAttributes\n}: ChartProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-toast-notification\",\n css: echartCss,\n window: targetWindow,\n });\n\n const chartRef = useRef<HTMLDivElement>(null);\n\n const option = useChartOptions({\n categoryColumnName,\n dataSource,\n seriesColumnNames,\n });\n\n const onContextMenu = useChartContextMenu({ categoryColumnName, dataSource });\n\n // Debounce resize event so it only fires periodically instead of constantly\n // const resizeChart = useMemo(\n // () =>\n // debounce(() => {\n // if (chartRef.current) {\n // const chart = getInstanceByDom(chartRef.current);\n // chart.resize();\n // }\n // }, 100),\n // [],\n // );\n\n useEffect(() => {\n // Initialize chart\n const chart = init(chartRef.current, null, chartSettings);\n\n chart.on(\"contextmenu\", onContextMenu);\n\n // Set up event listeners\n // for (const [key, handler] of Object.entries(events)) {\n // console.log(`register ${key} handler`);\n // chart.on(key, (param) => {\n // handler(param);\n // });\n // }\n\n // Resize event listener\n // const resizeObserver = new ResizeObserver(() => {\n // resizeChart();\n // });\n\n // resizeObserver.observe(chartRef.current);\n\n // Return cleanup function\n return () => {\n chart?.dispose();\n\n // if (chartRef.current) {\n // resizeObserver.unobserve(chartRef.current);\n // }\n // resizeObserver.disconnect();\n };\n }, [chartSettings, events, onContextMenu]);\n\n useEffect(() => {\n if (chartRef.current) {\n // Re-render chart when option changes\n const chart = getInstanceByDom(chartRef.current);\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n chart?.setOption(option, optionSettings);\n }\n }, [option, optionSettings]);\n\n return <div {...htmlAttributes} ref={chartRef} style={style} />;\n};\n"],"names":[],"mappings":";;;;;;;;;AAyBO,MAAM,QAAQ,CAAC;AAAA,EACpB,kBAAA;AAAA,EACA,aAAA,GAAgB,EAAE,gBAAA,EAAkB,IAAK,EAAA;AAAA;AAAA,EACzC,UAAA;AAAA,EACA,cAAA,GAAiB,EAAE,QAAA,EAAU,IAAK,EAAA;AAAA;AAAA,EAClC,KAAQ,GAAA,EAAE,KAAO,EAAA,MAAA,EAAQ,QAAQ,MAAO,EAAA;AAAA,EACxC,SAAS,EAAC;AAAA,EACV,iBAAA;AAAA,EACA,GAAG;AACL,CAAkB,KAAA;AAChB,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,wBAAA;AAAA,IACR,GAAK,EAAA,SAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA,QAAA,GAAW,OAAuB,IAAI,CAAA;AAE5C,EAAA,MAAM,SAAS,eAAgB,CAAA;AAAA,IAC7B,kBAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,aAAgB,GAAA,mBAAA,CAAoB,EAAE,kBAAA,EAAoB,YAAY,CAAA;AAc5E,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,QAAS,CAAA,OAAA,EAAS,MAAM,aAAa,CAAA;AAExD,IAAM,KAAA,CAAA,EAAA,CAAG,eAAe,aAAa,CAAA;AAkBrC,IAAA,OAAO,MAAM;AACX,MAAA,KAAA,EAAO,OAAQ,EAAA;AAAA,KAMjB;AAAA,GACC,EAAA,CAAC,aAAe,EAAA,MAAA,EAAQ,aAAa,CAAC,CAAA;AAEzC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAS,OAAS,EAAA;AAEpB,MAAM,MAAA,KAAA,GAAQ,gBAAiB,CAAA,QAAA,CAAS,OAAO,CAAA;AAG/C,MAAO,KAAA,EAAA,SAAA,CAAU,QAAQ,cAAc,CAAA;AAAA;AACzC,GACC,EAAA,CAAC,MAAQ,EAAA,cAAc,CAAC,CAAA;AAE3B,EAAA,2BAAQ,KAAK,EAAA,EAAA,GAAG,cAAgB,EAAA,GAAA,EAAK,UAAU,KAAc,EAAA,CAAA;AAC/D;;;;"}
1
+ {"version":3,"file":"Chart.js","sources":["../../../packages/vuu-chart/src/Chart.tsx"],"sourcesContent":["import { useRef, useEffect, HTMLAttributes } from \"react\";\nimport { init, getInstanceByDom } from \"echarts\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { ChartOptionsProps, useChartOptions } from \"./useChartOptions\";\nimport { useChartContextMenu } from \"./useChartContextMenu\";\n\nimport echartCss from \"./Chart.css\";\nimport { ItemColorFunction } from \"./ChartSeries\";\n\ntype OptionSettings = {\n notMerge: boolean;\n};\n\ntype ChartSettings = {\n renderer: \"svg\" | \"canvas\";\n useCoarsePointer: boolean;\n};\n\nexport interface ChartProps\n extends ChartOptionsProps,\n HTMLAttributes<HTMLDivElement> {\n chartSettings?: ChartSettings;\n itemColorFunction?: ItemColorFunction;\n optionSettings?: OptionSettings;\n palette?: string[];\n}\n\nexport const Chart = ({\n categoryColumnName,\n chartSettings = { useCoarsePointer: true, renderer: \"svg\" }, // enables clicking near a line and still highlighting it\n dataSource,\n itemColorFunction,\n optionSettings = { notMerge: true }, // don't merge two options together when updating option\n palette,\n style = { width: \"100%\", height: \"100%\" },\n seriesColumnNames,\n ...htmlAttributes\n}: ChartProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-toast-notification\",\n css: echartCss,\n window: targetWindow,\n });\n\n const chartRef = useRef<HTMLDivElement>(null);\n\n const option = useChartOptions({\n categoryColumnName,\n itemColorFunction,\n palette,\n dataSource,\n seriesColumnNames,\n });\n\n const onContextMenu = useChartContextMenu({ categoryColumnName });\n\n // Debounce resize event so it only fires periodically instead of constantly\n // const resizeChart = useMemo(\n // () =>\n // debounce(() => {\n // if (chartRef.current) {\n // const chart = getInstanceByDom(chartRef.current);\n // chart.resize();\n // }\n // }, 100),\n // [],\n // );\n\n useEffect(() => {\n // Initialize chart\n const chart = init(chartRef.current, null, chartSettings);\n\n chart.on(\"contextmenu\", onContextMenu);\n\n // Resize event listener\n // const resizeObserver = new ResizeObserver(() => {\n // resizeChart();\n // });\n\n // resizeObserver.observe(chartRef.current);\n\n // Return cleanup function\n return () => {\n chart?.dispose();\n\n // if (chartRef.current) {\n // resizeObserver.unobserve(chartRef.current);\n // }\n // resizeObserver.disconnect();\n };\n }, [chartSettings, onContextMenu]);\n\n useEffect(() => {\n if (chartRef.current) {\n // Re-render chart when option changes\n const chart = getInstanceByDom(chartRef.current);\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n chart?.setOption(option, optionSettings);\n }\n }, [option, optionSettings]);\n\n return <div {...htmlAttributes} ref={chartRef} style={style} />;\n};\n"],"names":[],"mappings":";;;;;;;;;AA4BO,MAAM,QAAQ,CAAC;AAAA,EACpB,kBAAA;AAAA,EACA,aAAgB,GAAA,EAAE,gBAAkB,EAAA,IAAA,EAAM,UAAU,KAAM,EAAA;AAAA;AAAA,EAC1D,UAAA;AAAA,EACA,iBAAA;AAAA,EACA,cAAA,GAAiB,EAAE,QAAA,EAAU,IAAK,EAAA;AAAA;AAAA,EAClC,OAAA;AAAA,EACA,KAAQ,GAAA,EAAE,KAAO,EAAA,MAAA,EAAQ,QAAQ,MAAO,EAAA;AAAA,EACxC,iBAAA;AAAA,EACA,GAAG;AACL,CAAkB,KAAA;AAChB,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,wBAAA;AAAA,IACR,GAAK,EAAA,SAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA,QAAA,GAAW,OAAuB,IAAI,CAAA;AAE5C,EAAA,MAAM,SAAS,eAAgB,CAAA;AAAA,IAC7B,kBAAA;AAAA,IACA,iBAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,MAAM,aAAgB,GAAA,mBAAA,CAAoB,EAAE,kBAAA,EAAoB,CAAA;AAchE,EAAA,SAAA,CAAU,MAAM;AAEd,IAAA,MAAM,KAAQ,GAAA,IAAA,CAAK,QAAS,CAAA,OAAA,EAAS,MAAM,aAAa,CAAA;AAExD,IAAM,KAAA,CAAA,EAAA,CAAG,eAAe,aAAa,CAAA;AAUrC,IAAA,OAAO,MAAM;AACX,MAAA,KAAA,EAAO,OAAQ,EAAA;AAAA,KAMjB;AAAA,GACC,EAAA,CAAC,aAAe,EAAA,aAAa,CAAC,CAAA;AAEjC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,SAAS,OAAS,EAAA;AAEpB,MAAM,MAAA,KAAA,GAAQ,gBAAiB,CAAA,QAAA,CAAS,OAAO,CAAA;AAG/C,MAAO,KAAA,EAAA,SAAA,CAAU,QAAQ,cAAc,CAAA;AAAA;AACzC,GACC,EAAA,CAAC,MAAQ,EAAA,cAAc,CAAC,CAAA;AAE3B,EAAA,2BAAQ,KAAK,EAAA,EAAA,GAAG,cAAgB,EAAA,GAAA,EAAK,UAAU,KAAc,EAAA,CAAA;AAC/D;;;;"}
@@ -1,4 +1,5 @@
1
- import { EventEmitter, Range, buildColumnMap } from '@vuu-ui/vuu-utils';
1
+ import { EventEmitter, Range, metadataKeys, buildColumnMap } from '@vuu-ui/vuu-utils';
2
+ import { MovingDataRowWindow } from './DataRowMovingWindow.js';
2
3
 
3
4
  var __defProp = Object.defineProperty;
4
5
  var __typeError = (msg) => {
@@ -10,8 +11,13 @@ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot
10
11
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
11
12
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
12
13
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
13
- var _categoryColumn, _columnMap, _dataSource, _categoryCount, _dates, _series, _seriesColumns;
14
- function getCategoriesAndSeries(columnMap, data, categoryColumn, seriesColumns) {
14
+ var _categoryColumn, _columnMap, _itemColorFunction, _dataWindow, _dates, _series, _seriesColumns;
15
+ const defaultItemColorFunction = ({ color }) => color;
16
+ const { KEY } = metadataKeys;
17
+ function DataSourceValue(key, row, value) {
18
+ return { key, row, value };
19
+ }
20
+ function getCategoriesAndSeries(columnMap, data, categoryColumn, seriesColumns, itemColorFunction = defaultItemColorFunction) {
15
21
  const categoryValues = [];
16
22
  const seriesMap = /* @__PURE__ */ new Map();
17
23
  data.forEach((row) => {
@@ -21,54 +27,88 @@ function getCategoriesAndSeries(columnMap, data, categoryColumn, seriesColumns)
21
27
  let series = seriesMap.get(seriesColumn);
22
28
  if (!series) {
23
29
  series = {
24
- id: "test-1",
30
+ //any reason we can't simply use col name here ?
31
+ id: seriesColumn,
25
32
  name: seriesColumn,
26
33
  label: seriesColumn,
27
34
  data: [],
28
- type: "line"
35
+ type: "line",
36
+ itemStyle: {
37
+ color: itemColorFunction
38
+ },
39
+ lineStyle: {
40
+ width: 1.5
41
+ },
42
+ symbol: "circle"
29
43
  };
30
44
  seriesMap.set(seriesColumn, series);
31
45
  }
32
- series.data.push(row[columnMap[seriesColumn]]);
46
+ const key = row[KEY];
47
+ const value = row[columnMap[seriesColumn]];
48
+ series.data.push(DataSourceValue(key, row, value));
33
49
  }
34
50
  });
35
51
  return [categoryValues, Array.from(seriesMap.values())];
36
52
  }
37
53
  class ChartSeries extends EventEmitter {
38
- constructor({ category, dataSource, series }) {
54
+ constructor({ dataSource, itemColorFunction }) {
39
55
  super();
40
- __privateAdd(this, _categoryColumn);
56
+ __privateAdd(this, _categoryColumn, "");
41
57
  __privateAdd(this, _columnMap, {});
42
- __privateAdd(this, _dataSource);
43
- __privateAdd(this, _categoryCount, 0);
58
+ __privateAdd(this, _itemColorFunction);
59
+ __privateAdd(this, _dataWindow, new MovingDataRowWindow(Range(0, 1e3)));
44
60
  __privateAdd(this, _dates, []);
45
61
  __privateAdd(this, _series, []);
46
- __privateAdd(this, _seriesColumns);
62
+ __privateAdd(this, _seriesColumns, []);
47
63
  __publicField(this, "handleData", (message) => {
48
64
  if (message.type === "subscribed") {
49
65
  __privateSet(this, _columnMap, buildColumnMap(message.tableSchema.columns));
50
66
  } else if (message.type === "viewport-update") {
51
- if (message.mode === "size-only") {
52
- __privateSet(this, _categoryCount, message.size ?? 0);
53
- } else if (message.rows) {
54
- const [dates, series] = getCategoriesAndSeries(
55
- __privateGet(this, _columnMap),
56
- message.rows,
57
- __privateGet(this, _categoryColumn),
58
- __privateGet(this, _seriesColumns)
59
- );
60
- __privateSet(this, _dates, dates);
61
- __privateSet(this, _series, series);
67
+ if (message.mode === "size-only") ; else if (message.rows) {
68
+ for (const row of message.rows) {
69
+ __privateGet(this, _dataWindow).add(row);
70
+ }
71
+ this.buildCategoriesAndSeries();
62
72
  }
63
73
  } else {
64
74
  console.warn(JSON.stringify(message));
65
75
  }
66
76
  });
67
- __privateSet(this, _categoryColumn, category);
68
- __privateSet(this, _dataSource, dataSource);
69
- __privateSet(this, _seriesColumns, series);
77
+ __privateSet(this, _itemColorFunction, itemColorFunction);
70
78
  dataSource.subscribe({ range: Range(0, 1e3) }, this.handleData);
71
79
  }
80
+ buildCategoriesAndSeries() {
81
+ if (__privateGet(this, _categoryColumn) && __privateGet(this, _seriesColumns).length > 0) {
82
+ const [dates, series] = getCategoriesAndSeries(
83
+ __privateGet(this, _columnMap),
84
+ __privateGet(this, _dataWindow).data,
85
+ __privateGet(this, _categoryColumn),
86
+ __privateGet(this, _seriesColumns),
87
+ __privateGet(this, _itemColorFunction)
88
+ );
89
+ __privateSet(this, _dates, dates);
90
+ __privateSet(this, _series, series);
91
+ this.emit("update");
92
+ }
93
+ }
94
+ get categoryColumn() {
95
+ return __privateGet(this, _categoryColumn);
96
+ }
97
+ set categoryColumn(categoryColumn) {
98
+ __privateSet(this, _categoryColumn, categoryColumn);
99
+ if (__privateGet(this, _seriesColumns).length > 0) {
100
+ this.buildCategoriesAndSeries();
101
+ }
102
+ }
103
+ get seriesColumnNames() {
104
+ return __privateGet(this, _seriesColumns);
105
+ }
106
+ set seriesColumnNames(seriesColumnNames) {
107
+ __privateSet(this, _seriesColumns, seriesColumnNames);
108
+ if (__privateGet(this, _categoryColumn)) {
109
+ this.buildCategoriesAndSeries();
110
+ }
111
+ }
72
112
  get categories() {
73
113
  return __privateGet(this, _dates);
74
114
  }
@@ -78,8 +118,8 @@ class ChartSeries extends EventEmitter {
78
118
  }
79
119
  _categoryColumn = new WeakMap();
80
120
  _columnMap = new WeakMap();
81
- _dataSource = new WeakMap();
82
- _categoryCount = new WeakMap();
121
+ _itemColorFunction = new WeakMap();
122
+ _dataWindow = new WeakMap();
83
123
  _dates = new WeakMap();
84
124
  _series = new WeakMap();
85
125
  _seriesColumns = new WeakMap();
@@ -1 +1 @@
1
- {"version":3,"file":"ChartSeries.js","sources":["../../../packages/vuu-chart/src/ChartSeries.ts"],"sourcesContent":["import {\n DataSource,\n DataSourceRow,\n DataSourceSubscribeCallback,\n} from \"@vuu-ui/vuu-data-types\";\nimport {\n buildColumnMap,\n ColumnMap,\n EventEmitter,\n Range,\n} from \"@vuu-ui/vuu-utils\";\n\ntype Series = {\n id: string;\n name: string;\n label: string;\n data: number[];\n type: \"line\";\n};\n\nfunction getCategoriesAndSeries(\n columnMap: ColumnMap,\n data: DataSourceRow[],\n categoryColumn: string,\n seriesColumns: string[],\n): [string[], Series[]] {\n const categoryValues: string[] = [];\n const seriesMap = new Map<string, Series>();\n\n data.forEach((row) => {\n const categoryValue = row[columnMap[categoryColumn]] as string;\n categoryValues.push(categoryValue);\n\n for (const seriesColumn of seriesColumns) {\n let series = seriesMap.get(seriesColumn);\n if (!series) {\n series = {\n id: \"test-1\",\n name: seriesColumn,\n label: seriesColumn,\n data: [],\n type: \"line\",\n };\n seriesMap.set(seriesColumn, series);\n }\n series.data.push(row[columnMap[seriesColumn]] as number);\n }\n });\n\n return [categoryValues, Array.from(seriesMap.values())];\n}\n\nexport type ChartEvents = {\n update: () => void;\n};\nexport interface ChartSeriesConstructorProps {\n dataSource: DataSource;\n /**\n * The column name of the column that defines our category axis.\n * By default, these are the x axis values.\n */\n category: string;\n /**\n * The column names of the columns that define our data.\n * By default, these are the y axis values.\n */\n series: string[];\n}\n\nexport class ChartSeries extends EventEmitter<ChartEvents> {\n #categoryColumn: string;\n #columnMap: ColumnMap = {};\n #dataSource: DataSource;\n #categoryCount = 0;\n\n #dates: string[] = [];\n #series: Series[] = [];\n #seriesColumns: string[];\n\n handleData: DataSourceSubscribeCallback = (message) => {\n if (message.type === \"subscribed\") {\n this.#columnMap = buildColumnMap(message.tableSchema.columns);\n } else if (message.type === \"viewport-update\") {\n if (message.mode === \"size-only\") {\n this.#categoryCount = message.size ?? 0;\n } else if (message.rows) {\n const [dates, series] = getCategoriesAndSeries(\n this.#columnMap,\n message.rows,\n this.#categoryColumn,\n this.#seriesColumns,\n );\n this.#dates = dates;\n this.#series = series;\n }\n } else {\n console.warn(JSON.stringify(message));\n }\n };\n\n constructor({ category, dataSource, series }: ChartSeriesConstructorProps) {\n super();\n this.#categoryColumn = category;\n this.#dataSource = dataSource;\n this.#seriesColumns = series;\n\n dataSource.subscribe({ range: Range(0, 1000) }, this.handleData);\n }\n\n get categories() {\n return this.#dates;\n }\n\n get series() {\n return this.#series;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChartSeries.js","sources":["../../../packages/vuu-chart/src/ChartSeries.ts"],"sourcesContent":["import {\n DataSource,\n DataSourceRow,\n DataSourceSubscribeCallback,\n} from \"@vuu-ui/vuu-data-types\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n buildColumnMap,\n ColumnMap,\n EventEmitter,\n Range,\n metadataKeys,\n} from \"@vuu-ui/vuu-utils\";\nimport { MovingDataRowWindow } from \"./DataRowMovingWindow\";\n\ntype Series = {\n id: string;\n name: string;\n label: string;\n data: DataSourceValue<number>[];\n lineStyle: {\n width: number;\n };\n itemStyle: {\n color: string | ItemColorFunction;\n };\n symbol: \"emptyCircle\" | \"circle\";\n type: \"line\";\n};\n\nexport type ItemColorFunction = (params: {\n color: string;\n data: DataSourceValue;\n dataIndex: number;\n name: string;\n seriesName: string;\n}) => string;\n\nconst defaultItemColorFunction: ItemColorFunction = ({ color }) => color;\n\nconst { KEY } = metadataKeys;\n\nexport type DataSourceValue<T extends VuuRowDataItemType = number> = {\n key: string;\n readonly row: DataSourceRow;\n value: T;\n};\n\nfunction DataSourceValue<T extends VuuRowDataItemType = number>(\n key: string,\n row: DataSourceRow,\n value: T,\n): DataSourceValue<T> {\n return { key, row, value };\n}\n\nfunction getCategoriesAndSeries(\n columnMap: ColumnMap,\n data: DataSourceRow[],\n categoryColumn: string,\n seriesColumns: string[],\n itemColorFunction = defaultItemColorFunction,\n): [string[], Series[]] {\n const categoryValues: string[] = [];\n const seriesMap = new Map<string, Series>();\n\n data.forEach((row) => {\n const categoryValue = row[columnMap[categoryColumn]] as string;\n categoryValues.push(categoryValue);\n\n for (const seriesColumn of seriesColumns) {\n let series = seriesMap.get(seriesColumn);\n if (!series) {\n series = {\n //any reason we can't simply use col name here ?\n id: seriesColumn,\n name: seriesColumn,\n label: seriesColumn,\n data: [],\n type: \"line\",\n itemStyle: {\n color: itemColorFunction,\n },\n lineStyle: {\n width: 1.5,\n },\n symbol: \"circle\",\n };\n seriesMap.set(seriesColumn, series);\n }\n\n const key = row[KEY] as string;\n const value = row[columnMap[seriesColumn]] as number;\n series.data.push(DataSourceValue(key, row, value));\n }\n });\n\n return [categoryValues, Array.from(seriesMap.values())];\n}\n\nexport type ChartEvents = {\n update: () => void;\n};\nexport interface ChartSeriesConstructorProps {\n dataSource: DataSource;\n itemColorFunction?: ItemColorFunction;\n}\n\nexport class ChartSeries extends EventEmitter<ChartEvents> {\n #categoryColumn = \"\";\n #columnMap: ColumnMap = {};\n #itemColorFunction: ItemColorFunction | undefined;\n #dataWindow = new MovingDataRowWindow(Range(0, 1000));\n\n #dates: string[] = [];\n #series: Series[] = [];\n #seriesColumns: string[] = [];\n\n handleData: DataSourceSubscribeCallback = (message) => {\n if (message.type === \"subscribed\") {\n this.#columnMap = buildColumnMap(message.tableSchema.columns);\n } else if (message.type === \"viewport-update\") {\n if (message.mode === \"size-only\") {\n // ???\n } else if (message.rows) {\n for (const row of message.rows) {\n this.#dataWindow.add(row);\n }\n this.buildCategoriesAndSeries();\n }\n } else {\n console.warn(JSON.stringify(message));\n }\n };\n\n buildCategoriesAndSeries() {\n if (this.#categoryColumn && this.#seriesColumns.length > 0) {\n const [dates, series] = getCategoriesAndSeries(\n this.#columnMap,\n this.#dataWindow.data,\n this.#categoryColumn,\n this.#seriesColumns,\n this.#itemColorFunction,\n );\n this.#dates = dates;\n this.#series = series;\n\n this.emit(\"update\");\n }\n }\n\n constructor({ dataSource, itemColorFunction }: ChartSeriesConstructorProps) {\n super();\n this.#itemColorFunction = itemColorFunction;\n dataSource.subscribe({ range: Range(0, 1000) }, this.handleData);\n }\n\n get categoryColumn() {\n return this.#categoryColumn;\n }\n\n set categoryColumn(categoryColumn: string) {\n this.#categoryColumn = categoryColumn;\n if (this.#seriesColumns.length > 0) {\n this.buildCategoriesAndSeries();\n }\n }\n\n get seriesColumnNames() {\n return this.#seriesColumns;\n }\n\n set seriesColumnNames(seriesColumnNames: string[]) {\n this.#seriesColumns = seriesColumnNames;\n if (this.#categoryColumn) {\n this.buildCategoriesAndSeries();\n }\n }\n\n get categories() {\n return this.#dates;\n }\n\n get series() {\n return this.#series;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,IAAA,eAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,WAAA,EAAA,MAAA,EAAA,OAAA,EAAA,cAAA;AAsCA,MAAM,wBAA8C,GAAA,CAAC,EAAE,KAAA,EAAY,KAAA,KAAA;AAEnE,MAAM,EAAE,KAAQ,GAAA,YAAA;AAQhB,SAAS,eAAA,CACP,GACA,EAAA,GAAA,EACA,KACoB,EAAA;AACpB,EAAO,OAAA,EAAE,GAAK,EAAA,GAAA,EAAK,KAAM,EAAA;AAC3B;AAEA,SAAS,uBACP,SACA,EAAA,IAAA,EACA,cACA,EAAA,aAAA,EACA,oBAAoB,wBACE,EAAA;AACtB,EAAA,MAAM,iBAA2B,EAAC;AAClC,EAAM,MAAA,SAAA,uBAAgB,GAAoB,EAAA;AAE1C,EAAK,IAAA,CAAA,OAAA,CAAQ,CAAC,GAAQ,KAAA;AACpB,IAAA,MAAM,aAAgB,GAAA,GAAA,CAAI,SAAU,CAAA,cAAc,CAAC,CAAA;AACnD,IAAA,cAAA,CAAe,KAAK,aAAa,CAAA;AAEjC,IAAA,KAAA,MAAW,gBAAgB,aAAe,EAAA;AACxC,MAAI,IAAA,MAAA,GAAS,SAAU,CAAA,GAAA,CAAI,YAAY,CAAA;AACvC,MAAA,IAAI,CAAC,MAAQ,EAAA;AACX,QAAS,MAAA,GAAA;AAAA;AAAA,UAEP,EAAI,EAAA,YAAA;AAAA,UACJ,IAAM,EAAA,YAAA;AAAA,UACN,KAAO,EAAA,YAAA;AAAA,UACP,MAAM,EAAC;AAAA,UACP,IAAM,EAAA,MAAA;AAAA,UACN,SAAW,EAAA;AAAA,YACT,KAAO,EAAA;AAAA,WACT;AAAA,UACA,SAAW,EAAA;AAAA,YACT,KAAO,EAAA;AAAA,WACT;AAAA,UACA,MAAQ,EAAA;AAAA,SACV;AACA,QAAU,SAAA,CAAA,GAAA,CAAI,cAAc,MAAM,CAAA;AAAA;AAGpC,MAAM,MAAA,GAAA,GAAM,IAAI,GAAG,CAAA;AACnB,MAAA,MAAM,KAAQ,GAAA,GAAA,CAAI,SAAU,CAAA,YAAY,CAAC,CAAA;AACzC,MAAA,MAAA,CAAO,KAAK,IAAK,CAAA,eAAA,CAAgB,GAAK,EAAA,GAAA,EAAK,KAAK,CAAC,CAAA;AAAA;AACnD,GACD,CAAA;AAED,EAAA,OAAO,CAAC,cAAgB,EAAA,KAAA,CAAM,KAAK,SAAU,CAAA,MAAA,EAAQ,CAAC,CAAA;AACxD;AAUO,MAAM,oBAAoB,YAA0B,CAAA;AAAA,EA2CzD,WAAY,CAAA,EAAE,UAAY,EAAA,iBAAA,EAAkD,EAAA;AAC1E,IAAM,KAAA,EAAA;AA3CR,IAAkB,YAAA,CAAA,IAAA,EAAA,eAAA,EAAA,EAAA,CAAA;AAClB,IAAA,YAAA,CAAA,IAAA,EAAA,UAAA,EAAwB,EAAC,CAAA;AACzB,IAAA,YAAA,CAAA,IAAA,EAAA,kBAAA,CAAA;AACA,IAAA,YAAA,CAAA,IAAA,EAAA,WAAA,EAAc,IAAI,mBAAA,CAAoB,KAAM,CAAA,CAAA,EAAG,GAAI,CAAC,CAAA,CAAA;AAEpD,IAAA,YAAA,CAAA,IAAA,EAAA,MAAA,EAAmB,EAAC,CAAA;AACpB,IAAA,YAAA,CAAA,IAAA,EAAA,OAAA,EAAoB,EAAC,CAAA;AACrB,IAAA,YAAA,CAAA,IAAA,EAAA,cAAA,EAA2B,EAAC,CAAA;AAE5B,IAAA,aAAA,CAAA,IAAA,EAAA,YAAA,EAA0C,CAAC,OAAY,KAAA;AACrD,MAAI,IAAA,OAAA,CAAQ,SAAS,YAAc,EAAA;AACjC,QAAA,YAAA,CAAA,IAAA,EAAK,UAAa,EAAA,cAAA,CAAe,OAAQ,CAAA,WAAA,CAAY,OAAO,CAAA,CAAA;AAAA,OAC9D,MAAA,IAAW,OAAQ,CAAA,IAAA,KAAS,iBAAmB,EAAA;AAC7C,QAAI,IAAA,OAAA,CAAQ,SAAS,WAAa,EAAA,CAElC,MAAA,IAAW,QAAQ,IAAM,EAAA;AACvB,UAAW,KAAA,MAAA,GAAA,IAAO,QAAQ,IAAM,EAAA;AAC9B,YAAK,YAAA,CAAA,IAAA,EAAA,WAAA,CAAA,CAAY,IAAI,GAAG,CAAA;AAAA;AAE1B,UAAA,IAAA,CAAK,wBAAyB,EAAA;AAAA;AAChC,OACK,MAAA;AACL,QAAA,OAAA,CAAQ,IAAK,CAAA,IAAA,CAAK,SAAU,CAAA,OAAO,CAAC,CAAA;AAAA;AACtC,KACF,CAAA;AAoBE,IAAA,YAAA,CAAA,IAAA,EAAK,kBAAqB,EAAA,iBAAA,CAAA;AAC1B,IAAW,UAAA,CAAA,SAAA,CAAU,EAAE,KAAO,EAAA,KAAA,CAAM,GAAG,GAAI,CAAA,EAAK,EAAA,IAAA,CAAK,UAAU,CAAA;AAAA;AACjE,EApBA,wBAA2B,GAAA;AACzB,IAAA,IAAI,YAAK,CAAA,IAAA,EAAA,eAAA,CAAA,IAAmB,YAAK,CAAA,IAAA,EAAA,cAAA,CAAA,CAAe,SAAS,CAAG,EAAA;AAC1D,MAAM,MAAA,CAAC,KAAO,EAAA,MAAM,CAAI,GAAA,sBAAA;AAAA,QACtB,YAAK,CAAA,IAAA,EAAA,UAAA,CAAA;AAAA,QACL,mBAAK,WAAY,CAAA,CAAA,IAAA;AAAA,QACjB,YAAK,CAAA,IAAA,EAAA,eAAA,CAAA;AAAA,QACL,YAAK,CAAA,IAAA,EAAA,cAAA,CAAA;AAAA,QACL,YAAK,CAAA,IAAA,EAAA,kBAAA;AAAA,OACP;AACA,MAAA,YAAA,CAAA,IAAA,EAAK,MAAS,EAAA,KAAA,CAAA;AACd,MAAA,YAAA,CAAA,IAAA,EAAK,OAAU,EAAA,MAAA,CAAA;AAEf,MAAA,IAAA,CAAK,KAAK,QAAQ,CAAA;AAAA;AACpB;AACF,EAQA,IAAI,cAAiB,GAAA;AACnB,IAAA,OAAO,YAAK,CAAA,IAAA,EAAA,eAAA,CAAA;AAAA;AACd,EAEA,IAAI,eAAe,cAAwB,EAAA;AACzC,IAAA,YAAA,CAAA,IAAA,EAAK,eAAkB,EAAA,cAAA,CAAA;AACvB,IAAI,IAAA,YAAA,CAAA,IAAA,EAAK,cAAe,CAAA,CAAA,MAAA,GAAS,CAAG,EAAA;AAClC,MAAA,IAAA,CAAK,wBAAyB,EAAA;AAAA;AAChC;AACF,EAEA,IAAI,iBAAoB,GAAA;AACtB,IAAA,OAAO,YAAK,CAAA,IAAA,EAAA,cAAA,CAAA;AAAA;AACd,EAEA,IAAI,kBAAkB,iBAA6B,EAAA;AACjD,IAAA,YAAA,CAAA,IAAA,EAAK,cAAiB,EAAA,iBAAA,CAAA;AACtB,IAAA,IAAI,mBAAK,eAAiB,CAAA,EAAA;AACxB,MAAA,IAAA,CAAK,wBAAyB,EAAA;AAAA;AAChC;AACF,EAEA,IAAI,UAAa,GAAA;AACf,IAAA,OAAO,YAAK,CAAA,IAAA,EAAA,MAAA,CAAA;AAAA;AACd,EAEA,IAAI,MAAS,GAAA;AACX,IAAA,OAAO,YAAK,CAAA,IAAA,EAAA,OAAA,CAAA;AAAA;AAEhB;AA7EE,eAAA,GAAA,IAAA,OAAA,EAAA;AACA,UAAA,GAAA,IAAA,OAAA,EAAA;AACA,kBAAA,GAAA,IAAA,OAAA,EAAA;AACA,WAAA,GAAA,IAAA,OAAA,EAAA;AAEA,MAAA,GAAA,IAAA,OAAA,EAAA;AACA,OAAA,GAAA,IAAA,OAAA,EAAA;AACA,cAAA,GAAA,IAAA,OAAA,EAAA;;;;"}
@@ -0,0 +1,95 @@
1
+ import { WindowRange, metadataKeys } from '@vuu-ui/vuu-utils';
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __typeError = (msg) => {
5
+ throw TypeError(msg);
6
+ };
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
9
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
10
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
11
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
12
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
13
+ var _range;
14
+ const { IDX, KEY } = metadataKeys;
15
+ class MovingDataRowWindow {
16
+ constructor({ from, to }) {
17
+ __publicField(this, "data");
18
+ __publicField(this, "rowCount", 0);
19
+ __privateAdd(this, _range);
20
+ __publicField(this, "setRowCount", (rowCount) => {
21
+ if (rowCount < this.data.length) {
22
+ this.data.length = rowCount;
23
+ }
24
+ this.rowCount = rowCount;
25
+ });
26
+ __privateSet(this, _range, new WindowRange(from, to));
27
+ this.data = new Array(Math.max(0, to - from));
28
+ this.rowCount = 0;
29
+ }
30
+ add(data) {
31
+ const index = data[IDX];
32
+ if (this.isWithinRange(index)) {
33
+ const internalIndex = index - __privateGet(this, _range).from;
34
+ this.data[internalIndex] = data;
35
+ }
36
+ }
37
+ getAtIndex(index) {
38
+ return __privateGet(this, _range).isWithin(index) && this.data[index - __privateGet(this, _range).from] != null ? this.data[index - __privateGet(this, _range).from] : void 0;
39
+ }
40
+ getByKey(key) {
41
+ return this.data.find((row) => row[KEY] === key);
42
+ }
43
+ isWithinRange(index) {
44
+ return __privateGet(this, _range).isWithin(index);
45
+ }
46
+ setRange({ from, to }) {
47
+ if (from !== __privateGet(this, _range).from || to !== __privateGet(this, _range).to) {
48
+ const [overlapFrom, overlapTo] = __privateGet(this, _range).overlap(from, to);
49
+ const newData = new Array(Math.max(0, to - from));
50
+ for (let i = overlapFrom; i < overlapTo; i++) {
51
+ const data = this.getAtIndex(i);
52
+ if (data) {
53
+ const index = i - from;
54
+ newData[index] = data;
55
+ }
56
+ }
57
+ this.data = newData;
58
+ __privateGet(this, _range).from = from;
59
+ __privateGet(this, _range).to = to;
60
+ }
61
+ }
62
+ get hasData() {
63
+ return this.data.some((d) => d !== void 0);
64
+ }
65
+ /**
66
+ * This will throw if there is no data. Check `hasData` first
67
+ * to guard against this, if not certain.
68
+ */
69
+ get firstRow() {
70
+ for (let i = 0; i < this.data.length; i++) {
71
+ if (this.data[i]) {
72
+ return this.data[i];
73
+ }
74
+ }
75
+ throw Error(`[DataRowMovingWinddow] firstRow, no data`);
76
+ }
77
+ get range() {
78
+ return __privateGet(this, _range);
79
+ }
80
+ // TODO make this more performant, see implementation in
81
+ // array-backed-moving-window - use same implementation
82
+ get hasAllRowsWithinRange() {
83
+ const { from, to } = __privateGet(this, _range);
84
+ for (let i = from; i < to; i++) {
85
+ if (this.getAtIndex(i) === void 0) {
86
+ return false;
87
+ }
88
+ }
89
+ return true;
90
+ }
91
+ }
92
+ _range = new WeakMap();
93
+
94
+ export { MovingDataRowWindow };
95
+ //# sourceMappingURL=DataRowMovingWindow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataRowMovingWindow.js","sources":["../../../packages/vuu-chart/src/DataRowMovingWindow.ts"],"sourcesContent":["import { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { WindowRange } from \"@vuu-ui/vuu-utils\";\nimport { metadataKeys } from \"@vuu-ui/vuu-utils\";\n\nconst { IDX, KEY } = metadataKeys;\n\nexport class MovingDataRowWindow {\n public data: DataSourceRow[];\n public rowCount = 0;\n #range: WindowRange;\n\n constructor({ from, to }: VuuRange) {\n this.#range = new WindowRange(from, to);\n //internal data is always 0 based, we add range.from to determine an offset\n this.data = new Array(Math.max(0, to - from));\n this.rowCount = 0;\n }\n\n setRowCount = (rowCount: number) => {\n if (rowCount < this.data.length) {\n this.data.length = rowCount;\n }\n\n this.rowCount = rowCount;\n };\n\n add(data: DataSourceRow) {\n const index = data[IDX];\n if (this.isWithinRange(index)) {\n const internalIndex = index - this.#range.from;\n this.data[internalIndex] = data;\n }\n }\n\n getAtIndex(index: number) {\n return this.#range.isWithin(index) &&\n this.data[index - this.#range.from] != null\n ? this.data[index - this.#range.from]\n : undefined;\n }\n\n getByKey(key: string) {\n return this.data.find((row) => row[KEY] === key);\n }\n\n isWithinRange(index: number) {\n return this.#range.isWithin(index);\n }\n\n setRange({ from, to }: VuuRange) {\n if (from !== this.#range.from || to !== this.#range.to) {\n const [overlapFrom, overlapTo] = this.#range.overlap(from, to);\n const newData = new Array(Math.max(0, to - from));\n for (let i = overlapFrom; i < overlapTo; i++) {\n const data = this.getAtIndex(i);\n if (data) {\n const index = i - from;\n newData[index] = data;\n }\n }\n this.data = newData;\n this.#range.from = from;\n this.#range.to = to;\n }\n }\n\n get hasData() {\n return this.data.some((d) => d !== undefined);\n }\n\n /**\n * This will throw if there is no data. Check `hasData` first\n * to guard against this, if not certain.\n */\n get firstRow() {\n for (let i = 0; i < this.data.length; i++) {\n if (this.data[i]) {\n return this.data[i];\n }\n }\n throw Error(`[DataRowMovingWinddow] firstRow, no data`);\n }\n\n get range() {\n return this.#range;\n }\n\n // TODO make this more performant, see implementation in\n // array-backed-moving-window - use same implementation\n get hasAllRowsWithinRange(): boolean {\n const { from, to } = this.#range;\n\n for (let i = from; i < to; i++) {\n if (this.getAtIndex(i) === undefined) {\n return false;\n }\n }\n return true;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -7,22 +7,24 @@ const useChartContextMenu = ({
7
7
  const showContextMenu = useContextMenu();
8
8
  const onContextMenu = useCallback(
9
9
  ({
10
- // dataIndex,
10
+ data,
11
11
  event,
12
12
  name: categoryValue,
13
- // seriesId,
14
13
  seriesName: valueColumn,
15
- value
16
- // ...params
14
+ value: keyedValue,
15
+ ...rest
17
16
  }) => {
18
17
  event.stop();
18
+ console.log({ rest });
19
+ const { row, value } = data;
19
20
  const menuOptions = {
20
21
  categoryColumn: categoryColumnName,
21
22
  categoryValue,
23
+ row,
22
24
  valueColumn,
23
25
  value
24
26
  };
25
- showContextMenu(event.event, "chart", menuOptions, {
27
+ showContextMenu(event.event, "series", menuOptions, {
26
28
  onOpenChange: (isOpen) => {
27
29
  console.log(`[useTableContextMenu] onOpenChange ${isOpen}`);
28
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useChartContextMenu.js","sources":["../../../packages/vuu-chart/src/useChartContextMenu.ts"],"sourcesContent":["import { useContextMenu } from \"@vuu-ui/vuu-context-menu\";\nimport { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { useCallback } from \"react\";\n\ntype EChartContextMenuEvent = {\n event: PointerEvent;\n offsetX: number;\n offsetY: number;\n stop: () => void;\n type: \"contextmenu\";\n};\n\nexport type ChartContextMenuOptions = {\n categoryColumn: string;\n categoryValue: VuuRowDataItemType;\n valueColumn: string;\n value: VuuRowDataItemType;\n};\n\ntype EChartContextMenuHandlerParams = {\n dataIndex: number;\n event: EChartContextMenuEvent;\n name: string;\n seriesId: string;\n seriesName: string;\n value: number;\n};\n\ninterface ChartContextMenuHookProps {\n allowContextMenu?: boolean;\n categoryColumnName: string;\n dataSource: DataSource;\n}\n\nexport const useChartContextMenu = ({\n categoryColumnName,\n}: ChartContextMenuHookProps) => {\n const showContextMenu = useContextMenu();\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n //@ts-ignore\n const onContextMenu = useCallback<any>(\n ({\n // dataIndex,\n event,\n name: categoryValue,\n // seriesId,\n seriesName: valueColumn,\n value,\n // ...params\n }: EChartContextMenuHandlerParams) => {\n event.stop();\n // console.log(\n // `on context menu [${dataIndex}] #${seriesId} ${categoryColumnName} = ${categoryValue}, ${valueColumn} = ${value}`,\n // {\n // params,\n // },\n // );\n const menuOptions: ChartContextMenuOptions = {\n categoryColumn: categoryColumnName,\n categoryValue,\n valueColumn,\n value,\n };\n\n showContextMenu(event.event, \"chart\", menuOptions, {\n onOpenChange: (isOpen: boolean) => {\n console.log(`[useTableContextMenu] onOpenChange ${isOpen}`);\n },\n });\n },\n [categoryColumnName, showContextMenu],\n );\n\n return onContextMenu;\n};\n"],"names":[],"mappings":";;;AAmCO,MAAM,sBAAsB,CAAC;AAAA,EAClC;AACF,CAAiC,KAAA;AAC/B,EAAA,MAAM,kBAAkB,cAAe,EAAA;AAIvC,EAAA,MAAM,aAAgB,GAAA,WAAA;AAAA,IACpB,CAAC;AAAA;AAAA,MAEC,KAAA;AAAA,MACA,IAAM,EAAA,aAAA;AAAA;AAAA,MAEN,UAAY,EAAA,WAAA;AAAA,MACZ;AAAA;AAAA,KAEoC,KAAA;AACpC,MAAA,KAAA,CAAM,IAAK,EAAA;AAOX,MAAA,MAAM,WAAuC,GAAA;AAAA,QAC3C,cAAgB,EAAA,kBAAA;AAAA,QAChB,aAAA;AAAA,QACA,WAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAgB,eAAA,CAAA,KAAA,CAAM,KAAO,EAAA,OAAA,EAAS,WAAa,EAAA;AAAA,QACjD,YAAA,EAAc,CAAC,MAAoB,KAAA;AACjC,UAAQ,OAAA,CAAA,GAAA,CAAI,CAAsC,mCAAA,EAAA,MAAM,CAAE,CAAA,CAAA;AAAA;AAC5D,OACD,CAAA;AAAA,KACH;AAAA,IACA,CAAC,oBAAoB,eAAe;AAAA,GACtC;AAEA,EAAO,OAAA,aAAA;AACT;;;;"}
1
+ {"version":3,"file":"useChartContextMenu.js","sources":["../../../packages/vuu-chart/src/useChartContextMenu.ts"],"sourcesContent":["import { useContextMenu } from \"@vuu-ui/vuu-context-menu\";\nimport { DataSourceRow } from \"@vuu-ui/vuu-data-types\";\nimport { VuuRowDataItemType } from \"@vuu-ui/vuu-protocol-types\";\nimport { useCallback } from \"react\";\nimport { DataSourceValue } from \"./ChartSeries\";\n\nexport type ChartMenuLocation = \"canvas\" | \"series\";\n\ntype EChartContextMenuEvent = {\n event: PointerEvent;\n offsetX: number;\n offsetY: number;\n stop: () => void;\n type: \"contextmenu\";\n};\n\nexport type ChartContextMenuOptions = {\n categoryColumn: string;\n categoryValue: VuuRowDataItemType;\n row: DataSourceRow;\n valueColumn: string;\n value: VuuRowDataItemType;\n};\n\ntype EChartContextMenuHandlerParams = {\n data: DataSourceValue;\n dataIndex: number;\n event: EChartContextMenuEvent;\n name: string;\n seriesId: string;\n seriesName: string;\n value: DataSourceValue;\n};\n\ninterface ChartContextMenuHookProps {\n allowContextMenu?: boolean;\n categoryColumnName: string;\n}\n\nexport const useChartContextMenu = ({\n categoryColumnName,\n}: ChartContextMenuHookProps) => {\n const showContextMenu = useContextMenu();\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n //@ts-ignore\n const onContextMenu = useCallback<any>(\n ({\n data,\n event,\n name: categoryValue,\n seriesName: valueColumn,\n value: keyedValue,\n ...rest\n }: EChartContextMenuHandlerParams) => {\n event.stop();\n console.log({ rest });\n const { row, value } = data;\n\n const menuOptions: ChartContextMenuOptions = {\n categoryColumn: categoryColumnName,\n categoryValue,\n row,\n valueColumn,\n value,\n };\n\n showContextMenu(event.event, \"series\", menuOptions, {\n onOpenChange: (isOpen: boolean) => {\n console.log(`[useTableContextMenu] onOpenChange ${isOpen}`);\n },\n });\n },\n [categoryColumnName, showContextMenu],\n );\n\n return onContextMenu;\n};\n"],"names":[],"mappings":";;;AAuCO,MAAM,sBAAsB,CAAC;AAAA,EAClC;AACF,CAAiC,KAAA;AAC/B,EAAA,MAAM,kBAAkB,cAAe,EAAA;AAIvC,EAAA,MAAM,aAAgB,GAAA,WAAA;AAAA,IACpB,CAAC;AAAA,MACC,IAAA;AAAA,MACA,KAAA;AAAA,MACA,IAAM,EAAA,aAAA;AAAA,MACN,UAAY,EAAA,WAAA;AAAA,MACZ,KAAO,EAAA,UAAA;AAAA,MACP,GAAG;AAAA,KACiC,KAAA;AACpC,MAAA,KAAA,CAAM,IAAK,EAAA;AACX,MAAQ,OAAA,CAAA,GAAA,CAAI,EAAE,IAAA,EAAM,CAAA;AACpB,MAAM,MAAA,EAAE,GAAK,EAAA,KAAA,EAAU,GAAA,IAAA;AAEvB,MAAA,MAAM,WAAuC,GAAA;AAAA,QAC3C,cAAgB,EAAA,kBAAA;AAAA,QAChB,aAAA;AAAA,QACA,GAAA;AAAA,QACA,WAAA;AAAA,QACA;AAAA,OACF;AAEA,MAAgB,eAAA,CAAA,KAAA,CAAM,KAAO,EAAA,QAAA,EAAU,WAAa,EAAA;AAAA,QAClD,YAAA,EAAc,CAAC,MAAoB,KAAA;AACjC,UAAQ,OAAA,CAAA,GAAA,CAAI,CAAsC,mCAAA,EAAA,MAAM,CAAE,CAAA,CAAA;AAAA;AAC5D,OACD,CAAA;AAAA,KACH;AAAA,IACA,CAAC,oBAAoB,eAAe;AAAA,GACtC;AAEA,EAAO,OAAA,aAAA;AACT;;;;"}
@@ -1,23 +1,43 @@
1
1
  import { useState, useMemo } from 'react';
2
2
  import { ChartSeries } from './ChartSeries.js';
3
+ import { itemsChanged } from '@vuu-ui/vuu-utils';
3
4
 
5
+ const defaultPalette = [
6
+ "#4676bf",
7
+ "#ab6528",
8
+ "#9f55c2",
9
+ "#2a8285",
10
+ "#697694",
11
+ "#B0549d"
12
+ ];
4
13
  const useChartOptions = ({
5
14
  categoryColumnName,
6
15
  dataSource,
16
+ itemColorFunction,
17
+ palette = defaultPalette,
7
18
  seriesColumnNames
8
19
  }) => {
9
20
  const [, forceRender] = useState({});
10
21
  const chartSeries = useMemo(() => {
22
+ console.log("new ChartSeries");
11
23
  const cs = new ChartSeries({
12
- category: categoryColumnName,
13
- series: seriesColumnNames,
24
+ itemColorFunction,
14
25
  dataSource
15
26
  });
16
27
  cs.on("update", () => forceRender({}));
17
28
  return cs;
18
- }, [categoryColumnName, dataSource, seriesColumnNames]);
29
+ }, [dataSource, itemColorFunction]);
30
+ useMemo(() => {
31
+ if (categoryColumnName !== chartSeries.categoryColumn) {
32
+ chartSeries.categoryColumn = categoryColumnName;
33
+ }
34
+ if (itemsChanged(seriesColumnNames, chartSeries.seriesColumnNames)) {
35
+ chartSeries.seriesColumnNames = seriesColumnNames;
36
+ }
37
+ }, [categoryColumnName, chartSeries, seriesColumnNames]);
19
38
  return {
20
39
  animation: false,
40
+ color: palette,
21
41
  dataZoom: [
22
42
  {
23
43
  type: "slider",
@@ -31,6 +51,9 @@ const useChartOptions = ({
31
51
  right: 5
32
52
  },
33
53
  series: chartSeries.series,
54
+ tooltip: {
55
+ trigger: "axis"
56
+ },
34
57
  xAxis: {
35
58
  data: chartSeries.categories
36
59
  },
@@ -1 +1 @@
1
- {"version":3,"file":"useChartOptions.js","sources":["../../../packages/vuu-chart/src/useChartOptions.ts"],"sourcesContent":["import { type EChartsCoreOption } from \"echarts\";\nimport { useMemo, useState } from \"react\";\nimport { ChartSeries } from \"./ChartSeries\";\nimport { DataSource } from \"@vuu-ui/vuu-data-types\";\n\nexport interface ChartOptionsProps {\n categoryColumnName: string;\n dataSource: DataSource;\n seriesColumnNames: string[];\n}\n\nexport const useChartOptions = ({\n categoryColumnName,\n dataSource,\n seriesColumnNames,\n}: ChartOptionsProps) => {\n const [, forceRender] = useState({});\n\n const chartSeries = useMemo(() => {\n const cs = new ChartSeries({\n category: categoryColumnName,\n series: seriesColumnNames,\n dataSource,\n });\n cs.on(\"update\", () => forceRender({}));\n return cs;\n }, [categoryColumnName, dataSource, seriesColumnNames]);\n\n return {\n animation: false,\n dataZoom: [\n {\n type: \"slider\",\n start: 0,\n end: 100,\n },\n ],\n grid: {\n left: \"0\",\n bottom: 0,\n right: 5,\n },\n series: chartSeries.series,\n xAxis: {\n data: chartSeries.categories,\n },\n yAxis: {},\n } as EChartsCoreOption;\n};\n"],"names":[],"mappings":";;;AAWO,MAAM,kBAAkB,CAAC;AAAA,EAC9B,kBAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAyB,KAAA;AACvB,EAAA,MAAM,GAAG,WAAW,CAAI,GAAA,QAAA,CAAS,EAAE,CAAA;AAEnC,EAAM,MAAA,WAAA,GAAc,QAAQ,MAAM;AAChC,IAAM,MAAA,EAAA,GAAK,IAAI,WAAY,CAAA;AAAA,MACzB,QAAU,EAAA,kBAAA;AAAA,MACV,MAAQ,EAAA,iBAAA;AAAA,MACR;AAAA,KACD,CAAA;AACD,IAAA,EAAA,CAAG,GAAG,QAAU,EAAA,MAAM,WAAY,CAAA,EAAE,CAAC,CAAA;AACrC,IAAO,OAAA,EAAA;AAAA,GACN,EAAA,CAAC,kBAAoB,EAAA,UAAA,EAAY,iBAAiB,CAAC,CAAA;AAEtD,EAAO,OAAA;AAAA,IACL,SAAW,EAAA,KAAA;AAAA,IACX,QAAU,EAAA;AAAA,MACR;AAAA,QACE,IAAM,EAAA,QAAA;AAAA,QACN,KAAO,EAAA,CAAA;AAAA,QACP,GAAK,EAAA;AAAA;AACP,KACF;AAAA,IACA,IAAM,EAAA;AAAA,MACJ,IAAM,EAAA,GAAA;AAAA,MACN,MAAQ,EAAA,CAAA;AAAA,MACR,KAAO,EAAA;AAAA,KACT;AAAA,IACA,QAAQ,WAAY,CAAA,MAAA;AAAA,IACpB,KAAO,EAAA;AAAA,MACL,MAAM,WAAY,CAAA;AAAA,KACpB;AAAA,IACA,OAAO;AAAC,GACV;AACF;;;;"}
1
+ {"version":3,"file":"useChartOptions.js","sources":["../../../packages/vuu-chart/src/useChartOptions.ts"],"sourcesContent":["import { type EChartsCoreOption } from \"echarts\";\nimport { useMemo, useState } from \"react\";\nimport { ChartSeries, ItemColorFunction } from \"./ChartSeries\";\nimport { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport { itemsChanged } from \"@vuu-ui/vuu-utils\";\n\nconst defaultPalette = [\n \"#4676bf\",\n \"#ab6528\",\n \"#9f55c2\",\n \"#2a8285\",\n \"#697694\",\n \"#B0549d\",\n];\nexport interface ChartOptionsProps {\n categoryColumnName: string;\n dataSource: DataSource;\n itemColorFunction?: ItemColorFunction;\n palette?: string[];\n seriesColumnNames: string[];\n}\n\nexport const useChartOptions = ({\n categoryColumnName,\n dataSource,\n itemColorFunction,\n palette = defaultPalette,\n seriesColumnNames,\n}: ChartOptionsProps) => {\n const [, forceRender] = useState({});\n\n const chartSeries = useMemo(() => {\n console.log(\"new ChartSeries\");\n const cs = new ChartSeries({\n itemColorFunction,\n dataSource,\n });\n cs.on(\"update\", () => forceRender({}));\n return cs;\n }, [dataSource, itemColorFunction]);\n\n useMemo(() => {\n if (categoryColumnName !== chartSeries.categoryColumn) {\n chartSeries.categoryColumn = categoryColumnName;\n }\n if (itemsChanged(seriesColumnNames, chartSeries.seriesColumnNames)) {\n chartSeries.seriesColumnNames = seriesColumnNames;\n }\n }, [categoryColumnName, chartSeries, seriesColumnNames]);\n\n return {\n animation: false,\n color: palette,\n dataZoom: [\n {\n type: \"slider\",\n start: 0,\n end: 100,\n },\n ],\n grid: {\n left: \"0\",\n bottom: 0,\n right: 5,\n },\n series: chartSeries.series,\n tooltip: {\n trigger: \"axis\",\n },\n xAxis: {\n data: chartSeries.categories,\n },\n yAxis: {},\n } as EChartsCoreOption;\n};\n"],"names":[],"mappings":";;;;AAMA,MAAM,cAAiB,GAAA;AAAA,EACrB,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA;AACF,CAAA;AASO,MAAM,kBAAkB,CAAC;AAAA,EAC9B,kBAAA;AAAA,EACA,UAAA;AAAA,EACA,iBAAA;AAAA,EACA,OAAU,GAAA,cAAA;AAAA,EACV;AACF,CAAyB,KAAA;AACvB,EAAA,MAAM,GAAG,WAAW,CAAI,GAAA,QAAA,CAAS,EAAE,CAAA;AAEnC,EAAM,MAAA,WAAA,GAAc,QAAQ,MAAM;AAChC,IAAA,OAAA,CAAQ,IAAI,iBAAiB,CAAA;AAC7B,IAAM,MAAA,EAAA,GAAK,IAAI,WAAY,CAAA;AAAA,MACzB,iBAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,EAAA,CAAG,GAAG,QAAU,EAAA,MAAM,WAAY,CAAA,EAAE,CAAC,CAAA;AACrC,IAAO,OAAA,EAAA;AAAA,GACN,EAAA,CAAC,UAAY,EAAA,iBAAiB,CAAC,CAAA;AAElC,EAAA,OAAA,CAAQ,MAAM;AACZ,IAAI,IAAA,kBAAA,KAAuB,YAAY,cAAgB,EAAA;AACrD,MAAA,WAAA,CAAY,cAAiB,GAAA,kBAAA;AAAA;AAE/B,IAAA,IAAI,YAAa,CAAA,iBAAA,EAAmB,WAAY,CAAA,iBAAiB,CAAG,EAAA;AAClE,MAAA,WAAA,CAAY,iBAAoB,GAAA,iBAAA;AAAA;AAClC,GACC,EAAA,CAAC,kBAAoB,EAAA,WAAA,EAAa,iBAAiB,CAAC,CAAA;AAEvD,EAAO,OAAA;AAAA,IACL,SAAW,EAAA,KAAA;AAAA,IACX,KAAO,EAAA,OAAA;AAAA,IACP,QAAU,EAAA;AAAA,MACR;AAAA,QACE,IAAM,EAAA,QAAA;AAAA,QACN,KAAO,EAAA,CAAA;AAAA,QACP,GAAK,EAAA;AAAA;AACP,KACF;AAAA,IACA,IAAM,EAAA;AAAA,MACJ,IAAM,EAAA,GAAA;AAAA,MACN,MAAQ,EAAA,CAAA;AAAA,MACR,KAAO,EAAA;AAAA,KACT;AAAA,IACA,QAAQ,WAAY,CAAA,MAAA;AAAA,IACpB,OAAS,EAAA;AAAA,MACP,OAAS,EAAA;AAAA,KACX;AAAA,IACA,KAAO,EAAA;AAAA,MACL,MAAM,WAAY,CAAA;AAAA,KACpB;AAAA,IACA,OAAO;AAAC,GACV;AACF;;;;"}
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
- "version": "2.1.0-alpha.1",
2
+ "version": "2.1.0-alpha.10",
3
3
  "description": "support for apache echarts using vuu data",
4
4
  "license": "Apache-2.0",
5
5
  "devDependencies": {
6
- "@vuu-ui/vuu-data-types": "2.1.0-alpha.1",
7
- "@vuu-ui/vuu-protocol-types": "2.1.0-alpha.1"
6
+ "@vuu-ui/vuu-data-types": "2.1.0-alpha.10",
7
+ "@vuu-ui/vuu-protocol-types": "2.1.0-alpha.10"
8
8
  },
9
9
  "dependencies": {
10
10
  "@salt-ds/styles": "0.2.1",
11
11
  "@salt-ds/window": "0.1.1",
12
- "@vuu-ui/vuu-context-menu": "2.1.0-alpha.1",
13
- "@vuu-ui/vuu-utils": "2.1.0-alpha.1"
12
+ "@vuu-ui/vuu-context-menu": "2.1.0-alpha.10",
13
+ "@vuu-ui/vuu-utils": "2.1.0-alpha.10"
14
14
  },
15
15
  "peerDependencies": {
16
16
  "echarts": "6.0.0",
package/types/Chart.d.ts CHANGED
@@ -1,15 +1,18 @@
1
1
  import { HTMLAttributes } from "react";
2
2
  import { ChartOptionsProps } from "./useChartOptions";
3
+ import { ItemColorFunction } from "./ChartSeries";
3
4
  type OptionSettings = {
4
5
  notMerge: boolean;
5
6
  };
6
7
  type ChartSettings = {
8
+ renderer: "svg" | "canvas";
7
9
  useCoarsePointer: boolean;
8
10
  };
9
11
  export interface ChartProps extends ChartOptionsProps, HTMLAttributes<HTMLDivElement> {
10
12
  chartSettings?: ChartSettings;
11
- events?: unknown;
13
+ itemColorFunction?: ItemColorFunction;
12
14
  optionSettings?: OptionSettings;
15
+ palette?: string[];
13
16
  }
14
- export declare const Chart: ({ categoryColumnName, chartSettings, dataSource, optionSettings, style, events, seriesColumnNames, ...htmlAttributes }: ChartProps) => import("react/jsx-runtime").JSX.Element;
17
+ export declare const Chart: ({ categoryColumnName, chartSettings, dataSource, itemColorFunction, optionSettings, palette, style, seriesColumnNames, ...htmlAttributes }: ChartProps) => import("react/jsx-runtime").JSX.Element;
15
18
  export {};
@@ -1,32 +1,48 @@
1
- import { DataSource, DataSourceSubscribeCallback } from "@vuu-ui/vuu-data-types";
1
+ import { DataSource, DataSourceRow, DataSourceSubscribeCallback } from "@vuu-ui/vuu-data-types";
2
+ import { VuuRowDataItemType } from "@vuu-ui/vuu-protocol-types";
2
3
  import { EventEmitter } from "@vuu-ui/vuu-utils";
3
4
  type Series = {
4
5
  id: string;
5
6
  name: string;
6
7
  label: string;
7
- data: number[];
8
+ data: DataSourceValue<number>[];
9
+ lineStyle: {
10
+ width: number;
11
+ };
12
+ itemStyle: {
13
+ color: string | ItemColorFunction;
14
+ };
15
+ symbol: "emptyCircle" | "circle";
8
16
  type: "line";
9
17
  };
18
+ export type ItemColorFunction = (params: {
19
+ color: string;
20
+ data: DataSourceValue;
21
+ dataIndex: number;
22
+ name: string;
23
+ seriesName: string;
24
+ }) => string;
25
+ export type DataSourceValue<T extends VuuRowDataItemType = number> = {
26
+ key: string;
27
+ readonly row: DataSourceRow;
28
+ value: T;
29
+ };
10
30
  export type ChartEvents = {
11
31
  update: () => void;
12
32
  };
13
33
  export interface ChartSeriesConstructorProps {
14
34
  dataSource: DataSource;
15
- /**
16
- * The column name of the column that defines our category axis.
17
- * By default, these are the x axis values.
18
- */
19
- category: string;
20
- /**
21
- * The column names of the columns that define our data.
22
- * By default, these are the y axis values.
23
- */
24
- series: string[];
35
+ itemColorFunction?: ItemColorFunction;
25
36
  }
26
37
  export declare class ChartSeries extends EventEmitter<ChartEvents> {
27
38
  #private;
28
39
  handleData: DataSourceSubscribeCallback;
29
- constructor({ category, dataSource, series }: ChartSeriesConstructorProps);
40
+ buildCategoriesAndSeries(): void;
41
+ constructor({ dataSource, itemColorFunction }: ChartSeriesConstructorProps);
42
+ get categoryColumn(): string;
43
+ set categoryColumn(categoryColumn: string);
44
+ get seriesColumnNames(): string[];
45
+ set seriesColumnNames(seriesColumnNames: string[]);
30
46
  get categories(): string[];
31
47
  get series(): Series[];
32
48
  }
@@ -0,0 +1,23 @@
1
+ import { DataSourceRow } from "@vuu-ui/vuu-data-types";
2
+ import { VuuRange } from "@vuu-ui/vuu-protocol-types";
3
+ import { WindowRange } from "@vuu-ui/vuu-utils";
4
+ export declare class MovingDataRowWindow {
5
+ #private;
6
+ data: DataSourceRow[];
7
+ rowCount: number;
8
+ constructor({ from, to }: VuuRange);
9
+ setRowCount: (rowCount: number) => void;
10
+ add(data: DataSourceRow): void;
11
+ getAtIndex(index: number): DataSourceRow | undefined;
12
+ getByKey(key: string): DataSourceRow | undefined;
13
+ isWithinRange(index: number): boolean;
14
+ setRange({ from, to }: VuuRange): void;
15
+ get hasData(): boolean;
16
+ /**
17
+ * This will throw if there is no data. Check `hasData` first
18
+ * to guard against this, if not certain.
19
+ */
20
+ get firstRow(): DataSourceRow;
21
+ get range(): WindowRange;
22
+ get hasAllRowsWithinRange(): boolean;
23
+ }
package/types/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { Chart, type ChartProps } from "./Chart";
2
- export { ChartSeries } from "./ChartSeries";
3
- export type { ChartContextMenuOptions } from "./useChartContextMenu";
2
+ export { ChartSeries, type DataSourceValue, type ItemColorFunction, } from "./ChartSeries";
3
+ export type { ChartContextMenuOptions, ChartMenuLocation, } from "./useChartContextMenu";
@@ -1,15 +1,16 @@
1
- import { DataSource } from "@vuu-ui/vuu-data-types";
1
+ import { DataSourceRow } from "@vuu-ui/vuu-data-types";
2
2
  import { VuuRowDataItemType } from "@vuu-ui/vuu-protocol-types";
3
+ export type ChartMenuLocation = "canvas" | "series";
3
4
  export type ChartContextMenuOptions = {
4
5
  categoryColumn: string;
5
6
  categoryValue: VuuRowDataItemType;
7
+ row: DataSourceRow;
6
8
  valueColumn: string;
7
9
  value: VuuRowDataItemType;
8
10
  };
9
11
  interface ChartContextMenuHookProps {
10
12
  allowContextMenu?: boolean;
11
13
  categoryColumnName: string;
12
- dataSource: DataSource;
13
14
  }
14
15
  export declare const useChartContextMenu: ({ categoryColumnName, }: ChartContextMenuHookProps) => any;
15
16
  export {};
@@ -1,8 +1,11 @@
1
1
  import { type EChartsCoreOption } from "echarts";
2
+ import { ItemColorFunction } from "./ChartSeries";
2
3
  import { DataSource } from "@vuu-ui/vuu-data-types";
3
4
  export interface ChartOptionsProps {
4
5
  categoryColumnName: string;
5
6
  dataSource: DataSource;
7
+ itemColorFunction?: ItemColorFunction;
8
+ palette?: string[];
6
9
  seriesColumnNames: string[];
7
10
  }
8
- export declare const useChartOptions: ({ categoryColumnName, dataSource, seriesColumnNames, }: ChartOptionsProps) => EChartsCoreOption;
11
+ export declare const useChartOptions: ({ categoryColumnName, dataSource, itemColorFunction, palette, seriesColumnNames, }: ChartOptionsProps) => EChartsCoreOption;