website: redesign part 23

This commit is contained in:
nym21
2026-06-07 16:46:53 +02:00
parent 33cc13708a
commit 36cfe49b20
15 changed files with 328 additions and 73 deletions
+1
View File
@@ -103,6 +103,7 @@
<link rel="stylesheet" href="/learn/charts/controls/style.css" /> <link rel="stylesheet" href="/learn/charts/controls/style.css" />
<link rel="stylesheet" href="/learn/charts/legend/style.css" /> <link rel="stylesheet" href="/learn/charts/legend/style.css" />
<link rel="stylesheet" href="/learn/charts/scrubber/style.css" /> <link rel="stylesheet" href="/learn/charts/scrubber/style.css" />
<link rel="stylesheet" href="/learn/charts/area/style.css" />
<link rel="stylesheet" href="/learn/charts/bar/style.css" /> <link rel="stylesheet" href="/learn/charts/bar/style.css" />
<link rel="stylesheet" href="/learn/charts/line/style.css" /> <link rel="stylesheet" href="/learn/charts/line/style.css" />
<link rel="stylesheet" href="/learn/charts/dots/style.css" /> <link rel="stylesheet" href="/learn/charts/dots/style.css" />
+62
View File
@@ -0,0 +1,62 @@
import { createAreaPathData, createLinePathData } from "../path.js";
import { appendSeriesPath } from "../series-path.js";
import { createOrderedIndexes } from "../order.js";
import { createLineSeries } from "../line/series.js";
/**
* @param {number} height
* @param {{ date: Date, value: number, x: number, y: number }[]} points
*/
function createAreaPoints(height, points) {
return points.map((point) => ({
...point,
y0: height,
y1: point.y,
}));
}
/**
* @param {SVGGElement} group
* @param {LoadedSeries[]} loadedSeries
* @param {number} height
* @param {SeriesHighlight} highlight
* @param {import("../scale.js").ChartScale} scale
* @param {import("../order.js").ChartOrder} order
*/
export function renderAreaPlot(
group,
loadedSeries,
height,
highlight,
scale,
order,
) {
const plottedSeries = createLineSeries(loadedSeries, height, scale);
const indexes = createOrderedIndexes(plottedSeries.length, order);
for (const index of indexes) {
const { color, points } = plottedSeries[index];
appendSeriesPath({
group,
highlight,
index,
chart: "area",
color,
d: createAreaPathData(createAreaPoints(height, points)),
});
appendSeriesPath({
group,
highlight,
index,
chart: "line",
color,
d: createLinePathData(points),
});
}
return plottedSeries;
}
/** @typedef {import("../highlight.js").SeriesHighlight} SeriesHighlight */
/** @typedef {import("../index.js").LoadedSeries} LoadedSeries */
+9
View File
@@ -0,0 +1,9 @@
main.learn {
figure[data-chart="series"] {
path[data-chart="area"] {
fill: var(--color, var(--orange));
fill-opacity: 0.5;
stroke: none;
}
}
}
+3 -3
View File
@@ -35,21 +35,21 @@ function createBarPathData(points, width) {
* @param {LoadedSeries[]} loadedSeries * @param {LoadedSeries[]} loadedSeries
* @param {number} height * @param {number} height
* @param {SeriesHighlight} highlight * @param {SeriesHighlight} highlight
* @param {{ reversed: boolean }} options
* @param {import("../scale.js").ChartScale} scale * @param {import("../scale.js").ChartScale} scale
* @param {import("../order.js").ChartOrder} order
*/ */
export function renderBarPlot( export function renderBarPlot(
group, group,
loadedSeries, loadedSeries,
height, height,
highlight, highlight,
options,
scale, scale,
order,
) { ) {
const { lineIndexes, plottedSeries, stackIndexes } = createStackedSeries( const { lineIndexes, plottedSeries, stackIndexes } = createStackedSeries(
loadedSeries, loadedSeries,
height, height,
options.reversed, order,
scale, scale,
); );
+14 -3
View File
@@ -1,5 +1,6 @@
import { formatCoordinate } from "../path.js"; import { formatCoordinate } from "../path.js";
import { appendSeriesPath } from "../series-path.js"; import { appendSeriesPath } from "../series-path.js";
import { createOrderedIndexes } from "../order.js";
import { createLineSeries } from "../line/series.js"; import { createLineSeries } from "../line/series.js";
const radius = 1; const radius = 1;
@@ -22,11 +23,21 @@ function createDotsPathData(points) {
* @param {number} height * @param {number} height
* @param {SeriesHighlight} highlight * @param {SeriesHighlight} highlight
* @param {import("../scale.js").ChartScale} scale * @param {import("../scale.js").ChartScale} scale
* @param {import("../order.js").ChartOrder} order
*/ */
export function renderDotsPlot(group, loadedSeries, height, highlight, scale) { export function renderDotsPlot(
group,
loadedSeries,
height,
highlight,
scale,
order,
) {
const plottedSeries = createLineSeries(loadedSeries, height, scale); const plottedSeries = createLineSeries(loadedSeries, height, scale);
const indexes = createOrderedIndexes(plottedSeries.length, order);
plottedSeries.forEach(({ color, points }, index) => { for (const index of indexes) {
const { color, points } = plottedSeries[index];
appendSeriesPath({ appendSeriesPath({
group, group,
highlight, highlight,
@@ -35,7 +46,7 @@ export function renderDotsPlot(group, loadedSeries, height, highlight, scale) {
color, color,
d: createDotsPathData(points), d: createDotsPathData(points),
}); });
}); }
return plottedSeries; return plottedSeries;
} }
+73 -11
View File
@@ -1,6 +1,11 @@
import { createFullscreenButton } from "./fullscreen.js"; import { createFullscreenButton } from "./fullscreen.js";
import { onChartVisibility } from "./intersection.js"; import { onChartVisibility } from "./intersection.js";
import { createLegend } from "./legend/index.js"; import { createLegend } from "./legend/index.js";
import {
createOrderControl,
getDefaultOrder,
saveOrder,
} from "./order.js";
import { createChartRenderer } from "./renderer.js"; import { createChartRenderer } from "./renderer.js";
import { import {
createScaleControl, createScaleControl,
@@ -20,6 +25,36 @@ import {
} from "./views.js"; } from "./views.js";
import { FALLBACK_VIEWBOX_HEIGHT, VIEWBOX_WIDTH } from "./viewbox.js"; import { FALLBACK_VIEWBOX_HEIGHT, VIEWBOX_WIDTH } from "./viewbox.js";
/**
* @template {string} T
* @param {Object} args
* @param {T} args.currentValue
* @param {(currentValue: T, onChange: (value: T) => void) => HTMLFieldSetElement} args.createControl
* @param {(chartKey: string, value: T) => void} args.save
* @param {string} args.chartKey
* @param {HTMLElement} args.figure
* @param {string} args.dataKey
* @param {(value: T) => void} args.setValue
* @param {() => void} args.render
*/
function createChartSettingControl({
currentValue,
createControl,
save,
chartKey,
figure,
dataKey,
setValue,
render,
}) {
return createControl(currentValue, (value) => {
setValue(value);
save(chartKey, value);
figure.dataset[dataKey] = value;
render();
});
}
/** @param {Chart} chart */ /** @param {Chart} chart */
export function createChart(chart) { export function createChart(chart) {
const figure = document.createElement("figure"); const figure = document.createElement("figure");
@@ -33,6 +68,7 @@ export function createChart(chart) {
let currentTimeframe = getDefaultTimeframe(chartKey); let currentTimeframe = getDefaultTimeframe(chartKey);
let currentView = getDefaultView(chartKey, chart.defaultType); let currentView = getDefaultView(chartKey, chart.defaultType);
let currentScale = getDefaultScale(chartKey, chart.defaultScale); let currentScale = getDefaultScale(chartKey, chart.defaultScale);
let currentOrder = getDefaultOrder(chartKey);
const { legend, menu, items, readout } = createLegend(chart); const { legend, menu, items, readout } = createLegend(chart);
figure.dataset.chart = "series"; figure.dataset.chart = "series";
@@ -40,6 +76,7 @@ export function createChart(chart) {
figure.dataset.timeframe = currentTimeframe; figure.dataset.timeframe = currentTimeframe;
figure.dataset.view = currentView; figure.dataset.view = currentView;
figure.dataset.scale = currentScale; figure.dataset.scale = currentScale;
figure.dataset.order = currentOrder;
svg.setAttribute( svg.setAttribute(
"viewBox", "viewBox",
`0 0 ${VIEWBOX_WIDTH} ${FALLBACK_VIEWBOX_HEIGHT}`, `0 0 ${VIEWBOX_WIDTH} ${FALLBACK_VIEWBOX_HEIGHT}`,
@@ -59,19 +96,44 @@ export function createChart(chart) {
chart, chart,
getView: () => currentView, getView: () => currentView,
getScale: () => currentScale, getScale: () => currentScale,
getOrder: () => currentOrder,
getTimeframe: () => currentTimeframe, getTimeframe: () => currentTimeframe,
}); });
const viewControl = createViewControl(currentView, (view) => { const viewControl = createChartSettingControl({
currentView = view; currentValue: currentView,
saveView(chartKey, view); createControl: createViewControl,
figure.dataset.view = view; save: saveView,
renderer.renderCurrent(); chartKey,
figure,
dataKey: "view",
setValue: (view) => {
currentView = view;
},
render: renderer.renderCurrent,
}); });
const scaleControl = createScaleControl(currentScale, (scale) => { const scaleControl = createChartSettingControl({
currentScale = scale; currentValue: currentScale,
saveScale(chartKey, scale); createControl: createScaleControl,
figure.dataset.scale = scale; save: saveScale,
renderer.renderCurrent(); chartKey,
figure,
dataKey: "scale",
setValue: (scale) => {
currentScale = scale;
},
render: renderer.renderCurrent,
});
const orderControl = createChartSettingControl({
currentValue: currentOrder,
createControl: createOrderControl,
save: saveOrder,
chartKey,
figure,
dataKey: "order",
setValue: (order) => {
currentOrder = order;
},
render: renderer.renderCurrent,
}); });
const timeframeControl = createTimeframeControl( const timeframeControl = createTimeframeControl(
currentTimeframe, currentTimeframe,
@@ -82,7 +144,7 @@ export function createChart(chart) {
void renderer.loadCurrent(); void renderer.loadCurrent();
}, },
); );
chartControls.append(viewControl, scaleControl); chartControls.append(viewControl, scaleControl, orderControl);
timeControls.append(timeframeControl, createFullscreenButton(figure)); timeControls.append(timeframeControl, createFullscreenButton(figure));
controls.append(chartControls, timeControls); controls.append(chartControls, timeControls);
plot.append(svg, status); plot.append(svg, status);
+14 -3
View File
@@ -1,5 +1,6 @@
import { createLinePathData } from "../path.js"; import { createLinePathData } from "../path.js";
import { appendSeriesPath } from "../series-path.js"; import { appendSeriesPath } from "../series-path.js";
import { createOrderedIndexes } from "../order.js";
import { createLineSeries } from "./series.js"; import { createLineSeries } from "./series.js";
/** /**
@@ -8,11 +9,21 @@ import { createLineSeries } from "./series.js";
* @param {number} height * @param {number} height
* @param {SeriesHighlight} highlight * @param {SeriesHighlight} highlight
* @param {import("../scale.js").ChartScale} scale * @param {import("../scale.js").ChartScale} scale
* @param {import("../order.js").ChartOrder} order
*/ */
export function renderLinePlot(group, loadedSeries, height, highlight, scale) { export function renderLinePlot(
group,
loadedSeries,
height,
highlight,
scale,
order,
) {
const plottedSeries = createLineSeries(loadedSeries, height, scale); const plottedSeries = createLineSeries(loadedSeries, height, scale);
const indexes = createOrderedIndexes(plottedSeries.length, order);
plottedSeries.forEach(({ color, points }, index) => { for (const index of indexes) {
const { color, points } = plottedSeries[index];
appendSeriesPath({ appendSeriesPath({
group, group,
highlight, highlight,
@@ -21,7 +32,7 @@ export function renderLinePlot(group, loadedSeries, height, highlight, scale) {
color, color,
d: createLinePathData(points), d: createLinePathData(points),
}); });
}); }
return plottedSeries; return plottedSeries;
} }
+4 -8
View File
@@ -1,21 +1,17 @@
import { VIEWBOX_WIDTH } from "../viewbox.js"; import { VIEWBOX_WIDTH } from "../viewbox.js";
import { scaleY } from "../scale.js"; import { createBounds, includeBoundValue, scaleY } from "../scale.js";
/** @param {LoadedSeries[]} series */ /** @param {LoadedSeries[]} series */
function createValueBounds(series) { function createValueBounds(series) {
let min = Infinity; const bounds = createBounds();
let max = -Infinity;
let minPositive = Infinity;
for (const { entries } of series) { for (const { entries } of series) {
for (const { value } of entries) { for (const { value } of entries) {
min = Math.min(min, value); includeBoundValue(bounds, value);
max = Math.max(max, value);
if (value > 0) minPositive = Math.min(minPositive, value);
} }
} }
return { min, max, minPositive }; return bounds;
} }
/** /**
+59
View File
@@ -0,0 +1,59 @@
import { createChartSetting } from "./setting.js";
const orders = /** @type {const} */ ([
{ value: "ascending", label: "Asc" },
{ value: "descending", label: "Dsc" },
]);
const defaultOrder = "ascending";
const setting = createChartSetting({
storageKey: "order",
legend: "Order",
options: orders,
defaultValue: defaultOrder,
});
/** @param {string} chartKey */
export function getDefaultOrder(chartKey) {
return setting.get(chartKey);
}
/**
* @param {string} chartKey
* @param {ChartOrder} order
*/
export function saveOrder(chartKey, order) {
setting.save(chartKey, order);
}
/**
* @param {ChartOrder} currentOrder
* @param {(order: ChartOrder) => void} onChange
*/
export function createOrderControl(currentOrder, onChange) {
return setting.create(currentOrder, onChange);
}
/**
* @param {number[]} indexes
* @param {ChartOrder} order
*/
export function orderIndexes(indexes, order) {
const orderedIndexes = [...indexes];
if (order === "descending") orderedIndexes.reverse();
return orderedIndexes;
}
/**
* @param {number} length
* @param {ChartOrder} order
*/
export function createOrderedIndexes(length, order) {
return orderIndexes(
Array.from({ length }, (_, index) => index),
order,
);
}
/** @typedef {(typeof orders)[number]["value"]} ChartOrder */
+35 -9
View File
@@ -1,3 +1,4 @@
import { renderAreaPlot } from "./area/index.js";
import { renderBarPlot } from "./bar/index.js"; import { renderBarPlot } from "./bar/index.js";
import { renderDotsPlot } from "./dots/index.js"; import { renderDotsPlot } from "./dots/index.js";
import { renderLinePlot } from "./line/index.js"; import { renderLinePlot } from "./line/index.js";
@@ -10,36 +11,61 @@ import { renderStackedPlot } from "./stacked/index.js";
* @param {number} height * @param {number} height
* @param {SeriesHighlight} highlight * @param {SeriesHighlight} highlight
* @param {ChartScale} scale * @param {ChartScale} scale
* @param {ChartOrder} order
*/ */
export function renderPlot(view, group, loadedSeries, height, highlight, scale) { export function renderPlot(
view,
group,
loadedSeries,
height,
highlight,
scale,
order,
) {
switch (view) { switch (view) {
case "line": case "line":
return renderLinePlot(group, loadedSeries, height, highlight, scale); return renderLinePlot(
case "bar":
case "bar-reversed":
return renderBarPlot(
group, group,
loadedSeries, loadedSeries,
height, height,
highlight, highlight,
{ reversed: view === "bar-reversed" },
scale, scale,
order,
); );
case "area":
return renderAreaPlot(
group,
loadedSeries,
height,
highlight,
scale,
order,
);
case "bar":
return renderBarPlot(group, loadedSeries, height, highlight, scale, order);
case "dots": case "dots":
return renderDotsPlot(group, loadedSeries, height, highlight, scale); return renderDotsPlot(
default: group,
loadedSeries,
height,
highlight,
scale,
order,
);
case "stacked":
return renderStackedPlot( return renderStackedPlot(
group, group,
loadedSeries, loadedSeries,
height, height,
highlight, highlight,
{ reversed: view === "stacked-reversed" },
scale, scale,
order,
); );
} }
} }
/** @typedef {import("./highlight.js").SeriesHighlight} SeriesHighlight */ /** @typedef {import("./highlight.js").SeriesHighlight} SeriesHighlight */
/** @typedef {import("./index.js").LoadedSeries} LoadedSeries */ /** @typedef {import("./index.js").LoadedSeries} LoadedSeries */
/** @typedef {import("./order.js").ChartOrder} ChartOrder */
/** @typedef {import("./scale.js").ChartScale} ChartScale */ /** @typedef {import("./scale.js").ChartScale} ChartScale */
/** @typedef {import("./views.js").ChartView} ChartView */ /** @typedef {import("./views.js").ChartView} ChartView */
+4
View File
@@ -15,6 +15,7 @@ import { getViewBoxHeight, VIEWBOX_WIDTH } from "./viewbox.js";
* @param {Chart} args.chart * @param {Chart} args.chart
* @param {() => ChartView} args.getView * @param {() => ChartView} args.getView
* @param {() => ChartScale} args.getScale * @param {() => ChartScale} args.getScale
* @param {() => ChartOrder} args.getOrder
* @param {() => TimeframeValue} args.getTimeframe * @param {() => TimeframeValue} args.getTimeframe
*/ */
export function createChartRenderer({ export function createChartRenderer({
@@ -26,6 +27,7 @@ export function createChartRenderer({
chart, chart,
getView, getView,
getScale, getScale,
getOrder,
getTimeframe, getTimeframe,
}) { }) {
const group = createSvgElement("g"); const group = createSvgElement("g");
@@ -68,6 +70,7 @@ export function createChartRenderer({
height, height,
highlight, highlight,
getScale(), getScale(),
getOrder(),
), ),
height, height,
); );
@@ -132,6 +135,7 @@ export function createChartRenderer({
/** @typedef {import("./index.js").Chart} Chart */ /** @typedef {import("./index.js").Chart} Chart */
/** @typedef {import("./index.js").LoadedSeries} LoadedSeries */ /** @typedef {import("./index.js").LoadedSeries} LoadedSeries */
/** @typedef {import("./legend/index.js").Readout} Readout */ /** @typedef {import("./legend/index.js").Readout} Readout */
/** @typedef {import("./order.js").ChartOrder} ChartOrder */
/** @typedef {import("./scale.js").ChartScale} ChartScale */ /** @typedef {import("./scale.js").ChartScale} ChartScale */
/** @typedef {import("./timeframes.js").TimeframeValue} TimeframeValue */ /** @typedef {import("./timeframes.js").TimeframeValue} TimeframeValue */
/** @typedef {import("./views.js").ChartView} ChartView */ /** @typedef {import("./views.js").ChartView} ChartView */
+18
View File
@@ -36,6 +36,24 @@ export function createScaleControl(currentScale, onChange) {
return setting.create(currentScale, onChange); return setting.create(currentScale, onChange);
} }
export function createBounds() {
return {
min: Infinity,
max: -Infinity,
minPositive: Infinity,
};
}
/**
* @param {ScaleBounds} bounds
* @param {number} value
*/
export function includeBoundValue(bounds, value) {
bounds.min = Math.min(bounds.min, value);
bounds.max = Math.max(bounds.max, value);
if (value > 0) bounds.minPositive = Math.min(bounds.minPositive, value);
}
/** /**
* @param {number} value * @param {number} value
* @param {ScaleBounds} bounds * @param {ScaleBounds} bounds
+3 -3
View File
@@ -7,21 +7,21 @@ import { createStackedSeries } from "./series.js";
* @param {LoadedSeries[]} loadedSeries * @param {LoadedSeries[]} loadedSeries
* @param {number} height * @param {number} height
* @param {SeriesHighlight} highlight * @param {SeriesHighlight} highlight
* @param {{ reversed: boolean }} options
* @param {import("../scale.js").ChartScale} scale * @param {import("../scale.js").ChartScale} scale
* @param {import("../order.js").ChartOrder} order
*/ */
export function renderStackedPlot( export function renderStackedPlot(
group, group,
loadedSeries, loadedSeries,
height, height,
highlight, highlight,
options,
scale, scale,
order,
) { ) {
const { lineIndexes, plottedSeries, stackIndexes } = createStackedSeries( const { lineIndexes, plottedSeries, stackIndexes } = createStackedSeries(
loadedSeries, loadedSeries,
height, height,
options.reversed, order,
scale, scale,
); );
+25 -27
View File
@@ -1,42 +1,40 @@
import { VIEWBOX_WIDTH } from "../viewbox.js"; import { VIEWBOX_WIDTH } from "../viewbox.js";
import { scaleY } from "../scale.js"; import { orderIndexes } from "../order.js";
import { createBounds, includeBoundValue, scaleY } from "../scale.js";
/** /**
* @param {LoadedSeries[]} series * @param {LoadedSeries[]} series
* @param {number[]} stackIndexes * @param {number[]} stackOrder
* @param {number[]} lineIndexes * @param {number[]} lineIndexes
*/ */
function createStackBounds(series, stackIndexes, lineIndexes) { function createStackBounds(series, stackOrder, lineIndexes) {
const bounds = createBounds();
const length = series[0].entries.length; const length = series[0].entries.length;
let min = 0;
let max = 0; includeBoundValue(bounds, 0);
let minPositive = Infinity;
for (let index = 0; index < length; index += 1) { for (let index = 0; index < length; index += 1) {
let negative = 0; let negative = 0;
let positive = 0; let positive = 0;
for (const seriesIndex of stackIndexes) { for (const seriesIndex of stackOrder) {
const value = series[seriesIndex].entries[index].value; const value = series[seriesIndex].entries[index].value;
const end = value < 0 ? negative + value : positive + value;
if (value < 0) negative += value; if (value < 0) negative = end;
else positive += value; else positive = end;
includeBoundValue(bounds, end);
} }
min = Math.min(min, negative);
max = Math.max(max, positive);
if (positive > 0) minPositive = Math.min(minPositive, positive);
for (const seriesIndex of lineIndexes) { for (const seriesIndex of lineIndexes) {
const value = series[seriesIndex].entries[index].value; const value = series[seriesIndex].entries[index].value;
min = Math.min(min, value); includeBoundValue(bounds, value);
max = Math.max(max, value);
if (value > 0) minPositive = Math.min(minPositive, value);
} }
} }
return { min, max, minPositive }; return bounds;
} }
/** @returns {StackedPoint[]} */ /** @returns {StackedPoint[]} */
@@ -47,36 +45,36 @@ function createStackedPoints() {
/** /**
* @param {LoadedSeries[]} loadedSeries * @param {LoadedSeries[]} loadedSeries
* @param {number} height * @param {number} height
* @param {boolean} reversed * @param {import("../order.js").ChartOrder} order
* @param {import("../scale.js").ChartScale} scale * @param {import("../scale.js").ChartScale} scale
*/ */
export function createStackedSeries(loadedSeries, height, reversed, scale) { export function createStackedSeries(loadedSeries, height, order, scale) {
const indexes = loadedSeries.map((_, index) => index); const indexes = loadedSeries.map((_, index) => index);
const lineIndexes = indexes.filter( const lineIndexes = orderIndexes(
(index) => loadedSeries[index].series.role === "line", indexes.filter((index) => loadedSeries[index].series.role === "line"),
order,
); );
const stackIndexes = indexes.filter( const stackIndexes = orderIndexes(
(index) => loadedSeries[index].series.role !== "line", indexes.filter((index) => loadedSeries[index].series.role !== "line"),
order,
); );
const bounds = createStackBounds(loadedSeries, stackIndexes, lineIndexes);
const length = loadedSeries[0].entries.length; const length = loadedSeries[0].entries.length;
const xScale = VIEWBOX_WIDTH / (length - 1); const xScale = VIEWBOX_WIDTH / (length - 1);
const order = [...stackIndexes];
const plottedSeries = loadedSeries.map(({ series, color }) => ({ const plottedSeries = loadedSeries.map(({ series, color }) => ({
series, series,
color, color,
points: createStackedPoints(), points: createStackedPoints(),
})); }));
if (reversed) order.reverse(); const bounds = createStackBounds(loadedSeries, stackIndexes, lineIndexes);
for (let index = 0; index < length; index += 1) { for (let index = 0; index < length; index += 1) {
let negative = 0; let negative = 0;
let positive = 0; let positive = 0;
const x = index * xScale; const x = index * xScale;
for (const seriesIndex of order) { for (const seriesIndex of stackIndexes) {
const { date, value } = loadedSeries[seriesIndex].entries[index]; const { date, value } = loadedSeries[seriesIndex].entries[index];
const start = value < 0 ? negative : positive; const start = value < 0 ? negative : positive;
const end = start + value; const end = start + value;
+4 -6
View File
@@ -2,18 +2,16 @@ import { createChartSetting } from "./setting.js";
export const viewTypes = /** @type {const} */ ({ export const viewTypes = /** @type {const} */ ({
line: "line", line: "line",
area: "area",
stacked: "stacked", stacked: "stacked",
stackedReversed: "stacked-reversed",
bar: "bar", bar: "bar",
barReversed: "bar-reversed",
dots: "dots", dots: "dots",
}); });
const views = /** @type {const} */ ([ const views = /** @type {const} */ ([
{ value: viewTypes.line, label: "Line" }, { value: viewTypes.line, label: "Line" },
{ value: viewTypes.stacked, label: "Stack↑" }, { value: viewTypes.area, label: "Area" },
{ value: viewTypes.stackedReversed, label: "Stack" }, { value: viewTypes.stacked, label: "Stack" },
{ value: viewTypes.bar, label: "Bars" }, { value: viewTypes.bar, label: "Bars" },
{ value: viewTypes.barReversed, label: "Bars↓" },
{ value: viewTypes.dots, label: "Dots" }, { value: viewTypes.dots, label: "Dots" },
]); ]);
const defaultView = viewTypes.stacked; const defaultView = viewTypes.stacked;