@lytjs/plugin-chart 5.0.1 → 6.4.0

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/dist/index.cjs CHANGED
@@ -1 +1,314 @@
1
- "use strict";var I=Object.defineProperty;var Y=Object.getOwnPropertyDescriptor;var q=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var U=(e,o)=>{for(var s in o)I(e,s,{get:o[s],enumerable:!0})},X=(e,o,s,m)=>{if(o&&typeof o=="object"||typeof o=="function")for(let t of q(o))!N.call(e,t)&&t!==s&&I(e,t,{get:()=>o[t],enumerable:!(m=Y(o,t))||m.enumerable});return e};var _=e=>X(I({},"__esModule",{value:!0}),e);var Z={};U(Z,{createChart:()=>Q});module.exports=_(Z);var L=["#42b883","#3b82f6","#f59e0b","#ef4444","#8b5cf6","#ec4899","#14b8a6","#f97316","#06b6d4","#84cc16"],p={title:"",width:600,height:400,showGrid:!0,showLegend:!0,showValues:!1,animationDuration:500,padding:{top:40,right:30,bottom:50,left:60},yMax:0,yMin:0};function J(){return typeof window!="undefined"&&window.devicePixelRatio||1}function P(e,o,s=5){let m=e-o;if(m===0)return[o-1,o,o+1];let t=m/(s-1),r=Math.pow(10,Math.floor(Math.log10(t))),n=t/r,b;n<=1?b=r:n<=2?b=2*r:n<=5?b=5*r:b=10*r;let v=[],c=Math.floor(o/b)*b;for(;c<=e+b*.5;)v.push(Math.round(c*1e10)/1e10),c+=b;return v}function H(e){return e>=1e6?(e/1e6).toFixed(1)+"M":e>=1e3?(e/1e3).toFixed(1)+"K":String(Math.round(e*100)/100)}function K(e,o,s,m){let{width:t,height:r,padding:n,showGrid:b,showLegend:v,showValues:c,title:D}=s,A=t-n.left-n.right,h=r-n.top-n.bottom,M=[];for(let l of o.datasets)M=M.concat(l.data);let B=s.yMax||Math.max(...M,0),V=s.yMin||Math.min(...M,0),C=P(B,V),w=C[0],S=C[C.length-1]-w||1;if(e.clearRect(0,0,t,r),D&&(e.fillStyle="#2c3e50",e.font="bold 16px -apple-system, BlinkMacSystemFont, sans-serif",e.textAlign="center",e.fillText(D,t/2,24)),b){e.strokeStyle="#e5e7eb",e.lineWidth=1,e.fillStyle="#95a5a6",e.font="12px -apple-system, BlinkMacSystemFont, sans-serif",e.textAlign="right";for(let l of C){let f=n.top+h-(l-w)/S*h;e.beginPath(),e.moveTo(n.left,f),e.lineTo(t-n.right,f),e.stroke(),e.fillText(H(l),n.left-8,f+4)}}let k=o.labels.length,i=A/k,a=Math.min(i*.6/o.datasets.length,50),u=(i-a*o.datasets.length)/2;for(let l=0;l<o.datasets.length;l++){let f=o.datasets[l],g=f.color||L[l%L.length];for(let d=0;d<f.data.length;d++){let T=f.data[d]*m,y=n.left+d*i+u+l*a,W=(T-w)/S*h,F=n.top+h-W;e.fillStyle=g,e.beginPath();let R=Math.min(4,a/4),E=Math.max(0,W);E>R*2?(e.moveTo(y,F+R),e.arcTo(y,F,y+R,F,R),e.arcTo(y+a,F,y+a,F+R,R),e.lineTo(y+a,n.top+h),e.lineTo(y,n.top+h)):e.rect(y,F,a,E),e.fill(),c&&m>=1&&(e.fillStyle="#2c3e50",e.font="11px -apple-system, BlinkMacSystemFont, sans-serif",e.textAlign="center",e.fillText(H(f.data[d]),y+a/2,F-6))}}e.fillStyle="#6c757d",e.font="12px -apple-system, BlinkMacSystemFont, sans-serif",e.textAlign="center";for(let l=0;l<o.labels.length;l++){let f=n.left+l*i+i/2;e.fillText(o.labels[l],f,r-n.bottom+20)}if(v&&o.datasets.length>1){let l=n.top-10,f=t/2-o.datasets.length*80/2;for(let g=0;g<o.datasets.length;g++){let d=o.datasets[g],T=d.color||L[g%L.length];e.fillStyle=T,e.fillRect(f,l-8,12,12),e.fillStyle="#2c3e50",e.font="12px -apple-system, BlinkMacSystemFont, sans-serif",e.textAlign="left",e.fillText(d.label,f+16,l+2),f+=e.measureText(d.label).width+36}}}function j(e,o,s,m){let{width:t,height:r,padding:n,showGrid:b,showLegend:v,showValues:c,title:D}=s,A=t-n.left-n.right,h=r-n.top-n.bottom,M=[];for(let i of o.datasets)M=M.concat(i.data);let B=s.yMax||Math.max(...M,0),V=s.yMin||Math.min(...M,0),C=P(B,V),w=C[0],S=C[C.length-1]-w||1;if(e.clearRect(0,0,t,r),D&&(e.fillStyle="#2c3e50",e.font="bold 16px -apple-system, BlinkMacSystemFont, sans-serif",e.textAlign="center",e.fillText(D,t/2,24)),b){e.strokeStyle="#e5e7eb",e.lineWidth=1,e.fillStyle="#95a5a6",e.font="12px -apple-system, BlinkMacSystemFont, sans-serif",e.textAlign="right";for(let i of C){let a=n.top+h-(i-w)/S*h;e.beginPath(),e.moveTo(n.left,a),e.lineTo(t-n.right,a),e.stroke(),e.fillText(H(i),n.left-8,a+4)}}let k=o.labels.length>1?A/(o.labels.length-1):0;for(let i=0;i<o.datasets.length;i++){let a=o.datasets[i],u=a.color||L[i%L.length];e.beginPath(),e.moveTo(n.left,n.top+h);for(let l=0;l<a.data.length;l++){let f=a.data[l]*m,g=n.left+l*k,d=n.top+h-(f-w)/S*h;e.lineTo(g,d)}e.lineTo(n.left+(a.data.length-1)*k,n.top+h),e.closePath(),e.fillStyle=u+"15",e.fill(),e.beginPath(),e.strokeStyle=u,e.lineWidth=2.5,e.lineJoin="round",e.lineCap="round";for(let l=0;l<a.data.length;l++){let f=a.data[l]*m,g=n.left+l*k,d=n.top+h-(f-w)/S*h;l===0?e.moveTo(g,d):e.lineTo(g,d)}e.stroke();for(let l=0;l<a.data.length;l++){let f=a.data[l]*m,g=n.left+l*k,d=n.top+h-(f-w)/S*h;e.beginPath(),e.arc(g,d,4,0,Math.PI*2),e.fillStyle="#fff",e.fill(),e.strokeStyle=u,e.lineWidth=2,e.stroke(),c&&m>=1&&(e.fillStyle="#2c3e50",e.font="11px -apple-system, BlinkMacSystemFont, sans-serif",e.textAlign="center",e.fillText(H(a.data[l]),g,d-10))}}e.fillStyle="#6c757d",e.font="12px -apple-system, BlinkMacSystemFont, sans-serif",e.textAlign="center";for(let i=0;i<o.labels.length;i++){let a=n.left+i*k;e.fillText(o.labels[i],a,r-n.bottom+20)}if(v&&o.datasets.length>1){let i=n.top-10,a=t/2-o.datasets.length*80/2;for(let u=0;u<o.datasets.length;u++){let l=o.datasets[u],f=l.color||L[u%L.length];e.strokeStyle=f,e.lineWidth=2.5,e.beginPath(),e.moveTo(a,i-2),e.lineTo(a+16,i-2),e.stroke(),e.fillStyle="#2c3e50",e.font="12px -apple-system, BlinkMacSystemFont, sans-serif",e.textAlign="left",e.fillText(l.label,a+22,i+2),a+=e.measureText(l.label).width+42}}}function Q(e,o){var V,C,w,G,S,k,i,a,u,l,f,g,d;let s;e instanceof HTMLCanvasElement?s=e:(s=document.createElement("canvas"),e.appendChild(s));let m=s.getContext("2d"),t=o.options,r=t==null?void 0:t.padding,n={title:(V=t==null?void 0:t.title)!=null?V:p.title,width:(C=t==null?void 0:t.width)!=null?C:p.width,height:(w=t==null?void 0:t.height)!=null?w:p.height,showGrid:(G=t==null?void 0:t.showGrid)!=null?G:p.showGrid,showLegend:(S=t==null?void 0:t.showLegend)!=null?S:p.showLegend,showValues:(k=t==null?void 0:t.showValues)!=null?k:p.showValues,animationDuration:(i=t==null?void 0:t.animationDuration)!=null?i:p.animationDuration,padding:{top:(a=r==null?void 0:r.top)!=null?a:p.padding.top,right:(u=r==null?void 0:r.right)!=null?u:p.padding.right,bottom:(l=r==null?void 0:r.bottom)!=null?l:p.padding.bottom,left:(f=r==null?void 0:r.left)!=null?f:p.padding.left},yMax:(g=t==null?void 0:t.yMax)!=null?g:p.yMax,yMin:(d=t==null?void 0:t.yMin)!=null?d:p.yMin},b=J(),v=n.width,c=n.height,D=o.data;function A(){s.width=v*b,s.height=c*b,s.style.width=v+"px",s.style.height=c+"px",m.setTransform(b,0,0,b,0,0)}let h=null;function M(T){o.type==="bar"?K(m,D,n,T):j(m,D,n,T)}function B(){h!==null&&cancelAnimationFrame(h);let T=performance.now(),y=n.animationDuration;function W(F){let R=F-T,E=Math.min(R/y,1),z=1-Math.pow(1-E,3);M(z),E<1?h=requestAnimationFrame(W):h=null}h=requestAnimationFrame(W)}return A(),B(),{update(T){D=T,A(),B()},resize(T,y){v=T,c=y,A(),M(1)},destroy(){h!==null&&(cancelAnimationFrame(h),h=null),m.clearRect(0,0,v,c),s.parentElement&&e instanceof HTMLElement&&s!==e&&e.removeChild(s)},getContext(){return m}}}
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var core = require('@lytjs/core');
6
+
7
+ // src/index.ts
8
+ var DEFAULT_COLORS = [
9
+ "#1890ff",
10
+ "#52c41a",
11
+ "#faad14",
12
+ "#ff4d4f",
13
+ "#722ed1",
14
+ "#13c2c2",
15
+ "#eb2f96",
16
+ "#fa541c"
17
+ ];
18
+ var DEFAULT_CONFIG = {
19
+ showLegend: true,
20
+ showGrid: true,
21
+ width: 400,
22
+ height: 300,
23
+ animationDuration: 500,
24
+ padding: 40
25
+ };
26
+ function createChart(canvas, config, options = {}) {
27
+ const {
28
+ defaultAnimationDuration = 500
29
+ } = options;
30
+ let currentConfig = { ...DEFAULT_CONFIG, ...config };
31
+ let animationFrame = null;
32
+ function getColor(datasetIndex, dataIndex) {
33
+ const dataset = currentConfig.datasets[datasetIndex];
34
+ const dataPoint = dataset?.data?.[dataIndex];
35
+ if (dataPoint?.color) return dataPoint.color;
36
+ if (dataset?.color) return dataset.color;
37
+ const colorIndex = dataIndex % DEFAULT_COLORS.length;
38
+ return DEFAULT_COLORS[colorIndex] || "#1890ff";
39
+ }
40
+ function drawBarChart(ctx, progress = 1) {
41
+ const { width, height, padding, datasets, showGrid } = currentConfig;
42
+ const ctxWidth = width - padding * 2;
43
+ const ctxHeight = height - padding * 2;
44
+ let maxValue = 0;
45
+ datasets.forEach((dataset) => {
46
+ dataset.data.forEach((point) => {
47
+ if (point.value > maxValue) maxValue = point.value;
48
+ });
49
+ });
50
+ if (showGrid) {
51
+ ctx.strokeStyle = "#e8e8e8";
52
+ ctx.lineWidth = 1;
53
+ for (let i = 0; i <= 5; i++) {
54
+ const y = padding + ctxHeight / 5 * i;
55
+ ctx.beginPath();
56
+ ctx.moveTo(padding, y);
57
+ ctx.lineTo(width - padding, y);
58
+ ctx.stroke();
59
+ ctx.fillStyle = "#666";
60
+ ctx.font = "12px sans-serif";
61
+ ctx.textAlign = "right";
62
+ ctx.fillText(
63
+ Math.round(maxValue - maxValue / 5 * i).toString(),
64
+ padding - 10,
65
+ y + 4
66
+ );
67
+ }
68
+ }
69
+ const totalBars = datasets.reduce((sum, ds) => sum + ds.data.length, 0);
70
+ const barWidth = ctxWidth / totalBars * 0.7;
71
+ const gap = ctxWidth / totalBars * 0.3;
72
+ let x = padding + gap / 2;
73
+ datasets.forEach((dataset, datasetIndex) => {
74
+ dataset.data.forEach((point, dataIndex) => {
75
+ const barHeight = point.value / maxValue * ctxHeight * progress;
76
+ const y = height - padding - barHeight;
77
+ ctx.fillStyle = getColor(datasetIndex, dataIndex);
78
+ ctx.fillRect(x, y, barWidth, barHeight);
79
+ ctx.fillStyle = "#666";
80
+ ctx.font = "11px sans-serif";
81
+ ctx.textAlign = "center";
82
+ ctx.fillText(
83
+ point.label,
84
+ x + barWidth / 2,
85
+ height - padding + 20
86
+ );
87
+ x += barWidth + gap;
88
+ });
89
+ });
90
+ }
91
+ function drawLineChart(ctx, progress = 1) {
92
+ const { width, height, padding, datasets, showGrid } = currentConfig;
93
+ const ctxWidth = width - padding * 2;
94
+ const ctxHeight = height - padding * 2;
95
+ let maxValue = 0;
96
+ datasets.forEach((dataset) => {
97
+ dataset.data.forEach((point) => {
98
+ if (point.value > maxValue) maxValue = point.value;
99
+ });
100
+ });
101
+ if (showGrid) {
102
+ ctx.strokeStyle = "#e8e8e8";
103
+ ctx.lineWidth = 1;
104
+ for (let i = 0; i <= 5; i++) {
105
+ const y = padding + ctxHeight / 5 * i;
106
+ ctx.beginPath();
107
+ ctx.moveTo(padding, y);
108
+ ctx.lineTo(width - padding, y);
109
+ ctx.stroke();
110
+ ctx.fillStyle = "#666";
111
+ ctx.font = "12px sans-serif";
112
+ ctx.textAlign = "right";
113
+ ctx.fillText(
114
+ Math.round(maxValue - maxValue / 5 * i).toString(),
115
+ padding - 10,
116
+ y + 4
117
+ );
118
+ }
119
+ }
120
+ datasets.forEach((dataset, datasetIndex) => {
121
+ const color = getColor(datasetIndex, 0);
122
+ ctx.strokeStyle = color;
123
+ ctx.fillStyle = color;
124
+ ctx.lineWidth = dataset.borderWidth || 2;
125
+ ctx.beginPath();
126
+ const stepX = ctxWidth / (dataset.data.length - 1);
127
+ dataset.data.forEach((point, index) => {
128
+ const x = padding + stepX * index;
129
+ const y = height - padding - point.value / maxValue * ctxHeight * progress;
130
+ if (index === 0) {
131
+ ctx.moveTo(x, y);
132
+ } else {
133
+ ctx.lineTo(x, y);
134
+ }
135
+ ctx.beginPath();
136
+ ctx.arc(x, y, 4, 0, Math.PI * 2);
137
+ ctx.fill();
138
+ ctx.beginPath();
139
+ ctx.moveTo(x, y);
140
+ ctx.fillStyle = "#666";
141
+ ctx.font = "11px sans-serif";
142
+ ctx.textAlign = "center";
143
+ ctx.fillText(
144
+ point.label,
145
+ x,
146
+ height - padding + 20
147
+ );
148
+ });
149
+ ctx.stroke();
150
+ });
151
+ }
152
+ function drawPieChart(ctx, progress = 1) {
153
+ const { width, height, padding, datasets } = currentConfig;
154
+ const centerX = width / 2;
155
+ const centerY = height / 2;
156
+ const radius = Math.min(width, height) / 2 - padding;
157
+ let totalValue = 0;
158
+ datasets.forEach((dataset) => {
159
+ dataset.data.forEach((point) => {
160
+ totalValue += point.value;
161
+ });
162
+ });
163
+ let currentAngle = -Math.PI / 2;
164
+ datasets.forEach((dataset, datasetIndex) => {
165
+ dataset.data.forEach((point, dataIndex) => {
166
+ const sliceAngle = point.value / totalValue * Math.PI * 2 * progress;
167
+ ctx.fillStyle = getColor(datasetIndex, dataIndex);
168
+ ctx.beginPath();
169
+ ctx.moveTo(centerX, centerY);
170
+ ctx.arc(centerX, centerY, radius, currentAngle, currentAngle + sliceAngle);
171
+ ctx.closePath();
172
+ ctx.fill();
173
+ currentAngle += sliceAngle;
174
+ });
175
+ });
176
+ }
177
+ function drawDoughnutChart(ctx, progress = 1) {
178
+ const { width, height, padding, datasets } = currentConfig;
179
+ const centerX = width / 2;
180
+ const centerY = height / 2;
181
+ const outerRadius = Math.min(width, height) / 2 - padding;
182
+ const innerRadius = outerRadius * 0.5;
183
+ let totalValue = 0;
184
+ datasets.forEach((dataset) => {
185
+ dataset.data.forEach((point) => {
186
+ totalValue += point.value;
187
+ });
188
+ });
189
+ let currentAngle = -Math.PI / 2;
190
+ datasets.forEach((dataset, datasetIndex) => {
191
+ dataset.data.forEach((point, dataIndex) => {
192
+ const sliceAngle = point.value / totalValue * Math.PI * 2 * progress;
193
+ ctx.fillStyle = getColor(datasetIndex, dataIndex);
194
+ ctx.beginPath();
195
+ ctx.arc(centerX, centerY, outerRadius, currentAngle, currentAngle + sliceAngle);
196
+ ctx.arc(centerX, centerY, innerRadius, currentAngle + sliceAngle, currentAngle, true);
197
+ ctx.closePath();
198
+ ctx.fill();
199
+ currentAngle += sliceAngle;
200
+ });
201
+ });
202
+ }
203
+ function drawTitle(ctx) {
204
+ if (!currentConfig.title) return;
205
+ ctx.fillStyle = "#333";
206
+ ctx.font = "bold 16px sans-serif";
207
+ ctx.textAlign = "center";
208
+ ctx.fillText(currentConfig.title, currentConfig.width / 2, 25);
209
+ }
210
+ function drawLegend(ctx) {
211
+ if (!currentConfig.showLegend) return;
212
+ let legendX = currentConfig.padding;
213
+ const legendY = currentConfig.height - 20;
214
+ currentConfig.datasets.forEach((dataset, datasetIndex) => {
215
+ dataset.data.forEach((point, dataIndex) => {
216
+ const color = getColor(datasetIndex, dataIndex);
217
+ ctx.fillStyle = color;
218
+ ctx.fillRect(legendX, legendY, 12, 12);
219
+ ctx.fillStyle = "#666";
220
+ ctx.font = "12px sans-serif";
221
+ ctx.textAlign = "left";
222
+ ctx.fillText(point.label, legendX + 18, legendY + 10);
223
+ legendX += 100;
224
+ });
225
+ });
226
+ }
227
+ function render() {
228
+ const ctx = canvas.getContext("2d");
229
+ if (!ctx) return;
230
+ canvas.width = currentConfig.width;
231
+ canvas.height = currentConfig.height;
232
+ ctx.clearRect(0, 0, currentConfig.width, currentConfig.height);
233
+ const startTime = Date.now();
234
+ const duration = currentConfig.animationDuration || defaultAnimationDuration;
235
+ function animate() {
236
+ if (!ctx) return;
237
+ const elapsed = Date.now() - startTime;
238
+ const progress = Math.min(elapsed / duration, 1);
239
+ ctx.clearRect(0, 0, currentConfig.width, currentConfig.height);
240
+ drawTitle(ctx);
241
+ switch (currentConfig.type) {
242
+ case "bar":
243
+ drawBarChart(ctx, progress);
244
+ break;
245
+ case "line":
246
+ drawLineChart(ctx, progress);
247
+ break;
248
+ case "pie":
249
+ drawPieChart(ctx, progress);
250
+ break;
251
+ case "doughnut":
252
+ drawDoughnutChart(ctx, progress);
253
+ break;
254
+ }
255
+ drawLegend(ctx);
256
+ if (progress < 1) {
257
+ animationFrame = requestAnimationFrame(animate);
258
+ }
259
+ }
260
+ animate();
261
+ }
262
+ function updateData(datasets) {
263
+ currentConfig.datasets = datasets;
264
+ render();
265
+ }
266
+ function destroy() {
267
+ if (animationFrame) {
268
+ cancelAnimationFrame(animationFrame);
269
+ }
270
+ }
271
+ render();
272
+ return {
273
+ render,
274
+ updateData,
275
+ destroy,
276
+ getCanvas: () => canvas
277
+ };
278
+ }
279
+ var pluginChart = core.definePlugin({
280
+ name: "chart",
281
+ version: "6.0.0",
282
+ description: "LytJS official chart plugin for rendering charts using Canvas API",
283
+ author: "LytJS Team",
284
+ keywords: ["lytjs", "chart", "canvas", "visualization"],
285
+ schema: {
286
+ type: "object",
287
+ object: {
288
+ properties: {
289
+ defaultColors: {
290
+ type: "array",
291
+ default: DEFAULT_COLORS
292
+ },
293
+ defaultAnimationDuration: { type: "number", default: 500 },
294
+ responsive: { type: "boolean", default: true }
295
+ }
296
+ }
297
+ },
298
+ install(app, options) {
299
+ const chartOptions = options;
300
+ app.provide("lyt-chart", {
301
+ create: (canvas, config) => createChart(canvas, config, chartOptions)
302
+ });
303
+ app.config.globalProperties.$chart = {
304
+ create: (canvas, config) => createChart(canvas, config, chartOptions)
305
+ };
306
+ }
307
+ });
308
+ var index_default = pluginChart;
309
+
310
+ exports.DEFAULT_COLORS = DEFAULT_COLORS;
311
+ exports.createChart = createChart;
312
+ exports.default = index_default;
313
+ //# sourceMappingURL=index.cjs.map
314
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":["definePlugin"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * @lytjs/plugin-chart\r\n *\r\n * LytJS official chart plugin for rendering charts using Canvas API with zero dependencies.\r\n *\r\n * @packageDocumentation\r\n */\r\n\r\nimport { definePlugin } from '@lytjs/core';\r\nimport type {\r\n ChartDataPoint,\r\n ChartDataset,\r\n ChartType,\r\n ChartConfig,\r\n ChartInstance,\r\n ChartPluginOptions,\r\n} from './types';\r\n\r\n// 默认颜色 palette\r\nconst DEFAULT_COLORS = [\r\n '#1890ff',\r\n '#52c41a',\r\n '#faad14',\r\n '#ff4d4f',\r\n '#722ed1',\r\n '#13c2c2',\r\n '#eb2f96',\r\n '#fa541c',\r\n];\r\n\r\n// 默认配置\r\nconst DEFAULT_CONFIG = {\r\n showLegend: true,\r\n showGrid: true,\r\n width: 400,\r\n height: 300,\r\n animationDuration: 500,\r\n padding: 40,\r\n};\r\n\r\n/**\r\n * 创建图表实例\r\n */\r\nfunction createChart(\r\n canvas: HTMLCanvasElement,\r\n config: ChartConfig,\r\n options: ChartPluginOptions = {}\r\n): ChartInstance {\r\n const {\r\n defaultAnimationDuration = 500,\r\n } = options;\r\n\r\n let currentConfig = { ...DEFAULT_CONFIG, ...config };\r\n let animationFrame: number | null = null;\r\n\r\n // 获取颜色\r\n function getColor(datasetIndex: number, dataIndex: number): string {\r\n const dataset = currentConfig.datasets[datasetIndex];\r\n const dataPoint = dataset?.data?.[dataIndex];\r\n if (dataPoint?.color) return dataPoint.color;\r\n if (dataset?.color) return dataset.color;\r\n const colorIndex = dataIndex % DEFAULT_COLORS.length;\r\n return DEFAULT_COLORS[colorIndex] || '#1890ff';\r\n }\r\n\r\n // 绘制柱状图\r\n function drawBarChart(ctx: CanvasRenderingContext2D, progress: number = 1) {\r\n const { width, height, padding, datasets, showGrid } = currentConfig;\r\n const ctxWidth = width - padding * 2;\r\n const ctxHeight = height - padding * 2;\r\n\r\n // 找到最大值\r\n let maxValue = 0;\r\n datasets.forEach((dataset) => {\r\n dataset.data.forEach((point) => {\r\n if (point.value > maxValue) maxValue = point.value;\r\n });\r\n });\r\n\r\n // 绘制网格线\r\n if (showGrid) {\r\n ctx.strokeStyle = '#e8e8e8';\r\n ctx.lineWidth = 1;\r\n for (let i = 0; i <= 5; i++) {\r\n const y = padding + (ctxHeight / 5) * i;\r\n ctx.beginPath();\r\n ctx.moveTo(padding, y);\r\n ctx.lineTo(width - padding, y);\r\n ctx.stroke();\r\n\r\n // Y轴标签\r\n ctx.fillStyle = '#666';\r\n ctx.font = '12px sans-serif';\r\n ctx.textAlign = 'right';\r\n ctx.fillText(\r\n Math.round((maxValue - (maxValue / 5) * i)).toString(),\r\n padding - 10,\r\n y + 4\r\n );\r\n }\r\n }\r\n\r\n // 绘制柱状图\r\n const totalBars = datasets.reduce((sum, ds) => sum + ds.data.length, 0);\r\n const barWidth = ctxWidth / totalBars * 0.7;\r\n const gap = ctxWidth / totalBars * 0.3;\r\n\r\n let x = padding + gap / 2;\r\n\r\n datasets.forEach((dataset, datasetIndex) => {\r\n dataset.data.forEach((point, dataIndex) => {\r\n const barHeight = (point.value / maxValue) * ctxHeight * progress;\r\n const y = height - padding - barHeight;\r\n\r\n ctx.fillStyle = getColor(datasetIndex, dataIndex);\r\n ctx.fillRect(x, y, barWidth, barHeight);\r\n\r\n // X轴标签\r\n ctx.fillStyle = '#666';\r\n ctx.font = '11px sans-serif';\r\n ctx.textAlign = 'center';\r\n ctx.fillText(\r\n point.label,\r\n x + barWidth / 2,\r\n height - padding + 20\r\n );\r\n\r\n x += barWidth + gap;\r\n });\r\n });\r\n }\r\n\r\n // 绘制折线图\r\n function drawLineChart(ctx: CanvasRenderingContext2D, progress: number = 1) {\r\n const { width, height, padding, datasets, showGrid } = currentConfig;\r\n const ctxWidth = width - padding * 2;\r\n const ctxHeight = height - padding * 2;\r\n\r\n // 找到最大值\r\n let maxValue = 0;\r\n datasets.forEach((dataset) => {\r\n dataset.data.forEach((point) => {\r\n if (point.value > maxValue) maxValue = point.value;\r\n });\r\n });\r\n\r\n // 绘制网格线\r\n if (showGrid) {\r\n ctx.strokeStyle = '#e8e8e8';\r\n ctx.lineWidth = 1;\r\n for (let i = 0; i <= 5; i++) {\r\n const y = padding + (ctxHeight / 5) * i;\r\n ctx.beginPath();\r\n ctx.moveTo(padding, y);\r\n ctx.lineTo(width - padding, y);\r\n ctx.stroke();\r\n\r\n // Y轴标签\r\n ctx.fillStyle = '#666';\r\n ctx.font = '12px sans-serif';\r\n ctx.textAlign = 'right';\r\n ctx.fillText(\r\n Math.round((maxValue - (maxValue / 5) * i)).toString(),\r\n padding - 10,\r\n y + 4\r\n );\r\n }\r\n }\r\n\r\n // 绘制折线\r\n datasets.forEach((dataset, datasetIndex) => {\r\n const color = getColor(datasetIndex, 0);\r\n ctx.strokeStyle = color;\r\n ctx.fillStyle = color;\r\n ctx.lineWidth = dataset.borderWidth || 2;\r\n ctx.beginPath();\r\n\r\n const stepX = ctxWidth / (dataset.data.length - 1);\r\n\r\n dataset.data.forEach((point, index) => {\r\n const x = padding + stepX * index;\r\n const y = height - padding - (point.value / maxValue) * ctxHeight * progress;\r\n\r\n if (index === 0) {\r\n ctx.moveTo(x, y);\r\n } else {\r\n ctx.lineTo(x, y);\r\n }\r\n\r\n // 绘制点\r\n ctx.beginPath();\r\n ctx.arc(x, y, 4, 0, Math.PI * 2);\r\n ctx.fill();\r\n ctx.beginPath();\r\n ctx.moveTo(x, y);\r\n\r\n // X轴标签\r\n ctx.fillStyle = '#666';\r\n ctx.font = '11px sans-serif';\r\n ctx.textAlign = 'center';\r\n ctx.fillText(\r\n point.label,\r\n x,\r\n height - padding + 20\r\n );\r\n });\r\n\r\n ctx.stroke();\r\n });\r\n }\r\n\r\n // 绘制饼图\r\n function drawPieChart(ctx: CanvasRenderingContext2D, progress: number = 1) {\r\n const { width, height, padding, datasets } = currentConfig;\r\n const centerX = width / 2;\r\n const centerY = height / 2;\r\n const radius = Math.min(width, height) / 2 - padding;\r\n\r\n // 计算总值\r\n let totalValue = 0;\r\n datasets.forEach((dataset) => {\r\n dataset.data.forEach((point) => {\r\n totalValue += point.value;\r\n });\r\n });\r\n\r\n let currentAngle = -Math.PI / 2; // 从顶部开始\r\n\r\n datasets.forEach((dataset, datasetIndex) => {\r\n dataset.data.forEach((point, dataIndex) => {\r\n const sliceAngle = (point.value / totalValue) * Math.PI * 2 * progress;\r\n\r\n ctx.fillStyle = getColor(datasetIndex, dataIndex);\r\n ctx.beginPath();\r\n ctx.moveTo(centerX, centerY);\r\n ctx.arc(centerX, centerY, radius, currentAngle, currentAngle + sliceAngle);\r\n ctx.closePath();\r\n ctx.fill();\r\n\r\n currentAngle += sliceAngle;\r\n });\r\n });\r\n }\r\n\r\n // 绘制环形图\r\n function drawDoughnutChart(ctx: CanvasRenderingContext2D, progress: number = 1) {\r\n const { width, height, padding, datasets } = currentConfig;\r\n const centerX = width / 2;\r\n const centerY = height / 2;\r\n const outerRadius = Math.min(width, height) / 2 - padding;\r\n const innerRadius = outerRadius * 0.5;\r\n\r\n // 计算总值\r\n let totalValue = 0;\r\n datasets.forEach((dataset) => {\r\n dataset.data.forEach((point) => {\r\n totalValue += point.value;\r\n });\r\n });\r\n\r\n let currentAngle = -Math.PI / 2;\r\n\r\n datasets.forEach((dataset, datasetIndex) => {\r\n dataset.data.forEach((point, dataIndex) => {\r\n const sliceAngle = (point.value / totalValue) * Math.PI * 2 * progress;\r\n\r\n ctx.fillStyle = getColor(datasetIndex, dataIndex);\r\n ctx.beginPath();\r\n ctx.arc(centerX, centerY, outerRadius, currentAngle, currentAngle + sliceAngle);\r\n ctx.arc(centerX, centerY, innerRadius, currentAngle + sliceAngle, currentAngle, true);\r\n ctx.closePath();\r\n ctx.fill();\r\n\r\n currentAngle += sliceAngle;\r\n });\r\n });\r\n }\r\n\r\n // 绘制标题\r\n function drawTitle(ctx: CanvasRenderingContext2D) {\r\n if (!currentConfig.title) return;\r\n\r\n ctx.fillStyle = '#333';\r\n ctx.font = 'bold 16px sans-serif';\r\n ctx.textAlign = 'center';\r\n ctx.fillText(currentConfig.title, currentConfig.width / 2, 25);\r\n }\r\n\r\n // 绘制图例\r\n function drawLegend(ctx: CanvasRenderingContext2D) {\r\n if (!currentConfig.showLegend) return;\r\n\r\n let legendX = currentConfig.padding;\r\n const legendY = currentConfig.height - 20;\r\n let itemIndex = 0;\r\n\r\n currentConfig.datasets.forEach((dataset, datasetIndex) => {\r\n dataset.data.forEach((point, dataIndex) => {\r\n const color = getColor(datasetIndex, dataIndex);\r\n\r\n // 绘制颜色方块\r\n ctx.fillStyle = color;\r\n ctx.fillRect(legendX, legendY, 12, 12);\r\n\r\n // 绘制标签\r\n ctx.fillStyle = '#666';\r\n ctx.font = '12px sans-serif';\r\n ctx.textAlign = 'left';\r\n ctx.fillText(point.label, legendX + 18, legendY + 10);\r\n\r\n legendX += 100;\r\n itemIndex++;\r\n });\r\n });\r\n }\r\n\r\n // 渲染函数\r\n function render() {\r\n const ctx = canvas.getContext('2d');\r\n if (!ctx) return;\r\n\r\n // 设置 canvas 尺寸\r\n canvas.width = currentConfig.width;\r\n canvas.height = currentConfig.height;\r\n\r\n // 清空画布\r\n ctx.clearRect(0, 0, currentConfig.width, currentConfig.height);\r\n\r\n const startTime = Date.now();\r\n const duration = currentConfig.animationDuration || defaultAnimationDuration;\r\n\r\n function animate() {\r\n if (!ctx) return;\r\n \r\n const elapsed = Date.now() - startTime;\r\n const progress = Math.min(elapsed / duration, 1);\r\n\r\n ctx.clearRect(0, 0, currentConfig.width, currentConfig.height);\r\n\r\n // 绘制标题\r\n drawTitle(ctx);\r\n\r\n // 绘制图表\r\n switch (currentConfig.type) {\r\n case 'bar':\r\n drawBarChart(ctx, progress);\r\n break;\r\n case 'line':\r\n drawLineChart(ctx, progress);\r\n break;\r\n case 'pie':\r\n drawPieChart(ctx, progress);\r\n break;\r\n case 'doughnut':\r\n drawDoughnutChart(ctx, progress);\r\n break;\r\n }\r\n\r\n // 绘制图例\r\n drawLegend(ctx);\r\n\r\n if (progress < 1) {\r\n animationFrame = requestAnimationFrame(animate);\r\n }\r\n }\r\n\r\n animate();\r\n }\r\n\r\n // 更新数据\r\n function updateData(datasets: ChartDataset[]) {\r\n currentConfig.datasets = datasets;\r\n render();\r\n }\r\n\r\n // 销毁\r\n function destroy() {\r\n if (animationFrame) {\r\n cancelAnimationFrame(animationFrame);\r\n }\r\n }\r\n\r\n // 初始化渲染\r\n render();\r\n\r\n return {\r\n render,\r\n updateData,\r\n destroy,\r\n getCanvas: () => canvas,\r\n };\r\n}\r\n\r\nconst pluginChart = definePlugin({\r\n name: 'chart',\r\n version: '6.0.0',\r\n description: 'LytJS official chart plugin for rendering charts using Canvas API',\r\n author: 'LytJS Team',\r\n keywords: ['lytjs', 'chart', 'canvas', 'visualization'],\r\n schema: {\r\n type: 'object',\r\n object: {\r\n properties: {\r\n defaultColors: { \r\n type: 'array', \r\n default: DEFAULT_COLORS,\r\n },\r\n defaultAnimationDuration: { type: 'number', default: 500 },\r\n responsive: { type: 'boolean', default: true },\r\n },\r\n },\r\n },\r\n install(app, options) {\r\n const chartOptions = options as ChartPluginOptions;\r\n\r\n // 提供创建图表的方法\r\n app.provide('lyt-chart', {\r\n create: (canvas: HTMLCanvasElement, config: ChartConfig) =>\r\n createChart(canvas, config, chartOptions),\r\n });\r\n\r\n // 挂载到全局属性\r\n app.config.globalProperties.$chart = {\r\n create: (canvas: HTMLCanvasElement, config: ChartConfig) =>\r\n createChart(canvas, config, chartOptions),\r\n };\r\n },\r\n});\r\n\r\nexport default pluginChart;\r\nexport type {\r\n ChartDataPoint,\r\n ChartDataset,\r\n ChartType,\r\n ChartConfig,\r\n ChartInstance,\r\n ChartPluginOptions,\r\n};\r\nexport { createChart, DEFAULT_COLORS };\r\n"]}
@@ -0,0 +1,79 @@
1
+ import * as _lytjs_core from '@lytjs/core';
2
+
3
+ /**
4
+ * @lytjs/plugin-chart types
5
+ *
6
+ * Type definitions for the chart plugin
7
+ */
8
+ /** 图表数据点 */
9
+ interface ChartDataPoint {
10
+ /** 标签 */
11
+ label: string;
12
+ /** 数值 */
13
+ value: number;
14
+ /** 颜色(可选) */
15
+ color?: string;
16
+ }
17
+ /** 数据集 */
18
+ interface ChartDataset {
19
+ /** 数据集标签 */
20
+ label: string;
21
+ /** 数据点数组 */
22
+ data: ChartDataPoint[];
23
+ /** 颜色(可选,应用于整个数据集) */
24
+ color?: string;
25
+ /** 边框宽度(可选) */
26
+ borderWidth?: number;
27
+ }
28
+ /** 图表类型 */
29
+ type ChartType = 'bar' | 'line' | 'pie' | 'doughnut';
30
+ /** 图表配置 */
31
+ interface ChartConfig {
32
+ /** 图表类型 */
33
+ type: ChartType;
34
+ /** 数据集 */
35
+ datasets: ChartDataset[];
36
+ /** 标题(可选) */
37
+ title?: string;
38
+ /** 是否显示图例 */
39
+ showLegend?: boolean;
40
+ /** 是否显示网格线 */
41
+ showGrid?: boolean;
42
+ /** 图表宽度 */
43
+ width?: number;
44
+ /** 图表高度 */
45
+ height?: number;
46
+ /** 动画持续时间(毫秒) */
47
+ animationDuration?: number;
48
+ /** 内边距 */
49
+ padding?: number;
50
+ }
51
+ /** 图表实例接口 */
52
+ interface ChartInstance {
53
+ /** 渲染图表 */
54
+ render(): void;
55
+ /** 更新数据 */
56
+ updateData(datasets: ChartDataset[]): void;
57
+ /** 销毁图表 */
58
+ destroy(): void;
59
+ /** 获取 Canvas 元素 */
60
+ getCanvas(): HTMLCanvasElement;
61
+ }
62
+ /** 图表插件选项 */
63
+ interface ChartPluginOptions {
64
+ /** 默认颜色 palette */
65
+ defaultColors?: string[];
66
+ /** 默认动画持续时间 */
67
+ defaultAnimationDuration?: number;
68
+ /** 响应式配置 */
69
+ responsive?: boolean;
70
+ }
71
+
72
+ declare const DEFAULT_COLORS: string[];
73
+ /**
74
+ * 创建图表实例
75
+ */
76
+ declare function createChart(canvas: HTMLCanvasElement, config: ChartConfig, options?: ChartPluginOptions): ChartInstance;
77
+ declare const pluginChart: _lytjs_core.PluginDefinition<unknown>;
78
+
79
+ export { type ChartConfig, type ChartDataPoint, type ChartDataset, type ChartInstance, type ChartPluginOptions, type ChartType, DEFAULT_COLORS, createChart, pluginChart as default };
package/dist/index.d.ts CHANGED
@@ -1,79 +1,79 @@
1
- /** 图表类型 */
2
- type ChartType = 'bar' | 'line';
1
+ import * as _lytjs_core from '@lytjs/core';
2
+
3
+ /**
4
+ * @lytjs/plugin-chart types
5
+ *
6
+ * Type definitions for the chart plugin
7
+ */
8
+ /** 图表数据点 */
9
+ interface ChartDataPoint {
10
+ /** 标签 */
11
+ label: string;
12
+ /** 数值 */
13
+ value: number;
14
+ /** 颜色(可选) */
15
+ color?: string;
16
+ }
3
17
  /** 数据集 */
