rn-native-ios-charts 0.2.2 → 0.2.3

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.
Files changed (2) hide show
  1. package/ios/ChartView.swift +67 -11
  2. package/package.json +1 -1
@@ -108,7 +108,7 @@ private struct ChartHostView: View {
108
108
  .customizedYAxis(config: props.yAxis)
109
109
  .conditionalChartXScale(domain: scaleDomain(props.xAxis))
110
110
  .conditionalChartYScale(domain: scaleDomain(props.yAxis))
111
- .conditionalTightX(enabled: props.tightX)
111
+ .conditionalTightX(enabled: props.tightX, xDomain: tightXDomain)
112
112
  .conditionalCategoryColors(props.categoryColors)
113
113
  .conditionalScrollable(
114
114
  enabled: props.scrollableX,
@@ -650,6 +650,28 @@ private struct ChartHostView: View {
650
650
  props.marks.flatMap { m in m.data.map(\.y) }
651
651
  }
652
652
 
653
+ /// Ordered, unique X values across every cartesian mark. Used to
654
+ /// pin the X scale's domain when `tightX` is enabled so the first
655
+ /// and last categorical values map to the literal left and right
656
+ /// edges of the plot (no half-cell insets).
657
+ ///
658
+ /// We walk marks in insertion order and skip duplicates with a
659
+ /// Set, so the resulting array preserves the data's natural left-
660
+ /// to-right ordering even when multiple series share X values.
661
+ private var tightXDomain: [String] {
662
+ var seen = Set<String>()
663
+ var out: [String] = []
664
+ for mark in props.marks
665
+ where mark.type != "sector" && mark.type != "rule" {
666
+ for point in mark.data {
667
+ if seen.insert(point.x).inserted {
668
+ out.append(point.x)
669
+ }
670
+ }
671
+ }
672
+ return out
673
+ }
674
+
653
675
  private func interpolationMethod(_ v: String) -> InterpolationMethod {
654
676
  switch v {
655
677
  case "catmullRom": return .catmullRom
@@ -855,17 +877,51 @@ private extension View {
855
877
  }
856
878
  }
857
879
 
858
- /// Trading-chart X mode: 0pt plot-dimension padding so the first
859
- /// and last data points sit flush against the chart's edges. Use
860
- /// when the axis is hidden and you want the line to bleed.
861
- /// `plotDimension` takes separate `startPadding` / `endPadding` —
862
- /// there's no single `padding:` form on this API.
880
+ /// Trading-chart X mode. Three coordinated tricks make the line /
881
+ /// area / bars reach both edges of the chart frame regardless of
882
+ /// data density:
883
+ ///
884
+ /// 1. **Explicit categorical domain** SwiftUI positions
885
+ /// categorical values at the CENTER of evenly-sized cells by
886
+ /// default (leaves a half-cell gap on each end, brutal with
887
+ /// few points). Passing the X strings as `domain:` pins the
888
+ /// first value to pixel 0 and the last to pixel-max.
889
+ ///
890
+ /// 2. **`.plotDimension(startPadding: 0, endPadding: 0)`** —
891
+ /// zeros out the scale's outer padding within the plot area.
892
+ ///
893
+ /// 3. **`chartPlotStyle { $0.frame(maxWidth: .infinity,
894
+ /// maxHeight: .infinity) }`** — forces the plot area itself to
895
+ /// fill the chart's full frame, in case SwiftUI's hidden axes
896
+ /// still reserve any space.
897
+ ///
898
+ /// All three together give the Robinhood / Apple Stocks look
899
+ /// where the chart's content truly spans edge-to-edge.
863
900
  @ViewBuilder
864
- func conditionalTightX(enabled: Bool) -> some View {
865
- if enabled {
866
- self.chartXScale(
867
- range: .plotDimension(startPadding: 0, endPadding: 0)
868
- )
901
+ func conditionalTightX(
902
+ enabled: Bool,
903
+ xDomain: [String]
904
+ ) -> some View {
905
+ if enabled && !xDomain.isEmpty {
906
+ self
907
+ .chartXScale(
908
+ domain: xDomain,
909
+ range: .plotDimension(startPadding: 0, endPadding: 0)
910
+ )
911
+ .chartPlotStyle { plot in
912
+ plot.frame(maxWidth: .infinity, maxHeight: .infinity)
913
+ }
914
+ } else if enabled {
915
+ // No data yet — apply just the range + plot expansion so the
916
+ // chart doesn't crash; once data arrives a re-render will set
917
+ // the categorical domain.
918
+ self
919
+ .chartXScale(
920
+ range: .plotDimension(startPadding: 0, endPadding: 0)
921
+ )
922
+ .chartPlotStyle { plot in
923
+ plot.frame(maxWidth: .infinity, maxHeight: .infinity)
924
+ }
869
925
  } else {
870
926
  self
871
927
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rn-native-ios-charts",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Native SwiftUI Charts for React Native / Expo. iOS-only, zero-compromise charts that bypass the limitations of cross-platform chart libraries.",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",