@meonode/canvas 1.1.0 → 1.3.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/{Readme.md → README.md} +320 -215
- package/dist/cjs/canvas/canvas.type.d.ts +50 -7
- package/dist/cjs/canvas/canvas.type.d.ts.map +1 -1
- package/dist/cjs/canvas/chart.canvas.util.d.ts.map +1 -1
- package/dist/cjs/canvas/chart.canvas.util.js +75 -8
- package/dist/cjs/canvas/chart.canvas.util.js.map +1 -1
- package/dist/cjs/canvas/grid.canvas.util.d.ts +25 -18
- package/dist/cjs/canvas/grid.canvas.util.d.ts.map +1 -1
- package/dist/cjs/canvas/grid.canvas.util.js +298 -210
- package/dist/cjs/canvas/grid.canvas.util.js.map +1 -1
- package/dist/cjs/canvas/text.canvas.util.d.ts.map +1 -1
- package/dist/cjs/canvas/text.canvas.util.js +84 -51
- package/dist/cjs/canvas/text.canvas.util.js.map +1 -1
- package/dist/esm/canvas/canvas.type.d.ts +50 -7
- package/dist/esm/canvas/canvas.type.d.ts.map +1 -1
- package/dist/esm/canvas/chart.canvas.util.d.ts.map +1 -1
- package/dist/esm/canvas/chart.canvas.util.js +75 -8
- package/dist/esm/canvas/grid.canvas.util.d.ts +25 -18
- package/dist/esm/canvas/grid.canvas.util.d.ts.map +1 -1
- package/dist/esm/canvas/grid.canvas.util.js +298 -210
- package/dist/esm/canvas/text.canvas.util.d.ts.map +1 -1
- package/dist/esm/canvas/text.canvas.util.js +84 -51
- package/package.json +25 -17
|
@@ -170,13 +170,22 @@ class ChartNode extends BoxNode {
|
|
|
170
170
|
return;
|
|
171
171
|
const chartData = this.chartData;
|
|
172
172
|
const chartOptions = this.chartOptions;
|
|
173
|
+
const { labels, datasets } = chartData;
|
|
174
|
+
const maxValue = Math.max(...datasets.flatMap(d => d.data));
|
|
173
175
|
const legendLayout = this.getLegendLayout(ctx, width, height);
|
|
174
|
-
|
|
176
|
+
let chartX = x + legendLayout.chartX;
|
|
175
177
|
const chartY = y + legendLayout.chartY;
|
|
176
|
-
|
|
178
|
+
let chartWidth = legendLayout.chartWidth;
|
|
177
179
|
const chartHeight = legendLayout.chartHeight;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
+
if (chartOptions?.showYAxis) {
|
|
181
|
+
const fontSize = chartOptions.yAxisFontSize || 12;
|
|
182
|
+
ctx.font = `${fontSize}px ${this.props.fontFamily || 'sans-serif'}`;
|
|
183
|
+
const formatter = chartOptions.yAxisLabelFormatter || ((v) => v.toString());
|
|
184
|
+
const maxLabel = formatter(maxValue);
|
|
185
|
+
const yAxisWidth = ctx.measureText(maxLabel).width + 10;
|
|
186
|
+
chartX += yAxisWidth;
|
|
187
|
+
chartWidth -= yAxisWidth;
|
|
188
|
+
}
|
|
180
189
|
let labelHeight = 0;
|
|
181
190
|
if (chartOptions?.showLabels) {
|
|
182
191
|
const fontSize = chartOptions.labelFontSize || 12;
|
|
@@ -204,6 +213,18 @@ class ChartNode extends BoxNode {
|
|
|
204
213
|
ctx.moveTo(chartX, gridY);
|
|
205
214
|
ctx.lineTo(chartX + chartWidth, gridY);
|
|
206
215
|
ctx.stroke();
|
|
216
|
+
if (chartOptions?.showYAxis) {
|
|
217
|
+
const value = maxValue - (maxValue / 5) * i;
|
|
218
|
+
const formatter = chartOptions.yAxisLabelFormatter || ((v) => (Math.round(v * 100) / 100).toString());
|
|
219
|
+
const label = formatter(value);
|
|
220
|
+
TextNode.renderSimpleText(ctx, label, chartX - 5, gridY, {
|
|
221
|
+
color: chartOptions.yAxisColor || chartOptions.axisColor || '#000',
|
|
222
|
+
fontSize: chartOptions.yAxisFontSize || 12,
|
|
223
|
+
fontFamily: this.props.fontFamily,
|
|
224
|
+
textAlign: 'right',
|
|
225
|
+
textBaseline: 'middle',
|
|
226
|
+
});
|
|
227
|
+
}
|
|
207
228
|
}
|
|
208
229
|
ctx.setLineDash([]);
|
|
209
230
|
}
|
|
@@ -216,6 +237,31 @@ class ChartNode extends BoxNode {
|
|
|
216
237
|
const barY = chartY + finalChartHeight - barHeight;
|
|
217
238
|
ctx.fillStyle = dataset.color || this.generateColor(datasetIndex);
|
|
218
239
|
ctx.fillRect(barX, barY, barWidth, barHeight);
|
|
240
|
+
// Render values
|
|
241
|
+
if (chartOptions?.showValues) {
|
|
242
|
+
const value = dataset.data[index];
|
|
243
|
+
const { renderValueItem } = chartOptions;
|
|
244
|
+
const valueX = barX + barWidth / 2;
|
|
245
|
+
const valueY = barY - 5; // 5px padding above bar
|
|
246
|
+
if (renderValueItem) {
|
|
247
|
+
const valueNode = renderValueItem({ item: value, index, datasetIndex });
|
|
248
|
+
if (valueNode) {
|
|
249
|
+
valueNode.processInitialChildren();
|
|
250
|
+
valueNode.node.calculateLayout(undefined, undefined, Style.Direction.LTR);
|
|
251
|
+
const layout = valueNode.node.getComputedLayout();
|
|
252
|
+
valueNode.render(ctx, valueX - layout.width / 2, valueY - layout.height);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
TextNode.renderSimpleText(ctx, value.toString(), valueX, valueY, {
|
|
257
|
+
color: chartOptions.valueColor || '#000',
|
|
258
|
+
fontSize: chartOptions.valueFontSize || 12,
|
|
259
|
+
fontFamily: this.props.fontFamily,
|
|
260
|
+
textAlign: 'center',
|
|
261
|
+
textBaseline: 'bottom',
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
219
265
|
});
|
|
220
266
|
// Render labels
|
|
221
267
|
if (chartOptions?.showLabels) {
|
|
@@ -250,13 +296,22 @@ class ChartNode extends BoxNode {
|
|
|
250
296
|
return;
|
|
251
297
|
const chartData = this.chartData;
|
|
252
298
|
const chartOptions = this.chartOptions;
|
|
299
|
+
const { labels, datasets } = chartData;
|
|
300
|
+
const maxValue = Math.max(...datasets.flatMap(d => d.data));
|
|
253
301
|
const legendLayout = this.getLegendLayout(ctx, width, height);
|
|
254
|
-
|
|
302
|
+
let chartX = x + legendLayout.chartX;
|
|
255
303
|
const chartY = y + legendLayout.chartY;
|
|
256
|
-
|
|
304
|
+
let chartWidth = legendLayout.chartWidth;
|
|
257
305
|
const chartHeight = legendLayout.chartHeight;
|
|
258
|
-
|
|
259
|
-
|
|
306
|
+
if (chartOptions?.showYAxis) {
|
|
307
|
+
const fontSize = chartOptions.yAxisFontSize || 12;
|
|
308
|
+
ctx.font = `${fontSize}px ${this.props.fontFamily || 'sans-serif'}`;
|
|
309
|
+
const formatter = chartOptions.yAxisLabelFormatter || ((v) => v.toString());
|
|
310
|
+
const maxLabel = formatter(maxValue);
|
|
311
|
+
const yAxisWidth = ctx.measureText(maxLabel).width + 10;
|
|
312
|
+
chartX += yAxisWidth;
|
|
313
|
+
chartWidth -= yAxisWidth;
|
|
314
|
+
}
|
|
260
315
|
let labelHeight = 0;
|
|
261
316
|
if (chartOptions?.showLabels) {
|
|
262
317
|
const fontSize = chartOptions.labelFontSize || 12;
|
|
@@ -282,6 +337,18 @@ class ChartNode extends BoxNode {
|
|
|
282
337
|
ctx.moveTo(chartX, gridY);
|
|
283
338
|
ctx.lineTo(chartX + chartWidth, gridY);
|
|
284
339
|
ctx.stroke();
|
|
340
|
+
if (chartOptions?.showYAxis) {
|
|
341
|
+
const value = maxValue - (maxValue / 5) * i;
|
|
342
|
+
const formatter = chartOptions.yAxisLabelFormatter || ((v) => (Math.round(v * 100) / 100).toString());
|
|
343
|
+
const label = formatter(value);
|
|
344
|
+
TextNode.renderSimpleText(ctx, label, chartX - 5, gridY, {
|
|
345
|
+
color: chartOptions.yAxisColor || chartOptions.axisColor || '#000',
|
|
346
|
+
fontSize: chartOptions.yAxisFontSize || 12,
|
|
347
|
+
fontFamily: this.props.fontFamily,
|
|
348
|
+
textAlign: 'right',
|
|
349
|
+
textBaseline: 'middle',
|
|
350
|
+
});
|
|
351
|
+
}
|
|
285
352
|
}
|
|
286
353
|
ctx.setLineDash([]);
|
|
287
354
|
}
|
|
@@ -1,39 +1,46 @@
|
|
|
1
|
-
import type { GridProps } from '../canvas/canvas.type.js';
|
|
1
|
+
import type { GridProps, GridItemProps } from '../canvas/canvas.type.js';
|
|
2
2
|
import { BoxNode, RowNode } from '../canvas/layout.canvas.util.js';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* GridItem Node. Theoretically just a BoxNode but typed differently in factory.
|
|
5
|
+
* In runtime, it behaves almost like a BoxNode, but we can detect it if needed,
|
|
6
|
+
* or simply rely on the props being present in the instance.
|
|
7
|
+
*/
|
|
8
|
+
export declare class GridItemNode extends BoxNode {
|
|
9
|
+
constructor(props: GridItemProps);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Factory for GridItem.
|
|
13
|
+
*/
|
|
14
|
+
export declare const GridItem: (props: GridItemProps) => GridItemNode;
|
|
15
|
+
/**
|
|
16
|
+
* Grid layout node that arranges children in a 2D grid.
|
|
17
|
+
* Implements a simplified version of the CSS Grid Layout algorithm.
|
|
7
18
|
*/
|
|
8
19
|
export declare class GridNode extends RowNode {
|
|
9
|
-
private readonly columns;
|
|
10
|
-
private readonly columnGapValue;
|
|
11
|
-
private readonly rowGapValue;
|
|
12
|
-
private readonly isVertical;
|
|
13
20
|
/**
|
|
14
21
|
* Creates a new grid layout node
|
|
15
22
|
* @param props Grid configuration properties
|
|
16
23
|
*/
|
|
17
24
|
constructor(props: GridProps);
|
|
18
25
|
/**
|
|
19
|
-
*
|
|
20
|
-
* Overridden primarily for documentation/clarity, functionality is inherited.
|
|
21
|
-
* @param child Child node to append
|
|
22
|
-
* @param index Index at which to insert the child
|
|
26
|
+
* Helper to parse a track size definition.
|
|
23
27
|
*/
|
|
24
|
-
|
|
28
|
+
private parseTrack;
|
|
29
|
+
/**
|
|
30
|
+
* Parses the gap property into pixels.
|
|
31
|
+
*/
|
|
32
|
+
private getGapPixels;
|
|
25
33
|
/**
|
|
26
34
|
* Update layout calculations after the initial layout is computed.
|
|
27
|
-
* This method calculates the appropriate flex-basis for children based on the
|
|
28
|
-
* number of columns and gaps, respecting the container's padding,
|
|
29
|
-
* and applies the gaps using Yoga's built-in properties.
|
|
30
35
|
*/
|
|
31
36
|
protected updateLayoutBasedOnComputedSize(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Resolves track sizes to pixels.
|
|
39
|
+
*/
|
|
40
|
+
private resolveTracks;
|
|
32
41
|
}
|
|
33
42
|
/**
|
|
34
43
|
* Factory function to create a new GridNode instance.
|
|
35
|
-
* @param props Grid configuration properties.
|
|
36
|
-
* @returns A new GridNode instance.
|
|
37
44
|
*/
|
|
38
45
|
export declare const Grid: (props: GridProps) => GridNode;
|
|
39
46
|
//# sourceMappingURL=grid.canvas.util.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/grid.canvas.util.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"grid.canvas.util.d.ts","sourceRoot":"","sources":["../../../src/canvas/grid.canvas.util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAiB,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACtF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAA;AAIjE;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,OAAO;gBAC3B,KAAK,EAAE,aAAa;CAMjC;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ,GAAI,OAAO,aAAa,iBAA4B,CAAA;AAEzE;;;GAGG;AACH,qBAAa,QAAS,SAAQ,OAAO;IACnC;;;OAGG;gBACS,KAAK,EAAE,SAAS;IAQ5B;;OAEG;IACH,OAAO,CAAC,UAAU;IAqBlB;;OAEG;IACH,OAAO,CAAC,YAAY;IAmBpB;;OAEG;cACgB,+BAA+B;IA4RlD;;OAEG;IACH,OAAO,CAAC,aAAa;CAkCtB;AAED;;GAEG;AACH,eAAO,MAAM,IAAI,GAAI,OAAO,SAAS,aAAwB,CAAA"}
|