4
18
  interface ChartDataset {
5
19
  /** 数据集标签 */
6
20
  label: string;
7
- /** 数据值数组 */
8
- data: number[];
9
- /** 数据集颜色 */
21
+ /** 数据点数组 */
22
+ data: ChartDataPoint[];
23
+ /** 颜色(可选,应用于整个数据集) */
10
24
  color?: string;
11
- /** 数据集背景色(柱状图填充色) */
12
- backgroundColor?: string;
25
+ /** 边框宽度(可选) */
26
+ borderWidth?: number;
13
27
  }
14
- /** 图表数据 */
15
- interface ChartData {
16
- /** X 轴标签 */
17
- labels: string[];
18
- /** 数据集列表 */
28
+ /** 图表类型 */
29
+ type ChartType = 'bar' | 'line' | 'pie' | 'doughnut';
30
+ /** 图表配置 */
31
+ interface ChartConfig {
32
+ /** 图表类型 */
33
+ type: ChartType;
34
+ /** 数据集 */
19
35
  datasets: ChartDataset[];
20
- }
21
- /** 图表配置选项 */
22
- interface ChartOptions {
23
- /** 图表标题 */
36
+ /** 标题(可选) */
24
37
  title?: string;
25
- /** 图表宽度(像素),默认 600 */
38
+ /** 是否显示图例 */
39
+ showLegend?: boolean;
40
+ /** 是否显示网格线 */
41
+ showGrid?: boolean;
42
+ /** 图表宽度 */
26
43
  width?: number;
27
- /** 图表高度(像素),默认 400 */
44
+ /** 图表高度 */
28
45
  height?: number;
29
- /** 是否显示网格线,默认 true */
30
- showGrid?: boolean;
31
- /** 是否显示图例,默认 true */
32
- showLegend?: boolean;
33
- /** 是否显示数值标签,默认 false */
34
- showValues?: boolean;
35
- /** 动画时长(毫秒),默认 500 */
46
+ /** 动画持续时间(毫秒) */
36
47
  animationDuration?: number;
37
48
  /** 内边距 */
38
- padding?: {
39
- top?: number;
40
- right?: number;
41
- bottom?: number;
42
- left?: number;
43
- };
44
- /** Y 轴最大值 */
45
- yMax?: number;
46
- /** Y 轴最小值 */
47
- yMin?: number;
49
+ padding?: number;
48
50
  }
49
- /** 图表创建参数 */
50
- interface ChartConfig {
51
- /** 图表类型 */
52
- type: ChartType;
53
- /** 图表数据 */
54
- data: ChartData;
55
- /** 图表选项 */
56
- options?: ChartOptions;
57
- }
58
- /** 图表实例 */
51
+ /** 图表实例接口 */
59
52
  interface ChartInstance {
60
- /** 更新图表数据 */
61
- update(data: ChartData): void;
62
- /** 调整图表尺寸 */
63
- resize(width: number, height: number): void;
64
- /** 销毁图表,释放资源 */
53
+ /** 渲染图表 */
54
+ render(): void;
55
+ /** 更新数据 */
56
+ updateData(datasets: ChartDataset[]): void;
57
+ /** 销毁图表 */
65
58
  destroy(): void;
66
- /** 获取 Canvas 上下文 */
67
- getContext(): CanvasRenderingContext2D;
59
+ /** 获取 Canvas 元素 */
60
+ getCanvas(): HTMLCanvasElement;
68
61
  }
62
+ /** 图表插件选项 */
63
+ interface ChartPluginOptions {
64
+ /** 默认颜色 palette */
65
+ defaultColors?: string[];
66
+ /** 默认动画持续时间 */
67
+ defaultAnimationDuration?: number;
68
+ /** 响应式配置 */
69
+ responsive?: boolean;
70
+ }
71
+
72
+ declare const DEFAULT_COLORS: string[];
69
73
  /**
70
74
  * 创建图表实例
71
- *
72
- * @param container - 容器元素或 Canvas 元素
73
- * @param config - 图表配置
74
- * @returns 图表实例
75
75
  */
76
- declare function createChart(container: HTMLElement | HTMLCanvasElement, config: ChartConfig): ChartInstance;
77
- export { createChart };
78
- export type { ChartType, ChartDataset, ChartData, ChartOptions, ChartConfig, ChartInstance, };
79
- //# sourceMappingURL=index.d.ts.map
76
+ declare function createChart(canvas: HTMLCanvasElement, config: ChartConfig, options?: ChartPluginOptions): ChartInstance;
77
+ declare const pluginChart: _lytjs_core.PluginDefinition<unknown>;
78
+
79
+ export { type ChartConfig, type ChartDataPoint, type ChartDataset, type ChartInstance, type ChartPluginOptions, type ChartType, DEFAULT_COLORS, createChart, pluginChart as default };