rn-native-ios-charts 0.1.0 → 0.2.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/CHANGELOG.md +76 -1
- package/README.md +254 -1
- package/ios/ChartConfig.swift +22 -0
- package/ios/ChartMark.swift +8 -0
- package/ios/ChartView.swift +417 -32
- package/ios/NativeIosChartsModule.swift +12 -0
- package/package.json +1 -1
- package/src/BarChart.tsx +19 -0
- package/src/Chart.tsx +18 -6
- package/src/LineChart.tsx +128 -29
- package/src/index.ts +1 -1
- package/src/types.ts +77 -2
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,80 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.2.0] — 2026-05-11
|
|
10
|
+
|
|
11
|
+
Production-grade upgrades: trading-chart props, multi-series support,
|
|
12
|
+
axis value formatters, richer tooltip + selection payloads, and an
|
|
13
|
+
axis-config bug fix that surfaced once people actually customized
|
|
14
|
+
their axes.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`tightX`** prop on `<Chart />` / `<LineChart />` / `<BarChart />`
|
|
19
|
+
— zeros out SwiftUI Charts' default plot-dimension X padding so
|
|
20
|
+
the first and last data points sit flush against the chart's left
|
|
21
|
+
and right edges. The "Robinhood / Apple Stocks" look. Pair with
|
|
22
|
+
`xAxis={{ hidden: true }}` for a clean trading-chart aesthetic.
|
|
23
|
+
- **`scrollableX`** + **`visibleXCount`** — enables SwiftUI's
|
|
24
|
+
native `chartScrollableAxes(.horizontal)` plus
|
|
25
|
+
`chartXVisibleDomain(length:)`. Use this instead of wrapping the
|
|
26
|
+
chart in an RN `<ScrollView horizontal>` — native scrolling
|
|
27
|
+
keeps tooltip coordinates correct and avoids gesture conflicts
|
|
28
|
+
with the selection scrubber.
|
|
29
|
+
- **`categoryColors`** chart-level prop — maps `category` →
|
|
30
|
+
`ColorValue`. Translates to SwiftUI's
|
|
31
|
+
`chartForegroundStyleScale`. Define a palette once at the chart
|
|
32
|
+
level instead of repeating `color` on every datum.
|
|
33
|
+
- **Axis value formatters.** `AxisConfig` now honors `valueFormat`
|
|
34
|
+
(`"raw" | "currency" | "percent" | "abbreviated" | "decimal"`),
|
|
35
|
+
`currencyCode`, `valueDecimals`, `valuePrefix`, and `valueSuffix`.
|
|
36
|
+
Common patterns:
|
|
37
|
+
```tsx
|
|
38
|
+
yAxis={{ valueFormat: "currency", currencyCode: "USD" }}
|
|
39
|
+
yAxis={{ valuePrefix: "$", valueDecimals: 0 }} // symbol-only
|
|
40
|
+
yAxis={{ valueFormat: "abbreviated" }} // 1K / 1.2M
|
|
41
|
+
yAxis={{ valueFormat: "percent" }} // 0.5 → "50%"
|
|
42
|
+
```
|
|
43
|
+
- **Multi-series tooltip.** `tooltip.multiSeries` renders one row
|
|
44
|
+
per cartesian mark at the selected X (color dot + series name +
|
|
45
|
+
formatted value). Drops to a single-row callout automatically
|
|
46
|
+
when only one mark is present. Useful for OHLC stock charts and
|
|
47
|
+
side-by-side comparisons.
|
|
48
|
+
- **`markIndex` + `pointIndex` in the `onSelect` payload.** Lets
|
|
49
|
+
consumers locate the datum in their `marks` array
|
|
50
|
+
deterministically — value-only matching is fragile when two
|
|
51
|
+
slices share the same y. Existing single-key consumers continue
|
|
52
|
+
to work; the indices are additive.
|
|
53
|
+
- **Multi-line `<LineChart>` via the new `series` prop.** Pass an
|
|
54
|
+
array of `{ name, color, data, ...overrides }` to draw multiple
|
|
55
|
+
lines on the same plot. Each series' `name` becomes the
|
|
56
|
+
`category` key, the legend label, and the row label in the
|
|
57
|
+
multi-series tooltip. The existing `data` prop still works for
|
|
58
|
+
single-series charts.
|
|
59
|
+
- **Bar chart enhancements.** Two new fields on `bar` marks (and
|
|
60
|
+
the matching `<BarChart>` props):
|
|
61
|
+
- `position: "auto" | "stacked" | "grouped"` — multi-series
|
|
62
|
+
positioning. `"stacked"` applies SwiftUI's
|
|
63
|
+
`positionAdjustment(.stacking)`; `"grouped"` applies
|
|
64
|
+
`position(by: .value("Series", category))` so bars sit
|
|
65
|
+
side-by-side.
|
|
66
|
+
- `horizontal: boolean` — swaps the X and Y axes for `bar`
|
|
67
|
+
marks. Use for Top-N lists and ranked leaderboards.
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
|
|
71
|
+
- **Axis customization fields now actually apply.** `xAxis` /
|
|
72
|
+
`yAxis` config has supported `labelColor`, `labelFontSize`,
|
|
73
|
+
`gridColor`, `gridLines`, and `tickLabels` since v0.1.0, but the
|
|
74
|
+
Swift side only toggled `.hidden` vs `.automatic` and silently
|
|
75
|
+
ignored the rest. Replaced the boolean toggle with a full
|
|
76
|
+
`AxisMarks` builder so every field is honored.
|
|
77
|
+
|
|
78
|
+
**Migration note:** if you were passing these fields and worked
|
|
79
|
+
around the lack of effect (e.g. extra padding to hide the
|
|
80
|
+
default label color), your chart will now render with the
|
|
81
|
+
requested style. Visual diffs are possible.
|
|
82
|
+
|
|
9
83
|
## [0.1.0] — 2026-05-11
|
|
10
84
|
|
|
11
85
|
Initial public release. iOS-only Expo module that bridges every SwiftUI
|
|
@@ -57,5 +131,6 @@ primitive plus convenience wrappers.
|
|
|
57
131
|
`View` so consuming code doesn't need to feature-detect. Pair with
|
|
58
132
|
`isChartSupported()` to swap in an alternative renderer.
|
|
59
133
|
|
|
60
|
-
[Unreleased]: https://github.com/abdallaemadeldin/rn-native-ios-charts/compare/v0.
|
|
134
|
+
[Unreleased]: https://github.com/abdallaemadeldin/rn-native-ios-charts/compare/v0.2.0...HEAD
|
|
135
|
+
[0.2.0]: https://github.com/abdallaemadeldin/rn-native-ios-charts/compare/v0.1.0...v0.2.0
|
|
61
136
|
[0.1.0]: https://github.com/abdallaemadeldin/rn-native-ios-charts/releases/tag/v0.1.0
|
package/README.md
CHANGED
|
@@ -136,6 +136,227 @@ import { LineChart } from "rn-native-ios-charts";
|
|
|
136
136
|
/>
|
|
137
137
|
```
|
|
138
138
|
|
|
139
|
+
## Trading-chart preset — `tightX` + hidden axes
|
|
140
|
+
|
|
141
|
+
For the Robinhood / Apple Stocks aesthetic — line flush against
|
|
142
|
+
both screen edges, no axes, no grid, deep gradient fill. The `tightX`
|
|
143
|
+
prop zeros out SwiftUI Charts' default plot-dimension padding so the
|
|
144
|
+
first and last points sit at the chart's left and right edges.
|
|
145
|
+
|
|
146
|
+
```tsx
|
|
147
|
+
import { LineChart } from "rn-native-ios-charts";
|
|
148
|
+
|
|
149
|
+
<LineChart
|
|
150
|
+
style={{ width: "100%", height: 260 }}
|
|
151
|
+
data={dailyPrice}
|
|
152
|
+
color="#1FA92E"
|
|
153
|
+
lineWidth={3}
|
|
154
|
+
interpolation="catmullRom"
|
|
155
|
+
area={{ startOpacity: 0.55, endOpacity: 0 }}
|
|
156
|
+
tightX
|
|
157
|
+
xAxis={{ hidden: true }}
|
|
158
|
+
yAxis={{ hidden: true }}
|
|
159
|
+
tooltip={{ enabled: true, valuePrefix: "$" }}
|
|
160
|
+
/>
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Multi-line charts — `<LineChart series={…} />`
|
|
164
|
+
|
|
165
|
+
Render multiple lines on the same plot by passing a `series` array
|
|
166
|
+
instead of a single `data` array. Each series has its own color and
|
|
167
|
+
its own line config (width, dash, interpolation, points, symbol,
|
|
168
|
+
area) — chart-level props act as fallbacks.
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
import { LineChart } from "rn-native-ios-charts";
|
|
172
|
+
|
|
173
|
+
<LineChart
|
|
174
|
+
// Chart-level defaults
|
|
175
|
+
lineWidth={2}
|
|
176
|
+
interpolation="catmullRom"
|
|
177
|
+
series={[
|
|
178
|
+
{
|
|
179
|
+
name: "Revenue",
|
|
180
|
+
color: "#1FA92E",
|
|
181
|
+
data: revenueByMonth,
|
|
182
|
+
area: { startOpacity: 0.4, endOpacity: 0 }, // shaded under this one
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: "Expenses",
|
|
186
|
+
color: "#F59E0B",
|
|
187
|
+
data: expensesByMonth,
|
|
188
|
+
lineWidth: 3,
|
|
189
|
+
dashArray: [6, 4], // dashed
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
name: "Forecast",
|
|
193
|
+
color: "#3B82F6",
|
|
194
|
+
data: forecastByMonth,
|
|
195
|
+
interpolation: "linear",
|
|
196
|
+
showPoints: true,
|
|
197
|
+
symbol: "diamond",
|
|
198
|
+
},
|
|
199
|
+
]}
|
|
200
|
+
tooltip={{ enabled: true, multiSeries: true, valuePrefix: "$" }}
|
|
201
|
+
/>
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Each series' `name` becomes:
|
|
205
|
+
|
|
206
|
+
- the `category` key on every point (so SwiftUI groups them into one
|
|
207
|
+
continuous line),
|
|
208
|
+
- the legend label, and
|
|
209
|
+
- the row label in the multi-series tooltip (see below).
|
|
210
|
+
|
|
211
|
+
The single-series `data` prop still works for one-line charts — pass
|
|
212
|
+
either `data` **or** `series`, not both. If both, `series` wins.
|
|
213
|
+
|
|
214
|
+
## Multi-series tooltip
|
|
215
|
+
|
|
216
|
+
Pair multi-line charts with `tooltip.multiSeries` to get a stacked-row
|
|
217
|
+
callout: one row per cartesian mark at the selected X, each with the
|
|
218
|
+
series' color dot, name, and formatted value.
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
<LineChart
|
|
222
|
+
series={[ /* multiple series as above */ ]}
|
|
223
|
+
tooltip={{
|
|
224
|
+
enabled: true,
|
|
225
|
+
multiSeries: true, // <-- enables the stacked-row callout
|
|
226
|
+
valuePrefix: "$",
|
|
227
|
+
backgroundColor: "#161618",
|
|
228
|
+
textColor: "#FFFFFF",
|
|
229
|
+
borderColor: "#2A2A2D",
|
|
230
|
+
}}
|
|
231
|
+
/>
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
When the chart has only one cartesian mark, `multiSeries` silently
|
|
235
|
+
falls back to the regular single-row tooltip — safe to leave on.
|
|
236
|
+
|
|
237
|
+
## Axis value formatters
|
|
238
|
+
|
|
239
|
+
Format the tick labels on either axis without writing custom Swift.
|
|
240
|
+
Supports four common formats plus optional prefix/suffix; works on
|
|
241
|
+
numeric axes (in practice: the Y axis, since X is `String`).
|
|
242
|
+
|
|
243
|
+
```tsx
|
|
244
|
+
<LineChart
|
|
245
|
+
data={annualRevenue}
|
|
246
|
+
yAxis={{ valueFormat: "currency", currencyCode: "USD" }}
|
|
247
|
+
/>
|
|
248
|
+
|
|
249
|
+
<LineChart
|
|
250
|
+
data={percentReturns}
|
|
251
|
+
yAxis={{ valueFormat: "percent" }} // 0.5 → "50%"
|
|
252
|
+
/>
|
|
253
|
+
|
|
254
|
+
<LineChart
|
|
255
|
+
data={networthOverTime}
|
|
256
|
+
yAxis={{ valueFormat: "abbreviated" }} // 1K, 1.2M, 3.4B
|
|
257
|
+
/>
|
|
258
|
+
|
|
259
|
+
<LineChart
|
|
260
|
+
data={returns}
|
|
261
|
+
yAxis={{ valuePrefix: "$", valueDecimals: 0 }} // symbol-only "$50,000"
|
|
262
|
+
/>
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
| `valueFormat` | Output (en-US) | Notes |
|
|
266
|
+
| ------------- | ------------------------- | -------------------------------------- |
|
|
267
|
+
| `"raw"` (default) | `50000` | Plain number with `valueDecimals`. |
|
|
268
|
+
| `"currency"` | `$50,000.00` | Locale-aware. Uses `currencyCode`. |
|
|
269
|
+
| `"percent"` | `50%` | SwiftUI multiplies by 100 — pass `0.5` to render `"50%"`. For pre-scaled (0–100) values, use `valueSuffix: "%"` instead. |
|
|
270
|
+
| `"abbreviated"` | `50K`, `1.2M`, `3.4B` | Compact notation. |
|
|
271
|
+
| `"decimal"` | `50,000.00` | Plain decimal with thousands separators. |
|
|
272
|
+
|
|
273
|
+
`valuePrefix` / `valueSuffix` are applied after the format style, so
|
|
274
|
+
`valueFormat: "decimal" + valuePrefix: "$"` gives you symbol-only
|
|
275
|
+
currency without locale code lookups.
|
|
276
|
+
|
|
277
|
+
## Category color palettes — `categoryColors`
|
|
278
|
+
|
|
279
|
+
When your data has `category` values, set a chart-level palette
|
|
280
|
+
instead of repeating `color` on every datum. Translates to SwiftUI's
|
|
281
|
+
`chartForegroundStyleScale`.
|
|
282
|
+
|
|
283
|
+
```tsx
|
|
284
|
+
<LineChart
|
|
285
|
+
series={[
|
|
286
|
+
{ name: "Cash", data: cashData },
|
|
287
|
+
{ name: "Stocks", data: stocksData },
|
|
288
|
+
{ name: "Bonds", data: bondsData },
|
|
289
|
+
]}
|
|
290
|
+
categoryColors={{
|
|
291
|
+
Cash: "#1FA92E",
|
|
292
|
+
Stocks: "#3B82F6",
|
|
293
|
+
Bonds: "#F59E0B",
|
|
294
|
+
}}
|
|
295
|
+
/>
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Per-series `color` (or per-point `color`) always overrides
|
|
299
|
+
`categoryColors` when both are set.
|
|
300
|
+
|
|
301
|
+
## Bar charts — stacking & horizontal
|
|
302
|
+
|
|
303
|
+
`<BarChart>` (and `bar` marks on the generic `<Chart>`) accept two
|
|
304
|
+
extra fields for multi-series layouts:
|
|
305
|
+
|
|
306
|
+
```tsx
|
|
307
|
+
// Stacked bars
|
|
308
|
+
<BarChart
|
|
309
|
+
data={[
|
|
310
|
+
{ x: "Q1", y: 24, category: "Revenue" },
|
|
311
|
+
{ x: "Q1", y: 18, category: "Expenses" },
|
|
312
|
+
{ x: "Q2", y: 31, category: "Revenue" },
|
|
313
|
+
{ x: "Q2", y: 22, category: "Expenses" },
|
|
314
|
+
]}
|
|
315
|
+
position="stacked"
|
|
316
|
+
categoryColors={{ Revenue: "#1FA92E", Expenses: "#F59E0B" }}
|
|
317
|
+
/>
|
|
318
|
+
|
|
319
|
+
// Grouped (side-by-side)
|
|
320
|
+
<BarChart
|
|
321
|
+
data={/* same data */}
|
|
322
|
+
position="grouped"
|
|
323
|
+
categoryColors={{ Revenue: "#1FA92E", Expenses: "#F59E0B" }}
|
|
324
|
+
/>
|
|
325
|
+
|
|
326
|
+
// Horizontal bars — Top-N / ranked leaderboards
|
|
327
|
+
<BarChart
|
|
328
|
+
data={topAssetsByValue} // [{ x: "AAPL", y: 38000 }, ...]
|
|
329
|
+
horizontal
|
|
330
|
+
cornerRadius={4}
|
|
331
|
+
/>
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
| Prop | Effect |
|
|
335
|
+
| ------------ | ---------------------------------------------------------------------- |
|
|
336
|
+
| `position: "auto"` | SwiftUI's default. |
|
|
337
|
+
| `position: "stacked"` | Applies `.positionAdjustment(.stacking)`. |
|
|
338
|
+
| `position: "grouped"` | Applies `.position(by: .value("Series", category))`. |
|
|
339
|
+
| `horizontal: true` | Swaps X and Y on `BarMark` — labels on the Y axis. |
|
|
340
|
+
|
|
341
|
+
## Horizontal scrolling for long time series
|
|
342
|
+
|
|
343
|
+
When you have more data points than fit on screen, use SwiftUI's
|
|
344
|
+
native `chartScrollableAxes(.horizontal)` instead of wrapping the
|
|
345
|
+
chart in an RN `<ScrollView horizontal>` — that wrapper would steal
|
|
346
|
+
the scrubber's pan gesture and shift the tooltip's touch coordinates.
|
|
347
|
+
|
|
348
|
+
```tsx
|
|
349
|
+
<LineChart
|
|
350
|
+
data={twoYearsOfDailyData} // ~730 points
|
|
351
|
+
scrollableX // enables native horizontal scroll
|
|
352
|
+
visibleXCount={30} // show ~30 days per "page"
|
|
353
|
+
tooltip={{ enabled: true }} // scrubber + tooltip still work
|
|
354
|
+
/>
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
`visibleXCount` is optional — omit it (or pass 0) to let SwiftUI
|
|
358
|
+
auto-decide.
|
|
359
|
+
|
|
139
360
|
## Interactivity — native tooltips & selection
|
|
140
361
|
|
|
141
362
|
All cartesian charts (line, area, bar, point, rectangle) support
|
|
@@ -189,9 +410,24 @@ the leftmost / rightmost / topmost data points.
|
|
|
189
410
|
Fires every time the selection changes (including when it clears):
|
|
190
411
|
|
|
191
412
|
```ts
|
|
192
|
-
|
|
413
|
+
type SelectedPoint = {
|
|
414
|
+
x: string;
|
|
415
|
+
y: number;
|
|
416
|
+
/** Index of the mark this point belongs to (0-based). */
|
|
417
|
+
markIndex: number;
|
|
418
|
+
/** Index of the point within that mark's data (0-based). */
|
|
419
|
+
pointIndex: number;
|
|
420
|
+
} | null;
|
|
421
|
+
|
|
422
|
+
onSelect?: (point: SelectedPoint) => void;
|
|
193
423
|
```
|
|
194
424
|
|
|
425
|
+
The `markIndex` + `pointIndex` pair locates the datum in the caller's
|
|
426
|
+
`marks` array deterministically — value-only matching is fragile
|
|
427
|
+
when two slices or points share the same y. Pies emit the slice
|
|
428
|
+
index on tap; cartesian charts emit the first cartesian mark's
|
|
429
|
+
index for the selected X.
|
|
430
|
+
|
|
195
431
|
For pie / donut charts there's no visual callout — `onSelect` fires
|
|
196
432
|
on slice taps via `chartAngleSelection`, and the natural place to
|
|
197
433
|
display the info is the `centerLabel`:
|
|
@@ -257,8 +493,25 @@ const [center, setCenter] = useState({ value: "$148K", label: "Total" });
|
|
|
257
493
|
[Interactivity](#interactivity--native-tooltips--selection) above.
|
|
258
494
|
- `onSelect(point)`: event fired when the user picks a point via the
|
|
259
495
|
scrubber or taps a pie sector. Payload is `{ x, y }` or `null`.
|
|
496
|
+
- `tightX`: zero out plot-dimension X padding so the line / area
|
|
497
|
+
bleeds to both edges. See [Trading-chart preset](#trading-chart-preset--tightx--hidden-axes).
|
|
498
|
+
- `scrollableX` + `visibleXCount`: enable SwiftUI's native horizontal
|
|
499
|
+
scrolling. See [Horizontal scrolling](#horizontal-scrolling-for-long-time-series).
|
|
500
|
+
- `categoryColors`: map `category` strings → colors. See
|
|
501
|
+
[Category color palettes](#category-color-palettes--categorycolors).
|
|
260
502
|
- `animate`: toggle SwiftUI's native ease-in-out on data changes.
|
|
261
503
|
|
|
504
|
+
`xAxis` / `yAxis` honor every field — `labelColor`, `labelFontSize`,
|
|
505
|
+
`gridColor`, `gridLines`, `tickLabels`, plus optional `[domainMin,
|
|
506
|
+
domainMax]` and `valueFormat` / `currencyCode` / `valueDecimals` /
|
|
507
|
+
`valuePrefix` / `valueSuffix` for tick label formatting. See
|
|
508
|
+
[Axis value formatters](#axis-value-formatters). (Fully wired from
|
|
509
|
+
v0.2.0 onward — v0.1.0 silently ignored everything except `hidden`.)
|
|
510
|
+
|
|
511
|
+
Bar marks additionally accept `position: "auto" | "stacked" |
|
|
512
|
+
"grouped"` and `horizontal: boolean` — see
|
|
513
|
+
[Bar charts — stacking & horizontal](#bar-charts--stacking--horizontal).
|
|
514
|
+
|
|
262
515
|
Top-level utility:
|
|
263
516
|
|
|
264
517
|
- `isChartSupported()`: runtime feature-detection helper — `true` on
|
package/ios/ChartConfig.swift
CHANGED
|
@@ -14,6 +14,23 @@ internal struct ChartAxisConfig: Record {
|
|
|
14
14
|
/// Explicit numeric domain. Both must be set to take effect.
|
|
15
15
|
@Field var domainMin: Double?
|
|
16
16
|
@Field var domainMax: Double?
|
|
17
|
+
/// Value-label format. Only meaningful for axes whose values are
|
|
18
|
+
/// Double (in practice: the Y axis — our X axis is `String`):
|
|
19
|
+
/// - "" / "raw" — no formatting, pass through
|
|
20
|
+
/// - "currency" — locale-aware currency (`currencyCode`)
|
|
21
|
+
/// - "percent" — multiplied by 100 with "%"
|
|
22
|
+
/// - "abbreviated" — compact "1K", "1.2M", "3.4B"
|
|
23
|
+
/// - "decimal" — plain number with `decimals` fraction digits
|
|
24
|
+
@Field var valueFormat: String = ""
|
|
25
|
+
/// Used when `valueFormat == "currency"`. Default "USD".
|
|
26
|
+
@Field var currencyCode: String = "USD"
|
|
27
|
+
/// Fraction digits for numeric formatters that respect it. Default 0.
|
|
28
|
+
@Field var valueDecimals: Int = 0
|
|
29
|
+
/// Prepended to the formatted value, e.g. "$" when not using the
|
|
30
|
+
/// currency format. Useful for custom prefixes/suffixes.
|
|
31
|
+
@Field var valuePrefix: String = ""
|
|
32
|
+
/// Appended to the formatted value, e.g. "%" or " years".
|
|
33
|
+
@Field var valueSuffix: String = ""
|
|
17
34
|
|
|
18
35
|
init() {}
|
|
19
36
|
}
|
|
@@ -56,6 +73,11 @@ internal struct ChartTooltipConfig: Record {
|
|
|
56
73
|
@Field var showDot: Bool = true
|
|
57
74
|
/// Show the x label above the y value in the callout.
|
|
58
75
|
@Field var showTitle: Bool = true
|
|
76
|
+
/// Render one row per mark at the selected X (color dot + series
|
|
77
|
+
/// name + value). Falls back to single-row mode when the chart has
|
|
78
|
+
/// only one cartesian mark anyway. Useful for OHLC stock charts
|
|
79
|
+
/// and side-by-side series comparisons.
|
|
80
|
+
@Field var multiSeries: Bool = false
|
|
59
81
|
@Field var backgroundColor: UIColor?
|
|
60
82
|
@Field var textColor: UIColor?
|
|
61
83
|
@Field var borderColor: UIColor?
|
package/ios/ChartMark.swift
CHANGED
|
@@ -43,6 +43,14 @@ internal struct ChartMark: Record {
|
|
|
43
43
|
@Field var cornerRadius: Double = 0
|
|
44
44
|
/// Bar width (pt). 0 = auto.
|
|
45
45
|
@Field var barWidth: Double = 0
|
|
46
|
+
/// Bar positioning when multiple BarMarks share an X:
|
|
47
|
+
/// - "auto" (default) — SwiftUI's default behavior
|
|
48
|
+
/// - "stacked" — explicit `.positionAdjustment(.stacking)`
|
|
49
|
+
/// - "grouped" — side-by-side via `.position(by: category)`
|
|
50
|
+
@Field var position: String = "auto"
|
|
51
|
+
/// Horizontal bars — swap the X and Y axes for `bar` marks. Use
|
|
52
|
+
/// for Top-N lists, ranked leaderboards, etc.
|
|
53
|
+
@Field var horizontal: Bool = false
|
|
46
54
|
|
|
47
55
|
// ─── Sector (pie / donut) ───
|
|
48
56
|
/// Inner radius as a ratio of outer, 0–1. 0 = full pie, 0.62 = thin donut.
|