webwriter-chart
Version:
ww-chart is an interactive data visualization widget for the WebWriter tool that implements various charts and diagrams for static and exploratory data visualization.
141 lines (120 loc) • 3.96 kB
text/typescript
import { CompleteChartData } from "../../interfaces";
import { Chart, ChartType } from "chart.js";
import { GenericChart } from "./GenericChart";
export function getContext<T extends GenericChart<{}>>(
this_: T,
canvasId = "chart-canvas"
): CanvasRenderingContext2D {
const canvas = (this_.shadowRoot?.getElementById(canvasId) ||
null) as HTMLCanvasElement | null;
if (!canvas) throw new Error("No canvas found");
const ctx = canvas.getContext("2d");
if (!ctx) throw new Error("No context found");
return ctx;
}
export const getLabels = (data: CompleteChartData): string[] =>
Object.values(data).map((val) => val.label);
export const getData = (data: CompleteChartData): number[] =>
Object.values(data).map((val) => val.value);
export function updateData(
sources: Record<string, any>[],
targets: Record<string, any>[]
) {
if (sources.length < targets.length) {
targets.splice(sources.length, targets.length - sources.length);
}
if (sources.length > targets.length) {
for (let i = targets.length; i < sources.length; i++) {
targets.push(sources[i]);
}
}
targets.forEach((target: any, i: number) => {
Object.keys(sources[i]).forEach((key) => (target[key] = sources[i][key]));
});
}
//TODO: fix ChartTypeRegistry
export class ChartHelper<T extends Chart<any, number[], string>> {
public chart: T;
private chartType: ChartType;
// Static method to create and initialize a ChartHelper
public static create<T extends Chart<any, number[], string>>(
type: ChartType,
chart: T
): ChartHelper<T> {
const helper = new ChartHelper<T>();
helper.initialize(type, chart);
return helper;
} // Add the closing parenthesis here
// Initialize method (private to ensure it's only called internally)
private initialize(type: ChartType, chart: T) {
// Ensure the chart is not null or undefined
if (!chart) {
throw new Error("Invalid chart instance passed to ChartHelper.");
}
// Ensure chart options are initialized
if (!chart.options) {
throw new Error("Chart options are not initialized.");
}
// Initialize the chart and chartType
this.chart = chart;
this.chartType = type;
}
public setTitle(title: string) {
if (!this.chart.options.plugins) this.chart.options.plugins = {};
if (!this.chart.options.plugins.title)
this.chart.options.plugins.title = {};
this.chart.options.plugins.title.text = title;
this.chart.options.plugins.title.display = title !== "";
}
public setYScales(
dynamicSize: boolean,
scaleMin: number,
scaleMax: number,
stepSize: number
) {
if (!this.chart.options.scales) this.chart.options.scales = {};
if (!this.chart.options.scales.y) this.chart.options.scales.y = {};
this.chart.options.scales.y = {
min: undefined,
max: undefined,
};
if (!dynamicSize)
this.chart.options.scales.y = {
min: scaleMin,
max: scaleMax,
ticks: {
stepSize: stepSize,
},
};
// @ts-ignore
if (this.chart.options.scales.y.beginAtZero)
// @ts-ignore
this.chart.options.scales.y.beginAtZero = dynamicSize;
}
public setIndexAxis(indexAxis: "x" | "y") {
this.chart.options.indexAxis = indexAxis;
}
public setXLabels(labels: string[]) {
this.chart.data.labels = labels;
}
public setHideExactValues(val: boolean) {
if (!val)
this.chart.options.events = [
"mousemove",
"mouseout",
"click",
"touchstart",
"touchmove",
];
else this.chart.options.events = [];
}
public setLineSmooth(isLineSmooth: boolean) {
if (!this.chart.options.elements) this.chart.options.elements = {};
if (!this.chart.options.elements.line)
this.chart.options.elements.line = {};
this.chart.options.elements.line.tension = isLineSmooth ? 0.4 : 0;
}
public update() {
this.chart.update();
}
}