kt-template-online-api/src/qqbot/plugins/bangDream/tsugu/render-blocks/timeline-chart.ts

105 lines
2.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Chart, registerables } from 'chart.js';
import type { ChartConfiguration, ChartItem } from 'chart.js';
import { Canvas, FontLibrary, loadImage } from 'skia-canvas';
import 'chartjs-adapter-moment';
import { assetsRootPath } from '@/qqbot/plugins/bangDream/tsugu/runtime/config';
import { assetErrorImageBuffer } from '@/qqbot/plugins/bangDream/tsugu/canvas/image-utils';
import {
BANGDREAM_TIMELINE_CHART_SPEC,
getTimelineDisplayYMax,
getTimelineRawYMax,
type TimelineChartDataset,
type TimelineChartPoint,
} from '@/qqbot/plugins/bangDream/tsugu/render-blocks/timeline-chart-spec';
// 2. 注册 Chart.js 所有组件
Chart.register(...registerables);
// 3. 强制使用 `basic` platform避免 DOM 相关错误
// ChartJSNode.defaults.platform = 'basic';
// 4. 配置字体(如果有的话)
FontLibrary.use('old', [`${assetsRootPath}/Fonts/old.ttf`]);
// 5. 定义参数接口
interface DrawTimeLineChartOptions {
start: Date;
end: Date;
setStartToZero?: boolean;
data: {
datasets: TimelineChartDataset[];
};
}
// 6. 主函数:生成时间轴图表
/**
* 在图片布局层中绘制时间线条谱面。
*
* @param options1 - options1参数。
* @param displayLabel - 展示Label参数未传入时使用默认值。
*/
export async function drawTimeLineChart(
{ start, end, setStartToZero = false, data }: DrawTimeLineChartOptions,
displayLabel = false,
) {
const width = BANGDREAM_TIMELINE_CHART_SPEC.canvas.width;
const height = BANGDREAM_TIMELINE_CHART_SPEC.canvas.height;
// 7. 创建 skia-canvas 实例
const canvas = new Canvas(width, height);
const ctx = canvas.getContext('2d');
// 8. 计算 y 轴最大值
const yMax = getTimelineRawYMax(data.datasets);
// 9. 配置 Chart.js 选项
const options = {
plugins: {
legend: {
labels: {
font: {
size: BANGDREAM_TIMELINE_CHART_SPEC.legend.fontSize,
},
},
display: displayLabel,
},
},
scales: {
x: {
type: 'time' as const,
time: {
unit: BANGDREAM_TIMELINE_CHART_SPEC.xAxis.unit,
},
min: start.getTime(),
max: end.getTime(),
display: !setStartToZero,
},
y: {
min: BANGDREAM_TIMELINE_CHART_SPEC.yAxis.min,
max: getTimelineDisplayYMax(yMax),
},
},
};
// 10. Chart.js 配置
const config: ChartConfiguration<'line', TimelineChartPoint[]> = {
type: 'line' as const,
data,
options: {
...options,
responsive: BANGDREAM_TIMELINE_CHART_SPEC.responsive, // 重要:关闭 Chart.js 自适应模式
animation: BANGDREAM_TIMELINE_CHART_SPEC.animation,
},
};
try {
// 11. 生成 Chart.js 图表
new Chart(ctx as unknown as ChartItem, config);
// 12. 返回 skia-canvas 的 Image 对象
return canvas;
} catch {
return loadImage(assetErrorImageBuffer);
}
}