@impulse-ui-native/charts 2.0.1 → 2.1.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/LICENSE +21 -0
- package/dist/index.d.mts +320 -2
- package/dist/index.js +1081 -3
- package/dist/index.js.map +1 -1
- package/package.json +17 -8
package/dist/index.js
CHANGED
|
@@ -1,6 +1,1084 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
|
|
1
|
+
// src/components/primitives/grid.tsx
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import { DashPathEffect, Group, Path } from "@shopify/react-native-skia";
|
|
4
|
+
import { memo } from "@impulse-ui-native/core";
|
|
5
|
+
|
|
6
|
+
// src/constants/axis.constants.ts
|
|
7
|
+
var AxisDefaultWidth = 1;
|
|
8
|
+
var AxisDefaultOpacity = 1;
|
|
9
|
+
var AxisDefaultTickLength = 4;
|
|
10
|
+
var AxisDefaultLabelGap = 4;
|
|
11
|
+
|
|
12
|
+
// src/constants/grid.constants.ts
|
|
13
|
+
var GridDefaultWidth = 1;
|
|
14
|
+
var GridDefaultOpacity = 1;
|
|
15
|
+
var GridDefaultXVisible = true;
|
|
16
|
+
var GridDefaultYVisible = true;
|
|
17
|
+
|
|
18
|
+
// src/constants/label.constants.ts
|
|
19
|
+
var TabularNumsFeature = {
|
|
20
|
+
name: "tnum",
|
|
21
|
+
value: 1
|
|
22
|
+
};
|
|
23
|
+
var LabelDefaultHorizontalAlignment = "left";
|
|
24
|
+
var LabelDefaultVerticalAlignment = "top";
|
|
25
|
+
|
|
26
|
+
// src/constants/line.constants.ts
|
|
27
|
+
import { ChartColorTokens } from "@impulse-ui-native/theme";
|
|
28
|
+
var LineDefaultColor = ChartColorTokens[0];
|
|
29
|
+
var LineDefaultColors = ChartColorTokens;
|
|
30
|
+
var LineDefaultWidth = 2;
|
|
31
|
+
var LineDefaultOpacity = 1;
|
|
32
|
+
var LineDefaultCurve = "linear";
|
|
33
|
+
var LineDefaultCap = "round";
|
|
34
|
+
var LineDefaultJoin = "round";
|
|
35
|
+
|
|
36
|
+
// src/constants/line-chart.constants.ts
|
|
37
|
+
var LineChartDefaultTickCount = 5;
|
|
38
|
+
var LineChartDefaultNumericDomain = [0, 1];
|
|
39
|
+
|
|
40
|
+
// src/utils/axis.util.ts
|
|
41
|
+
function createAxisTicks(values, scale) {
|
|
42
|
+
return values.reduce((ticks, value) => {
|
|
43
|
+
const position = scale(value);
|
|
44
|
+
if (position !== void 0 && Number.isFinite(position)) {
|
|
45
|
+
ticks.push({ value, position });
|
|
46
|
+
}
|
|
47
|
+
return ticks;
|
|
48
|
+
}, []);
|
|
49
|
+
}
|
|
50
|
+
function createXAxisLayout(props) {
|
|
51
|
+
const ticks = createAxisTicks(props.values, props.scale);
|
|
52
|
+
const axisY = props.plot.y + props.plot.height;
|
|
53
|
+
const labelOffset = props.tickLength + props.labelGap;
|
|
54
|
+
return {
|
|
55
|
+
line: {
|
|
56
|
+
start: { x: props.plot.x, y: axisY },
|
|
57
|
+
end: { x: props.plot.x + props.plot.width, y: axisY }
|
|
58
|
+
},
|
|
59
|
+
ticks: ticks.map((tick, index) => ({
|
|
60
|
+
...tick,
|
|
61
|
+
start: { x: tick.position, y: axisY },
|
|
62
|
+
end: { x: tick.position, y: axisY + props.tickLength },
|
|
63
|
+
labelRect: createXAxisLabelRect(ticks, index, props.region, labelOffset)
|
|
64
|
+
}))
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function createYAxisLayout(props) {
|
|
68
|
+
const ticks = createAxisTicks(props.values, props.scale);
|
|
69
|
+
const axisX = props.plot.x;
|
|
70
|
+
const labelWidth = props.region.width - props.tickLength - props.labelGap;
|
|
71
|
+
return {
|
|
72
|
+
line: {
|
|
73
|
+
start: { x: axisX, y: props.plot.y },
|
|
74
|
+
end: { x: axisX, y: props.plot.y + props.plot.height }
|
|
75
|
+
},
|
|
76
|
+
ticks: ticks.map((tick) => ({
|
|
77
|
+
...tick,
|
|
78
|
+
start: { x: axisX - props.tickLength, y: tick.position },
|
|
79
|
+
end: { x: axisX, y: tick.position },
|
|
80
|
+
labelRect: createYAxisLabelRect(
|
|
81
|
+
tick.position,
|
|
82
|
+
props.region,
|
|
83
|
+
labelWidth,
|
|
84
|
+
props.fontSize
|
|
85
|
+
)
|
|
86
|
+
}))
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function createXAxisLabelRect(ticks, index, region, offset) {
|
|
90
|
+
const tick = ticks[index];
|
|
91
|
+
const previous = ticks[index - 1];
|
|
92
|
+
const next = ticks[index + 1];
|
|
93
|
+
const previousSpacing = previous ? Math.abs(tick.position - previous.position) : next ? Math.abs(next.position - tick.position) : region.width;
|
|
94
|
+
const nextSpacing = next ? Math.abs(next.position - tick.position) : previous ? Math.abs(tick.position - previous.position) : region.width;
|
|
95
|
+
const width = Math.max(0, Math.min(previousSpacing, nextSpacing));
|
|
96
|
+
return {
|
|
97
|
+
x: tick.position - width / 2,
|
|
98
|
+
y: region.y + offset,
|
|
99
|
+
width,
|
|
100
|
+
height: Math.max(0, region.height - offset)
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function createYAxisLabelRect(position, region, width, fontSize) {
|
|
104
|
+
return {
|
|
105
|
+
x: region.x,
|
|
106
|
+
y: position - fontSize,
|
|
107
|
+
width: Math.max(0, width),
|
|
108
|
+
height: fontSize * 2
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function formatAxisTick(value, format) {
|
|
112
|
+
return format ? format(value) : String(value);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// src/utils/chart-layout.util.ts
|
|
116
|
+
function createChartLayout(size, insets = {}) {
|
|
117
|
+
const resolvedInsets = {
|
|
118
|
+
top: insets.top ?? 0,
|
|
119
|
+
right: insets.right ?? 0,
|
|
120
|
+
bottom: insets.bottom ?? 0,
|
|
121
|
+
left: insets.left ?? 0
|
|
122
|
+
};
|
|
123
|
+
const plotWidth = Math.max(
|
|
124
|
+
0,
|
|
125
|
+
size.width - resolvedInsets.left - resolvedInsets.right
|
|
126
|
+
);
|
|
127
|
+
const plotHeight = Math.max(
|
|
128
|
+
0,
|
|
129
|
+
size.height - resolvedInsets.top - resolvedInsets.bottom
|
|
130
|
+
);
|
|
131
|
+
const plot = {
|
|
132
|
+
x: resolvedInsets.left,
|
|
133
|
+
y: resolvedInsets.top,
|
|
134
|
+
width: plotWidth,
|
|
135
|
+
height: plotHeight
|
|
136
|
+
};
|
|
137
|
+
return {
|
|
138
|
+
size,
|
|
139
|
+
insets: resolvedInsets,
|
|
140
|
+
plot,
|
|
141
|
+
xAxis: {
|
|
142
|
+
x: plot.x,
|
|
143
|
+
y: plot.y + plot.height,
|
|
144
|
+
width: plot.width,
|
|
145
|
+
height: resolvedInsets.bottom
|
|
146
|
+
},
|
|
147
|
+
yAxis: {
|
|
148
|
+
x: 0,
|
|
149
|
+
y: plot.y,
|
|
150
|
+
width: resolvedInsets.left,
|
|
151
|
+
height: plot.height
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function createInsetRect(rect, amount) {
|
|
156
|
+
const inset = Math.max(0, amount);
|
|
157
|
+
const horizontalInset = Math.min(inset, rect.width / 2);
|
|
158
|
+
const verticalInset = Math.min(inset, rect.height / 2);
|
|
159
|
+
return {
|
|
160
|
+
x: rect.x + horizontalInset,
|
|
161
|
+
y: rect.y + verticalInset,
|
|
162
|
+
width: Math.max(0, rect.width - horizontalInset * 2),
|
|
163
|
+
height: Math.max(0, rect.height - verticalInset * 2)
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// src/utils/grid.util.ts
|
|
168
|
+
import { Skia } from "@shopify/react-native-skia";
|
|
169
|
+
function createVerticalGridPath(values, scale, plot) {
|
|
170
|
+
const ticks = createAxisTicks(values, scale);
|
|
171
|
+
if (ticks.length === 0) {
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
const path = Skia.Path.Make();
|
|
175
|
+
ticks.forEach(({ position }) => {
|
|
176
|
+
path.moveTo(position, plot.y);
|
|
177
|
+
path.lineTo(position, plot.y + plot.height);
|
|
178
|
+
});
|
|
179
|
+
return path;
|
|
180
|
+
}
|
|
181
|
+
function createHorizontalGridPath(values, scale, plot) {
|
|
182
|
+
const ticks = createAxisTicks(values, scale);
|
|
183
|
+
if (ticks.length === 0) {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
const path = Skia.Path.Make();
|
|
187
|
+
ticks.forEach(({ position }) => {
|
|
188
|
+
path.moveTo(plot.x, position);
|
|
189
|
+
path.lineTo(plot.x + plot.width, position);
|
|
190
|
+
});
|
|
191
|
+
return path;
|
|
192
|
+
}
|
|
193
|
+
function resolveGridLineOptions(options, defaultVisible, defaultColor) {
|
|
194
|
+
if (typeof options === "boolean") {
|
|
195
|
+
return {
|
|
196
|
+
visible: options,
|
|
197
|
+
color: defaultColor,
|
|
198
|
+
width: GridDefaultWidth,
|
|
199
|
+
opacity: GridDefaultOpacity
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
visible: isGridLineVisible(options, defaultVisible),
|
|
204
|
+
color: options?.color ?? defaultColor,
|
|
205
|
+
width: options?.width ?? GridDefaultWidth,
|
|
206
|
+
opacity: options?.opacity ?? GridDefaultOpacity,
|
|
207
|
+
dash: options?.dash
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
function isGridLineVisible(options, defaultVisible) {
|
|
211
|
+
if (typeof options === "boolean") {
|
|
212
|
+
return options;
|
|
213
|
+
}
|
|
214
|
+
return options?.visible ?? defaultVisible;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// src/utils/label.util.ts
|
|
218
|
+
import { TextAlign } from "@shopify/react-native-skia";
|
|
219
|
+
function getLabelTextAlign(alignment) {
|
|
220
|
+
if (alignment === "center") {
|
|
221
|
+
return TextAlign.Center;
|
|
222
|
+
}
|
|
223
|
+
if (alignment === "right") {
|
|
224
|
+
return TextAlign.Right;
|
|
225
|
+
}
|
|
226
|
+
return TextAlign.Left;
|
|
227
|
+
}
|
|
228
|
+
function getLabelY(rect, paragraphHeight, alignment) {
|
|
229
|
+
if (alignment === "center") {
|
|
230
|
+
return rect.y + (rect.height - paragraphHeight) / 2;
|
|
231
|
+
}
|
|
232
|
+
if (alignment === "bottom") {
|
|
233
|
+
return rect.y + rect.height - paragraphHeight;
|
|
234
|
+
}
|
|
235
|
+
return rect.y;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// src/utils/line.util.ts
|
|
239
|
+
import { Skia as Skia2 } from "@shopify/react-native-skia";
|
|
240
|
+
import { line as createD3Line, curveLinear, curveMonotoneX } from "d3-shape";
|
|
241
|
+
function createLinePath(coordinates, curve) {
|
|
242
|
+
const pathData = createD3Line().defined((coordinate) => coordinate.x !== null && coordinate.y !== null).x((coordinate) => coordinate.x).y((coordinate) => coordinate.y).curve(curve === "monotone" ? curveMonotoneX : curveLinear)(coordinates);
|
|
243
|
+
return pathData ? Skia2.Path.MakeFromSVGString(pathData) : null;
|
|
244
|
+
}
|
|
245
|
+
function fitLineCoordinatesToRect(coordinates, source, target) {
|
|
246
|
+
return coordinates.map((coordinate) => ({
|
|
247
|
+
...coordinate,
|
|
248
|
+
x: coordinate.x === null ? null : mapCoordinate(
|
|
249
|
+
coordinate.x,
|
|
250
|
+
source.x,
|
|
251
|
+
source.width,
|
|
252
|
+
target.x,
|
|
253
|
+
target.width
|
|
254
|
+
),
|
|
255
|
+
y: coordinate.y === null ? null : mapCoordinate(
|
|
256
|
+
coordinate.y,
|
|
257
|
+
source.y,
|
|
258
|
+
source.height,
|
|
259
|
+
target.y,
|
|
260
|
+
target.height
|
|
261
|
+
)
|
|
262
|
+
}));
|
|
263
|
+
}
|
|
264
|
+
function mapCoordinate(value, sourceStart, sourceLength, targetStart, targetLength) {
|
|
265
|
+
if (sourceLength <= 0) {
|
|
266
|
+
return targetStart + targetLength / 2;
|
|
267
|
+
}
|
|
268
|
+
return targetStart + (value - sourceStart) / sourceLength * targetLength;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// src/utils/line-chart.util.ts
|
|
272
|
+
import { extent } from "d3-array";
|
|
273
|
+
import { scaleLinear, scalePoint, scaleTime } from "d3-scale";
|
|
274
|
+
function createLineChartModel(props) {
|
|
275
|
+
const xTickCount = getTickCount(props.xAxis?.tickCount);
|
|
276
|
+
const yTickCount = getTickCount(props.yAxis?.tickCount);
|
|
277
|
+
const xRange = [
|
|
278
|
+
props.plot.x,
|
|
279
|
+
props.plot.x + props.plot.width
|
|
280
|
+
];
|
|
281
|
+
const yRange = [
|
|
282
|
+
props.plot.y + props.plot.height,
|
|
283
|
+
props.plot.y
|
|
284
|
+
];
|
|
285
|
+
const xModel = createXScale(
|
|
286
|
+
props.data.map((point) => point.x),
|
|
287
|
+
props.xScaleType ?? "linear",
|
|
288
|
+
xRange,
|
|
289
|
+
xTickCount
|
|
290
|
+
);
|
|
291
|
+
const yValues = props.data.reduce((values, point) => {
|
|
292
|
+
if (point.y !== null && Number.isFinite(point.y)) {
|
|
293
|
+
values.push(point.y);
|
|
294
|
+
}
|
|
295
|
+
return values;
|
|
296
|
+
}, []);
|
|
297
|
+
const yDomain = props.yAxis?.domain ?? getNumericDomain(yValues);
|
|
298
|
+
const d3YScale = scaleLinear().domain(yDomain).range(yRange);
|
|
299
|
+
if (!props.yAxis?.domain && yTickCount > 0) {
|
|
300
|
+
d3YScale.nice(yTickCount);
|
|
301
|
+
}
|
|
302
|
+
const resolvedYDomain = d3YScale.domain();
|
|
303
|
+
const yScale = (value) => d3YScale(value);
|
|
304
|
+
const coordinates = createLineChartCoordinates(
|
|
305
|
+
props.data,
|
|
306
|
+
xModel.scale,
|
|
307
|
+
yScale
|
|
308
|
+
);
|
|
309
|
+
return {
|
|
310
|
+
xDomain: xModel.domain,
|
|
311
|
+
yDomain: resolvedYDomain,
|
|
312
|
+
xTicks: xModel.ticks,
|
|
313
|
+
yTicks: d3YScale.ticks(yTickCount),
|
|
314
|
+
coordinates,
|
|
315
|
+
xScale: xModel.scale,
|
|
316
|
+
yScale
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
function createLineChartCoordinates(data, xScale, yScale) {
|
|
320
|
+
return data.map((datum, index) => {
|
|
321
|
+
const x = xScale(datum.x);
|
|
322
|
+
const y = datum.y === null ? void 0 : yScale(datum.y);
|
|
323
|
+
return {
|
|
324
|
+
datum,
|
|
325
|
+
index,
|
|
326
|
+
x: isFiniteCoordinate(x) ? x : null,
|
|
327
|
+
y: isFiniteCoordinate(y) ? y : null
|
|
328
|
+
};
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
function createXScale(values, scaleType, range, tickCount) {
|
|
332
|
+
if (scaleType === "point") {
|
|
333
|
+
const d3Scale2 = scalePoint().domain(values).range(range);
|
|
334
|
+
const domain = d3Scale2.domain();
|
|
335
|
+
return {
|
|
336
|
+
domain,
|
|
337
|
+
ticks: selectPointTicks(domain, tickCount),
|
|
338
|
+
scale: (value) => d3Scale2(value)
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
if (scaleType === "time") {
|
|
342
|
+
const dates = values.filter(
|
|
343
|
+
(value) => value instanceof Date && Number.isFinite(value.getTime())
|
|
344
|
+
);
|
|
345
|
+
const [minimum, maximum] = extent(dates);
|
|
346
|
+
const domain = minimum && maximum ? [minimum, maximum] : [/* @__PURE__ */ new Date(0), /* @__PURE__ */ new Date(1)];
|
|
347
|
+
const d3Scale2 = scaleTime().domain(domain).range(range);
|
|
348
|
+
if (tickCount > 0) {
|
|
349
|
+
d3Scale2.nice(tickCount);
|
|
350
|
+
}
|
|
351
|
+
return {
|
|
352
|
+
domain: d3Scale2.domain(),
|
|
353
|
+
ticks: d3Scale2.ticks(tickCount),
|
|
354
|
+
scale: (value) => value instanceof Date && Number.isFinite(value.getTime()) ? d3Scale2(value) : void 0
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
const numbers = values.filter(
|
|
358
|
+
(value) => typeof value === "number" && Number.isFinite(value)
|
|
359
|
+
);
|
|
360
|
+
const d3Scale = scaleLinear().domain(getNumericDomain(numbers)).range(range);
|
|
361
|
+
if (tickCount > 0) {
|
|
362
|
+
d3Scale.nice(tickCount);
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
domain: d3Scale.domain(),
|
|
366
|
+
ticks: d3Scale.ticks(tickCount),
|
|
367
|
+
scale: (value) => typeof value === "number" && Number.isFinite(value) ? d3Scale(value) : void 0
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
function getNumericDomain(values) {
|
|
371
|
+
const [minimum, maximum] = extent(values);
|
|
372
|
+
return minimum === void 0 || maximum === void 0 ? LineChartDefaultNumericDomain : [minimum, maximum];
|
|
373
|
+
}
|
|
374
|
+
function getTickCount(tickCount) {
|
|
375
|
+
return tickCount === void 0 || !Number.isFinite(tickCount) ? LineChartDefaultTickCount : Math.max(0, Math.floor(tickCount));
|
|
376
|
+
}
|
|
377
|
+
function selectPointTicks(values, tickCount) {
|
|
378
|
+
if (tickCount <= 0 || values.length === 0) {
|
|
379
|
+
return [];
|
|
380
|
+
}
|
|
381
|
+
if (values.length <= tickCount) {
|
|
382
|
+
return [...values];
|
|
383
|
+
}
|
|
384
|
+
if (tickCount === 1) {
|
|
385
|
+
return [values[0]];
|
|
386
|
+
}
|
|
387
|
+
const lastIndex = values.length - 1;
|
|
388
|
+
return Array.from({ length: tickCount }, (_, index) => {
|
|
389
|
+
const valueIndex = Math.round(index * lastIndex / (tickCount - 1));
|
|
390
|
+
return values[valueIndex];
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
function isFiniteCoordinate(value) {
|
|
394
|
+
return value !== void 0 && Number.isFinite(value);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// src/utils/multi-line-chart.util.ts
|
|
398
|
+
function createDrawableMultiLineChartSeries(series, index, plot) {
|
|
399
|
+
const width = series.line?.width ?? LineDefaultWidth;
|
|
400
|
+
const linePlot = createInsetRect(plot, width / 2);
|
|
401
|
+
return {
|
|
402
|
+
...series,
|
|
403
|
+
coordinates: fitLineCoordinatesToRect(series.coordinates, plot, linePlot),
|
|
404
|
+
line: {
|
|
405
|
+
...series.line,
|
|
406
|
+
color: series.line?.color ?? LineDefaultColors[index % LineDefaultColors.length] ?? LineDefaultColor
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// src/utils/paragraph-builder.util.ts
|
|
412
|
+
import {
|
|
413
|
+
Skia as Skia3
|
|
414
|
+
} from "@shopify/react-native-skia";
|
|
415
|
+
function createParagraphBuilder(props) {
|
|
416
|
+
if (props.typefaceProvider) {
|
|
417
|
+
return Skia3.ParagraphBuilder.Make(
|
|
418
|
+
props.paragraphStyle,
|
|
419
|
+
props.typefaceProvider
|
|
420
|
+
);
|
|
421
|
+
}
|
|
422
|
+
return Skia3.ParagraphBuilder.Make(props.paragraphStyle);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// src/components/primitives/grid.tsx
|
|
426
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
427
|
+
var Grid = memo(function Grid2(props) {
|
|
428
|
+
const { options, plot, theme, xScale, xTicks, yScale, yTicks } = props;
|
|
429
|
+
const xStyle = useMemo(
|
|
430
|
+
() => resolveGridLineOptions(
|
|
431
|
+
options?.x,
|
|
432
|
+
GridDefaultXVisible,
|
|
433
|
+
theme.colors.border.subtle.value
|
|
434
|
+
),
|
|
435
|
+
[options?.x, theme.colors.border.subtle.value]
|
|
436
|
+
);
|
|
437
|
+
const yStyle = useMemo(
|
|
438
|
+
() => resolveGridLineOptions(
|
|
439
|
+
options?.y,
|
|
440
|
+
GridDefaultYVisible,
|
|
441
|
+
theme.colors.border.subtle.value
|
|
442
|
+
),
|
|
443
|
+
[options?.y, theme.colors.border.subtle.value]
|
|
444
|
+
);
|
|
445
|
+
const xPath = useMemo(
|
|
446
|
+
() => createVerticalGridPath(xTicks, xScale, plot),
|
|
447
|
+
[plot, xScale, xTicks]
|
|
448
|
+
);
|
|
449
|
+
const yPath = useMemo(
|
|
450
|
+
() => createHorizontalGridPath(yTicks, yScale, plot),
|
|
451
|
+
[plot, yScale, yTicks]
|
|
452
|
+
);
|
|
453
|
+
return /* @__PURE__ */ jsxs(Group, { children: [
|
|
454
|
+
xStyle.visible && xPath ? /* @__PURE__ */ jsx(
|
|
455
|
+
Path,
|
|
456
|
+
{
|
|
457
|
+
path: xPath,
|
|
458
|
+
color: xStyle.color,
|
|
459
|
+
opacity: xStyle.opacity,
|
|
460
|
+
strokeWidth: xStyle.width,
|
|
461
|
+
style: "stroke",
|
|
462
|
+
children: xStyle.dash?.length ? /* @__PURE__ */ jsx(DashPathEffect, { intervals: [...xStyle.dash] }) : null
|
|
463
|
+
}
|
|
464
|
+
) : null,
|
|
465
|
+
yStyle.visible && yPath ? /* @__PURE__ */ jsx(
|
|
466
|
+
Path,
|
|
467
|
+
{
|
|
468
|
+
path: yPath,
|
|
469
|
+
color: yStyle.color,
|
|
470
|
+
opacity: yStyle.opacity,
|
|
471
|
+
strokeWidth: yStyle.width,
|
|
472
|
+
style: "stroke",
|
|
473
|
+
children: yStyle.dash?.length ? /* @__PURE__ */ jsx(DashPathEffect, { intervals: [...yStyle.dash] }) : null
|
|
474
|
+
}
|
|
475
|
+
) : null
|
|
476
|
+
] });
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
// src/components/primitives/label.tsx
|
|
480
|
+
import { useMemo as useMemo2 } from "react";
|
|
481
|
+
import {
|
|
482
|
+
Group as Group2,
|
|
483
|
+
Paragraph,
|
|
484
|
+
Skia as Skia4
|
|
485
|
+
} from "@shopify/react-native-skia";
|
|
486
|
+
import { memo as memo2 } from "@impulse-ui-native/core";
|
|
487
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
488
|
+
var Label = memo2(function Label2(props) {
|
|
489
|
+
const {
|
|
490
|
+
color,
|
|
491
|
+
fontManager,
|
|
492
|
+
fontSize,
|
|
493
|
+
fontFamily,
|
|
494
|
+
fontWeight,
|
|
495
|
+
horizontalAlign = LabelDefaultHorizontalAlignment,
|
|
496
|
+
rect,
|
|
497
|
+
rotation = 0,
|
|
498
|
+
text,
|
|
499
|
+
theme,
|
|
500
|
+
tnum,
|
|
501
|
+
maxLines = 1,
|
|
502
|
+
verticalAlign = LabelDefaultVerticalAlignment
|
|
503
|
+
} = props;
|
|
504
|
+
const paragraph = useMemo2(() => {
|
|
505
|
+
const fontFeatures = [];
|
|
506
|
+
if (tnum) {
|
|
507
|
+
fontFeatures.push(TabularNumsFeature);
|
|
508
|
+
}
|
|
509
|
+
const textStyle = {
|
|
510
|
+
color: Skia4.Color(color ?? theme.colors.text.secondary),
|
|
511
|
+
fontSize: fontSize ?? theme.fontSize.xs,
|
|
512
|
+
fontFeatures
|
|
513
|
+
};
|
|
514
|
+
if (fontFamily) {
|
|
515
|
+
textStyle.fontFamilies = [fontFamily];
|
|
516
|
+
}
|
|
517
|
+
if (fontWeight !== void 0) {
|
|
518
|
+
textStyle.fontStyle = { weight: fontWeight };
|
|
519
|
+
}
|
|
520
|
+
const result = createParagraphBuilder({
|
|
521
|
+
paragraphStyle: {
|
|
522
|
+
ellipsis: "\u2026",
|
|
523
|
+
maxLines: Math.max(1, Math.floor(maxLines)),
|
|
524
|
+
textAlign: getLabelTextAlign(horizontalAlign)
|
|
525
|
+
},
|
|
526
|
+
typefaceProvider: fontManager
|
|
527
|
+
}).pushStyle(textStyle).addText(text).pop().build();
|
|
528
|
+
result.layout(rect.width);
|
|
529
|
+
return result;
|
|
530
|
+
}, [
|
|
531
|
+
color,
|
|
532
|
+
fontManager,
|
|
533
|
+
fontFamily,
|
|
534
|
+
fontSize,
|
|
535
|
+
fontWeight,
|
|
536
|
+
horizontalAlign,
|
|
537
|
+
rect.width,
|
|
538
|
+
text,
|
|
539
|
+
theme.colors.text.secondary,
|
|
540
|
+
theme.fontSize.xs,
|
|
541
|
+
tnum,
|
|
542
|
+
maxLines
|
|
543
|
+
]);
|
|
544
|
+
const rotationProps = useMemo2(
|
|
545
|
+
() => ({
|
|
546
|
+
origin: {
|
|
547
|
+
x: rect.x + rect.width / 2,
|
|
548
|
+
y: rect.y + rect.height / 2
|
|
549
|
+
},
|
|
550
|
+
transform: [{ rotate: rotation * Math.PI / 180 }]
|
|
551
|
+
}),
|
|
552
|
+
[rect.height, rect.width, rect.x, rect.y, rotation]
|
|
553
|
+
);
|
|
554
|
+
if (!paragraph) {
|
|
555
|
+
return null;
|
|
556
|
+
}
|
|
557
|
+
const y = getLabelY(rect, paragraph.getHeight(), verticalAlign);
|
|
558
|
+
return /* @__PURE__ */ jsx2(Group2, { origin: rotationProps.origin, transform: rotationProps.transform, children: /* @__PURE__ */ jsx2(Paragraph, { paragraph, x: rect.x, y, width: rect.width }) });
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
// src/components/primitives/line.tsx
|
|
562
|
+
import { useMemo as useMemo3 } from "react";
|
|
563
|
+
import { DashPathEffect as DashPathEffect2, Path as Path2 } from "@shopify/react-native-skia";
|
|
564
|
+
import { memo as memo3 } from "@impulse-ui-native/core";
|
|
565
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
566
|
+
var Line = memo3(function Line2(props) {
|
|
567
|
+
const {
|
|
568
|
+
cap = LineDefaultCap,
|
|
569
|
+
color = LineDefaultColor,
|
|
570
|
+
coordinates,
|
|
571
|
+
curve = LineDefaultCurve,
|
|
572
|
+
dash,
|
|
573
|
+
join = LineDefaultJoin,
|
|
574
|
+
opacity = LineDefaultOpacity,
|
|
575
|
+
visible = true,
|
|
576
|
+
width = LineDefaultWidth
|
|
577
|
+
} = props;
|
|
578
|
+
const path = useMemo3(
|
|
579
|
+
() => createLinePath(coordinates, curve),
|
|
580
|
+
[coordinates, curve]
|
|
581
|
+
);
|
|
582
|
+
if (!visible || !path) {
|
|
583
|
+
return null;
|
|
584
|
+
}
|
|
585
|
+
return /* @__PURE__ */ jsx3(
|
|
586
|
+
Path2,
|
|
587
|
+
{
|
|
588
|
+
path,
|
|
589
|
+
color,
|
|
590
|
+
opacity,
|
|
591
|
+
strokeWidth: width,
|
|
592
|
+
style: "stroke",
|
|
593
|
+
strokeCap: cap,
|
|
594
|
+
strokeJoin: join,
|
|
595
|
+
children: dash?.length ? /* @__PURE__ */ jsx3(DashPathEffect2, { intervals: [...dash] }) : null
|
|
596
|
+
}
|
|
597
|
+
);
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
// src/components/primitives/x-axis.tsx
|
|
601
|
+
import { Fragment, useMemo as useMemo4 } from "react";
|
|
602
|
+
import {
|
|
603
|
+
DashPathEffect as DashPathEffect3,
|
|
604
|
+
Group as Group3,
|
|
605
|
+
Line as SkiaLine
|
|
606
|
+
} from "@shopify/react-native-skia";
|
|
607
|
+
import { memo as memo4 } from "@impulse-ui-native/core";
|
|
608
|
+
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
609
|
+
var XAxis = memo4(function XAxis2(props) {
|
|
610
|
+
const {
|
|
611
|
+
fontManager,
|
|
612
|
+
lineVisible = true,
|
|
613
|
+
options,
|
|
614
|
+
plot,
|
|
615
|
+
region,
|
|
616
|
+
scale,
|
|
617
|
+
theme,
|
|
618
|
+
ticks,
|
|
619
|
+
tickVisible = true
|
|
620
|
+
} = props;
|
|
621
|
+
const line = options?.line;
|
|
622
|
+
const tick = options?.tick;
|
|
623
|
+
const label = options?.label;
|
|
624
|
+
const tickLength = tick?.length ?? AxisDefaultTickLength;
|
|
625
|
+
const labelGap = label?.gap ?? AxisDefaultLabelGap;
|
|
626
|
+
const fontSize = label?.fontSize ?? theme.fontSize.xs;
|
|
627
|
+
const layout = useMemo4(
|
|
628
|
+
() => createXAxisLayout({
|
|
629
|
+
values: ticks,
|
|
630
|
+
scale,
|
|
631
|
+
plot,
|
|
632
|
+
region,
|
|
633
|
+
tickLength,
|
|
634
|
+
labelGap
|
|
635
|
+
}),
|
|
636
|
+
[labelGap, plot, region, scale, tickLength, ticks]
|
|
637
|
+
);
|
|
638
|
+
return /* @__PURE__ */ jsxs2(Group3, { children: [
|
|
639
|
+
lineVisible && line?.visible !== false ? /* @__PURE__ */ jsx4(
|
|
640
|
+
SkiaLine,
|
|
641
|
+
{
|
|
642
|
+
p1: layout.line.start,
|
|
643
|
+
p2: layout.line.end,
|
|
644
|
+
color: line?.color ?? theme.colors.border.default.value,
|
|
645
|
+
opacity: line?.opacity ?? AxisDefaultOpacity,
|
|
646
|
+
strokeWidth: line?.width ?? AxisDefaultWidth,
|
|
647
|
+
children: line?.dash?.length ? /* @__PURE__ */ jsx4(DashPathEffect3, { intervals: [...line.dash] }) : null
|
|
648
|
+
}
|
|
649
|
+
) : null,
|
|
650
|
+
layout.ticks.map((tick2, index) => /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
651
|
+
tickVisible && options?.tick?.visible !== false ? /* @__PURE__ */ jsx4(
|
|
652
|
+
SkiaLine,
|
|
653
|
+
{
|
|
654
|
+
p1: tick2.start,
|
|
655
|
+
p2: tick2.end,
|
|
656
|
+
color: options?.tick?.color ?? theme.colors.border.default.value,
|
|
657
|
+
opacity: options?.tick?.opacity ?? AxisDefaultOpacity,
|
|
658
|
+
strokeWidth: options?.tick?.width ?? AxisDefaultWidth,
|
|
659
|
+
children: options?.tick?.dash?.length ? /* @__PURE__ */ jsx4(DashPathEffect3, { intervals: [...options.tick.dash] }) : null
|
|
660
|
+
}
|
|
661
|
+
) : null,
|
|
662
|
+
label?.visible !== false ? /* @__PURE__ */ jsx4(
|
|
663
|
+
Label,
|
|
664
|
+
{
|
|
665
|
+
text: formatAxisTick(tick2.value, options?.format),
|
|
666
|
+
rect: tick2.labelRect,
|
|
667
|
+
horizontalAlign: "center",
|
|
668
|
+
color: label?.color,
|
|
669
|
+
fontSize,
|
|
670
|
+
fontFamily: label?.fontFamily,
|
|
671
|
+
fontWeight: label?.fontWeight,
|
|
672
|
+
fontManager,
|
|
673
|
+
maxLines: label?.maxLines,
|
|
674
|
+
rotation: label?.rotation,
|
|
675
|
+
theme,
|
|
676
|
+
tnum: typeof tick2.value === "number"
|
|
677
|
+
}
|
|
678
|
+
) : null
|
|
679
|
+
] }, `${String(tick2.value)}-${index}`))
|
|
680
|
+
] });
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
// src/components/primitives/y-axis.tsx
|
|
684
|
+
import { Fragment as Fragment2, useMemo as useMemo5 } from "react";
|
|
685
|
+
import {
|
|
686
|
+
DashPathEffect as DashPathEffect4,
|
|
687
|
+
Group as Group4,
|
|
688
|
+
Line as SkiaLine2
|
|
689
|
+
} from "@shopify/react-native-skia";
|
|
690
|
+
import { memo as memo5 } from "@impulse-ui-native/core";
|
|
691
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
692
|
+
var YAxis = memo5(function YAxis2(props) {
|
|
693
|
+
const {
|
|
694
|
+
fontManager,
|
|
695
|
+
lineVisible = true,
|
|
696
|
+
options,
|
|
697
|
+
plot,
|
|
698
|
+
region,
|
|
699
|
+
scale,
|
|
700
|
+
theme,
|
|
701
|
+
ticks,
|
|
702
|
+
tickVisible = true
|
|
703
|
+
} = props;
|
|
704
|
+
const line = options?.line;
|
|
705
|
+
const tick = options?.tick;
|
|
706
|
+
const label = options?.label;
|
|
707
|
+
const tickLength = tick?.length ?? AxisDefaultTickLength;
|
|
708
|
+
const labelGap = label?.gap ?? AxisDefaultLabelGap;
|
|
709
|
+
const fontSize = label?.fontSize ?? theme.fontSize.xs;
|
|
710
|
+
const layout = useMemo5(
|
|
711
|
+
() => createYAxisLayout({
|
|
712
|
+
values: ticks,
|
|
713
|
+
scale,
|
|
714
|
+
plot,
|
|
715
|
+
region,
|
|
716
|
+
tickLength,
|
|
717
|
+
labelGap,
|
|
718
|
+
fontSize
|
|
719
|
+
}),
|
|
720
|
+
[fontSize, labelGap, plot, region, scale, tickLength, ticks]
|
|
721
|
+
);
|
|
722
|
+
return /* @__PURE__ */ jsxs3(Group4, { children: [
|
|
723
|
+
lineVisible && line?.visible !== false ? /* @__PURE__ */ jsx5(
|
|
724
|
+
SkiaLine2,
|
|
725
|
+
{
|
|
726
|
+
p1: layout.line.start,
|
|
727
|
+
p2: layout.line.end,
|
|
728
|
+
color: line?.color ?? theme.colors.border.default.value,
|
|
729
|
+
opacity: line?.opacity ?? AxisDefaultOpacity,
|
|
730
|
+
strokeWidth: line?.width ?? AxisDefaultWidth,
|
|
731
|
+
children: line?.dash?.length ? /* @__PURE__ */ jsx5(DashPathEffect4, { intervals: [...line.dash] }) : null
|
|
732
|
+
}
|
|
733
|
+
) : null,
|
|
734
|
+
layout.ticks.map((tick2, index) => /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
735
|
+
tickVisible && options?.tick?.visible !== false ? /* @__PURE__ */ jsx5(
|
|
736
|
+
SkiaLine2,
|
|
737
|
+
{
|
|
738
|
+
p1: tick2.start,
|
|
739
|
+
p2: tick2.end,
|
|
740
|
+
color: options?.tick?.color ?? theme.colors.border.default.value,
|
|
741
|
+
opacity: options?.tick?.opacity ?? AxisDefaultOpacity,
|
|
742
|
+
strokeWidth: options?.tick?.width ?? AxisDefaultWidth,
|
|
743
|
+
children: options?.tick?.dash?.length ? /* @__PURE__ */ jsx5(DashPathEffect4, { intervals: [...options.tick.dash] }) : null
|
|
744
|
+
}
|
|
745
|
+
) : null,
|
|
746
|
+
label?.visible !== false ? /* @__PURE__ */ jsx5(
|
|
747
|
+
Label,
|
|
748
|
+
{
|
|
749
|
+
text: formatAxisTick(tick2.value, options?.format),
|
|
750
|
+
rect: tick2.labelRect,
|
|
751
|
+
horizontalAlign: "right",
|
|
752
|
+
verticalAlign: "center",
|
|
753
|
+
color: label?.color,
|
|
754
|
+
fontSize,
|
|
755
|
+
fontFamily: label?.fontFamily,
|
|
756
|
+
fontWeight: label?.fontWeight,
|
|
757
|
+
fontManager,
|
|
758
|
+
maxLines: label?.maxLines,
|
|
759
|
+
rotation: label?.rotation,
|
|
760
|
+
theme,
|
|
761
|
+
tnum: true
|
|
762
|
+
}
|
|
763
|
+
) : null
|
|
764
|
+
] }, `${tick2.value}-${index}`))
|
|
765
|
+
] });
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
// src/components/line-chart.tsx
|
|
769
|
+
import { StyleSheet } from "react-native";
|
|
770
|
+
import { Canvas } from "@shopify/react-native-skia";
|
|
771
|
+
import { memo as memo7 } from "@impulse-ui-native/core";
|
|
772
|
+
import { useTheme } from "@impulse-ui-native/theme";
|
|
773
|
+
|
|
774
|
+
// src/hooks/use-chart-canvas.hook.ts
|
|
775
|
+
import { useCanvasRef, useCanvasSize } from "@shopify/react-native-skia";
|
|
776
|
+
function useChartCanvas() {
|
|
777
|
+
const ref = useCanvasRef();
|
|
778
|
+
const { size } = useCanvasSize(ref);
|
|
779
|
+
return { ref, size };
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
// src/hooks/use-line-chart.hook.ts
|
|
783
|
+
import { useMemo as useMemo6 } from "react";
|
|
784
|
+
function useLineChart(props) {
|
|
785
|
+
const { data, plot, xAxis, xScaleType, yAxis } = props;
|
|
786
|
+
return useMemo6(
|
|
787
|
+
() => createLineChartModel({ data, plot, xAxis, xScaleType, yAxis }),
|
|
788
|
+
[data, plot, xAxis, xScaleType, yAxis]
|
|
789
|
+
);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
// src/hooks/use-multi-line-chart.hook.ts
|
|
793
|
+
import { useMemo as useMemo7 } from "react";
|
|
794
|
+
function useMultiLineChart(props) {
|
|
795
|
+
const { plot, series, xAxis, xScaleType, yAxis } = props;
|
|
796
|
+
const data = useMemo7(
|
|
797
|
+
() => series.flatMap((currentSeries) => currentSeries.data),
|
|
798
|
+
[series]
|
|
799
|
+
);
|
|
800
|
+
const { xDomain, xScale, xTicks, yDomain, yScale, yTicks } = useLineChart({
|
|
801
|
+
data,
|
|
802
|
+
plot,
|
|
803
|
+
xAxis,
|
|
804
|
+
xScaleType,
|
|
805
|
+
yAxis
|
|
806
|
+
});
|
|
807
|
+
const seriesModels = useMemo7(
|
|
808
|
+
() => series.map((currentSeries) => ({
|
|
809
|
+
...currentSeries,
|
|
810
|
+
coordinates: createLineChartCoordinates(
|
|
811
|
+
currentSeries.data,
|
|
812
|
+
xScale,
|
|
813
|
+
yScale
|
|
814
|
+
)
|
|
815
|
+
})),
|
|
816
|
+
[series, xScale, yScale]
|
|
817
|
+
);
|
|
818
|
+
return useMemo7(
|
|
819
|
+
() => ({
|
|
820
|
+
series: seriesModels,
|
|
821
|
+
xDomain,
|
|
822
|
+
xScale,
|
|
823
|
+
xTicks,
|
|
824
|
+
yDomain,
|
|
825
|
+
yScale,
|
|
826
|
+
yTicks
|
|
827
|
+
}),
|
|
828
|
+
[seriesModels, xDomain, xScale, xTicks, yDomain, yScale, yTicks]
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// src/components/line-chart-body.tsx
|
|
833
|
+
import { useMemo as useMemo8 } from "react";
|
|
834
|
+
import { Group as Group5 } from "@shopify/react-native-skia";
|
|
835
|
+
import { memo as memo6 } from "@impulse-ui-native/core";
|
|
836
|
+
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
837
|
+
var LineChartBody = memo6(function LineChartBodyComponent(props) {
|
|
838
|
+
const {
|
|
839
|
+
data,
|
|
840
|
+
fontManager,
|
|
841
|
+
grid,
|
|
842
|
+
insets,
|
|
843
|
+
line,
|
|
844
|
+
size,
|
|
845
|
+
theme,
|
|
846
|
+
xAxis,
|
|
847
|
+
xScaleType,
|
|
848
|
+
yAxis
|
|
849
|
+
} = props;
|
|
850
|
+
const layout = useMemo8(() => createChartLayout(size, insets), [insets, size]);
|
|
851
|
+
const { coordinates, xScale, xTicks, yScale, yTicks } = useLineChart({
|
|
852
|
+
data,
|
|
853
|
+
plot: layout.plot,
|
|
854
|
+
xAxis,
|
|
855
|
+
xScaleType,
|
|
856
|
+
yAxis
|
|
857
|
+
});
|
|
858
|
+
const linePlot = useMemo8(
|
|
859
|
+
() => createInsetRect(layout.plot, (line?.width ?? LineDefaultWidth) / 2),
|
|
860
|
+
[layout.plot, line?.width]
|
|
861
|
+
);
|
|
862
|
+
const lineCoordinates = useMemo8(
|
|
863
|
+
() => fitLineCoordinatesToRect(coordinates, layout.plot, linePlot),
|
|
864
|
+
[coordinates, layout.plot, linePlot]
|
|
865
|
+
);
|
|
866
|
+
const isGridStyle = grid !== void 0;
|
|
867
|
+
return /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
868
|
+
isGridStyle ? /* @__PURE__ */ jsx6(
|
|
869
|
+
Grid,
|
|
870
|
+
{
|
|
871
|
+
options: grid,
|
|
872
|
+
plot: layout.plot,
|
|
873
|
+
theme,
|
|
874
|
+
xTicks,
|
|
875
|
+
xScale,
|
|
876
|
+
yTicks,
|
|
877
|
+
yScale
|
|
878
|
+
}
|
|
879
|
+
) : null,
|
|
880
|
+
xAxis?.visible !== false ? /* @__PURE__ */ jsx6(
|
|
881
|
+
XAxis,
|
|
882
|
+
{
|
|
883
|
+
ticks: xTicks,
|
|
884
|
+
scale: xScale,
|
|
885
|
+
plot: layout.plot,
|
|
886
|
+
region: layout.xAxis,
|
|
887
|
+
theme,
|
|
888
|
+
options: xAxis,
|
|
889
|
+
fontManager,
|
|
890
|
+
lineVisible: !isGridStyle,
|
|
891
|
+
tickVisible: !isGridStyle
|
|
892
|
+
}
|
|
893
|
+
) : null,
|
|
894
|
+
yAxis?.visible !== false ? /* @__PURE__ */ jsx6(
|
|
895
|
+
YAxis,
|
|
896
|
+
{
|
|
897
|
+
ticks: yTicks,
|
|
898
|
+
scale: yScale,
|
|
899
|
+
plot: layout.plot,
|
|
900
|
+
region: layout.yAxis,
|
|
901
|
+
theme,
|
|
902
|
+
options: yAxis,
|
|
903
|
+
fontManager,
|
|
904
|
+
lineVisible: !isGridStyle,
|
|
905
|
+
tickVisible: !isGridStyle
|
|
906
|
+
}
|
|
907
|
+
) : null,
|
|
908
|
+
/* @__PURE__ */ jsx6(Group5, { clip: layout.plot, children: /* @__PURE__ */ jsx6(Line, { coordinates: lineCoordinates, ...line }) })
|
|
909
|
+
] });
|
|
910
|
+
});
|
|
911
|
+
|
|
912
|
+
// src/components/line-chart.tsx
|
|
913
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
914
|
+
var LineChart = memo7(function LineChart2(props) {
|
|
915
|
+
const theme = useTheme();
|
|
916
|
+
const { ref, size } = useChartCanvas();
|
|
917
|
+
return /* @__PURE__ */ jsx7(Canvas, { ref, style: styles.container, children: /* @__PURE__ */ jsx7(LineChartBody, { ...props, size, theme }) });
|
|
918
|
+
});
|
|
919
|
+
var styles = StyleSheet.create({
|
|
920
|
+
container: {
|
|
921
|
+
flex: 1
|
|
922
|
+
}
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
// src/components/multi-line-chart.tsx
|
|
926
|
+
import { StyleSheet as StyleSheet2 } from "react-native";
|
|
927
|
+
import { Canvas as Canvas2 } from "@shopify/react-native-skia";
|
|
928
|
+
import { memo as memo9 } from "@impulse-ui-native/core";
|
|
929
|
+
import { useTheme as useTheme2 } from "@impulse-ui-native/theme";
|
|
930
|
+
|
|
931
|
+
// src/components/multi-line-chart-body.tsx
|
|
932
|
+
import { useMemo as useMemo9 } from "react";
|
|
933
|
+
import { Group as Group6 } from "@shopify/react-native-skia";
|
|
934
|
+
import { memo as memo8 } from "@impulse-ui-native/core";
|
|
935
|
+
import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
936
|
+
var MultiLineChartBody = memo8(function MultiLineChartBodyComponent(props) {
|
|
937
|
+
const {
|
|
938
|
+
fontManager,
|
|
939
|
+
grid,
|
|
940
|
+
insets,
|
|
941
|
+
series,
|
|
942
|
+
size,
|
|
943
|
+
theme,
|
|
944
|
+
xAxis,
|
|
945
|
+
xScaleType,
|
|
946
|
+
yAxis
|
|
947
|
+
} = props;
|
|
948
|
+
const layout = useMemo9(() => createChartLayout(size, insets), [insets, size]);
|
|
949
|
+
const {
|
|
950
|
+
series: seriesModels,
|
|
951
|
+
xScale,
|
|
952
|
+
xTicks,
|
|
953
|
+
yScale,
|
|
954
|
+
yTicks
|
|
955
|
+
} = useMultiLineChart({
|
|
956
|
+
plot: layout.plot,
|
|
957
|
+
series,
|
|
958
|
+
xAxis,
|
|
959
|
+
xScaleType,
|
|
960
|
+
yAxis
|
|
961
|
+
});
|
|
962
|
+
const drawableSeries = useMemo9(
|
|
963
|
+
() => seriesModels.map(
|
|
964
|
+
(currentSeries, index) => createDrawableMultiLineChartSeries(currentSeries, index, layout.plot)
|
|
965
|
+
),
|
|
966
|
+
[layout.plot, seriesModels]
|
|
967
|
+
);
|
|
968
|
+
const isGridStyle = grid !== void 0;
|
|
969
|
+
return /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
970
|
+
isGridStyle ? /* @__PURE__ */ jsx8(
|
|
971
|
+
Grid,
|
|
972
|
+
{
|
|
973
|
+
options: grid,
|
|
974
|
+
plot: layout.plot,
|
|
975
|
+
theme,
|
|
976
|
+
xTicks,
|
|
977
|
+
xScale,
|
|
978
|
+
yTicks,
|
|
979
|
+
yScale
|
|
980
|
+
}
|
|
981
|
+
) : null,
|
|
982
|
+
xAxis?.visible !== false ? /* @__PURE__ */ jsx8(
|
|
983
|
+
XAxis,
|
|
984
|
+
{
|
|
985
|
+
ticks: xTicks,
|
|
986
|
+
scale: xScale,
|
|
987
|
+
plot: layout.plot,
|
|
988
|
+
region: layout.xAxis,
|
|
989
|
+
theme,
|
|
990
|
+
options: xAxis,
|
|
991
|
+
fontManager,
|
|
992
|
+
lineVisible: !isGridStyle,
|
|
993
|
+
tickVisible: !isGridStyle
|
|
994
|
+
}
|
|
995
|
+
) : null,
|
|
996
|
+
yAxis?.visible !== false ? /* @__PURE__ */ jsx8(
|
|
997
|
+
YAxis,
|
|
998
|
+
{
|
|
999
|
+
ticks: yTicks,
|
|
1000
|
+
scale: yScale,
|
|
1001
|
+
plot: layout.plot,
|
|
1002
|
+
region: layout.yAxis,
|
|
1003
|
+
theme,
|
|
1004
|
+
options: yAxis,
|
|
1005
|
+
fontManager,
|
|
1006
|
+
lineVisible: !isGridStyle,
|
|
1007
|
+
tickVisible: !isGridStyle
|
|
1008
|
+
}
|
|
1009
|
+
) : null,
|
|
1010
|
+
/* @__PURE__ */ jsx8(Group6, { clip: layout.plot, children: drawableSeries.map((currentSeries) => /* @__PURE__ */ jsx8(
|
|
1011
|
+
Line,
|
|
1012
|
+
{
|
|
1013
|
+
coordinates: currentSeries.coordinates,
|
|
1014
|
+
...currentSeries.line
|
|
1015
|
+
},
|
|
1016
|
+
currentSeries.id
|
|
1017
|
+
)) })
|
|
1018
|
+
] });
|
|
1019
|
+
});
|
|
1020
|
+
|
|
1021
|
+
// src/components/multi-line-chart.tsx
|
|
1022
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1023
|
+
var MultiLineChart = memo9(function MultiLineChart2(props) {
|
|
1024
|
+
const theme = useTheme2();
|
|
1025
|
+
const { ref, size } = useChartCanvas();
|
|
1026
|
+
return /* @__PURE__ */ jsx9(Canvas2, { ref, style: styles2.container, children: /* @__PURE__ */ jsx9(MultiLineChartBody, { ...props, size, theme }) });
|
|
1027
|
+
});
|
|
1028
|
+
var styles2 = StyleSheet2.create({
|
|
1029
|
+
container: {
|
|
1030
|
+
flex: 1
|
|
1031
|
+
}
|
|
1032
|
+
});
|
|
3
1033
|
export {
|
|
4
|
-
|
|
1034
|
+
AxisDefaultLabelGap,
|
|
1035
|
+
AxisDefaultOpacity,
|
|
1036
|
+
AxisDefaultTickLength,
|
|
1037
|
+
AxisDefaultWidth,
|
|
1038
|
+
Grid,
|
|
1039
|
+
GridDefaultOpacity,
|
|
1040
|
+
GridDefaultWidth,
|
|
1041
|
+
GridDefaultXVisible,
|
|
1042
|
+
GridDefaultYVisible,
|
|
1043
|
+
Label,
|
|
1044
|
+
LabelDefaultHorizontalAlignment,
|
|
1045
|
+
LabelDefaultVerticalAlignment,
|
|
1046
|
+
Line,
|
|
1047
|
+
LineChart,
|
|
1048
|
+
LineChartDefaultNumericDomain,
|
|
1049
|
+
LineChartDefaultTickCount,
|
|
1050
|
+
LineDefaultCap,
|
|
1051
|
+
LineDefaultColor,
|
|
1052
|
+
LineDefaultColors,
|
|
1053
|
+
LineDefaultCurve,
|
|
1054
|
+
LineDefaultJoin,
|
|
1055
|
+
LineDefaultOpacity,
|
|
1056
|
+
LineDefaultWidth,
|
|
1057
|
+
MultiLineChart,
|
|
1058
|
+
TabularNumsFeature,
|
|
1059
|
+
XAxis,
|
|
1060
|
+
YAxis,
|
|
1061
|
+
createAxisTicks,
|
|
1062
|
+
createChartLayout,
|
|
1063
|
+
createDrawableMultiLineChartSeries,
|
|
1064
|
+
createHorizontalGridPath,
|
|
1065
|
+
createInsetRect,
|
|
1066
|
+
createLineChartCoordinates,
|
|
1067
|
+
createLineChartModel,
|
|
1068
|
+
createLinePath,
|
|
1069
|
+
createParagraphBuilder,
|
|
1070
|
+
createVerticalGridPath,
|
|
1071
|
+
createXAxisLabelRect,
|
|
1072
|
+
createXAxisLayout,
|
|
1073
|
+
createYAxisLabelRect,
|
|
1074
|
+
createYAxisLayout,
|
|
1075
|
+
fitLineCoordinatesToRect,
|
|
1076
|
+
formatAxisTick,
|
|
1077
|
+
getLabelTextAlign,
|
|
1078
|
+
getLabelY,
|
|
1079
|
+
resolveGridLineOptions,
|
|
1080
|
+
useChartCanvas,
|
|
1081
|
+
useLineChart,
|
|
1082
|
+
useMultiLineChart
|
|
5
1083
|
};
|
|
6
1084
|
//# sourceMappingURL=index.js.map
|