Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Documentation

on:
pull_request:
paths:
- ".github/workflows/docs.yml"
- "CHANGELOG.md"
- "Package.swift"
- "README.md"
- "Sources/**"
- "docs/**"
push:
branches:
- main
paths:
- ".github/workflows/docs.yml"
- "CHANGELOG.md"
- "Package.swift"
- "README.md"
- "Sources/**"
- "docs/**"

jobs:
docbuild:
runs-on: macos-latest

steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Build DocC catalog
run: |
xcodebuild docbuild \
-scheme SimpleChart \
-destination 'platform=macOS' \
-derivedDataPath .build/DerivedData \
CODE_SIGNING_ALLOWED=NO
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
- Public interaction helper types: `SCChartSelectionState`, `SCChartInspectionOverlay`, `SCChartScrollBehavior`, `SCChartGestureConfiguration`, and `SCChartHoverState`.
- Viewport coordination helpers for centered, clamped, and zoomed visible-window updates.
- Focused tests for the interaction-helper slice, including interaction helper state, wrapper configuration, and viewport utilities.
- Zoomable navigation helpers: `SCChartTimeViewport`, `SCChartZoomBehavior`, and `SCChartNavigationCoordinator`.
- Viewport-driven zoom support for `SCScrollableLineChart` and `SCScrollableTimeSeriesChart`, including focused tests for indexed and time-series navigation state.
- Helper-style annotation presets for caption, badge, and formatted value-label rendering via `SCChartAnnotation`.
- Availability-gated `SCSelectableSectorChart` and `SCSelectableDonutChart` wrappers for `SectorMark` angle-selection workflows on newer OS versions.
- Focused tests for selectable sector/donut wrapper configuration and annotation helper presets.
Expand All @@ -33,6 +35,8 @@
- Visible-domain and scroll-behavior presets for analytics- and finance-style windows.
- Focused tests for inspection-wrapper configuration and time-series selection state.
- A new `docs/tutorials/` learning path with sequenced tutorials for first chart setup, helper-first data construction, interactions, time-series, composed charts, and legacy migration.
- A first-party `SimpleChart.docc` catalog with package overview and focused articles for getting started, wrapper selection, interactive charts, and legacy migration.
- A contributor-facing `docs/editor-support.md` guide covering Xcode Quick Help, local DocC builds, and `sourcekit-lsp` usage.
- Availability-gated vectorized plot wrappers: `SCNativeLinePlotChart`, `SCNativeAreaPlotChart`, `SCNativeBarPlotChart`, `SCNativePointPlotChart`, and `SCNativeRectanglePlotChart`.
- Availability-gated function and parametric plot wrappers: `SCNativeFunctionLinePlotChart`, `SCNativeParametricLinePlotChart`, and `SCNativeFunctionAreaPlotChart`.
- Availability-gated 3D wrappers and helpers: `SCChart3DPoint`, `SCChart3DPoseStyle`, `SCChart3DSeriesStyle`, `SCNative3DPointChart`, `SCNative3DRectangleChart`, `SCNative3DRuleChart`, and `SCNativeSurfacePlotChart`.
Expand All @@ -47,7 +51,8 @@

### Changed

- Added Xcode Quick Help documentation to the first-discovery public API surface so the core models, styles, composition entrypoints, and primary wrappers are easier to explore directly from Xcode.
- Added Xcode Quick Help documentation across the full exposed package API surface, including the native wrapper/helper layer and the deprecated compatibility layer, so every public type and entry point is easier to discover directly from Xcode.
- Added richer Quick Help coverage for the zoom/navigation surface, including `SCChartTimeViewport`, `SCChartScrollBehavior`, `SCChartZoomBehavior`, and the scrollable interactive wrappers.
- Raised minimum supported platform versions to Swift Charts baselines:
- iOS 16+
- macOS 13+
Expand All @@ -66,7 +71,9 @@
- Refactored composed-chart annotation rendering and sector-selection overlays to use the shared `SCChartAnnotationLabelView` helper path.
- Refactored selection and hover inspection rendering to share the same callout and value-label helper path.
- Reworked the documentation entrypoint around a real quick-start flow, with dedicated getting-started and chart-selection guides for new users.
- Added repository-level documentation discovery links for the DocC catalog and editor support guide, plus a CI docbuild path for keeping the package documentation healthy.
- Expanded the README wrapper catalog and coverage/status sections to include the vectorized plot and 3D chart surface.
- Updated the scrolling and time-series docs to show viewport-based zoom configuration for indexed and date-based interactive wrappers.

### Deprecated

Expand Down
23 changes: 19 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ If you are new to the package, start here instead of reading the full README top
3. Use the focused guides below when you need the next step

- [Getting Started](docs/getting-started.md)
- [DocC Catalog Source](Sources/SimpleChart/SimpleChart.docc/SimpleChart.md)
- [Tutorials](docs/tutorials/README.md)
- [Chart Selection Guide](docs/chart-selection-guide.md)
- [Editor Support](docs/editor-support.md)
- [Migration from the legacy API](#migration-from-the-legacy-api)

## Platform requirements
Expand Down Expand Up @@ -41,10 +43,10 @@ The native layer is built around a small shared model surface:
- `SCChartSectorSegment` for sector and donut charts
- `SCChartBarGroup` and `SCChartStackSegment` for grouped and stacked bars
- `SCChartTimePoint` for time-series datasets
- `SCChartVisibleDomain` and `SCChartViewport` for scroll-window helpers
- `SCChartVisibleDomain`, `SCChartViewport`, and `SCChartTimeViewport` for scroll-window helpers
- `SCChartNumericValueFormat` and `SCChartDateValueFormat` for helper-style axis formatting
- `SCChartSelection` for wrapper-managed chart selection state
- `SCChartSelectionState`, `SCChartInspectionOverlay`, `SCChartScrollBehavior`, `SCChartGestureConfiguration`, and `SCChartHoverState` for reusable interaction configuration
- `SCChartSelectionState`, `SCChartInspectionOverlay`, `SCChartScrollBehavior`, `SCChartZoomBehavior`, `SCChartGestureConfiguration`, and `SCChartHoverState` for reusable interaction configuration
- `SCChartMark` for composed mark-based chart definitions
- `SCChartAnnotationStyle`, `SCChartAnnotation`, `SCChartOverlay`, `SCChartScale`, and `SCChartComposition` for reusable composed-chart helpers

Expand Down Expand Up @@ -163,6 +165,14 @@ let scrollBehavior = SCChartScrollBehavior.continuous(.points(7))
let timeWindow = SCChartScrollBehavior.timeWindow(hours: 24)
let analyticsScroll = SCChartScrollBehavior.analytics(points: 21)
let financeScroll = SCChartScrollBehavior.finance(tradingDays: 10)
let timeViewport = SCChartTimeViewport.starting(
at: Date(timeIntervalSince1970: 1_700_000_000),
duration: 60 * 60 * 24
)
let zoomBehavior = SCChartZoomBehavior(
minimumVisibleLength: 3,
maximumVisibleLength: 14
)
let gestures = SCChartGestureConfiguration.interactive
let compositionScale = SCChartScale(
xVisibleDomain: .points(6),
Expand Down Expand Up @@ -356,7 +366,10 @@ struct RevenueExplorer: View {
@State private var selectionState = SCChartSelectionState()
@State private var hoverState: SCChartHoverState?
@State private var viewport = SCChartViewport.starting(at: 0, length: 7)
@State private var scrollPosition = Date(timeIntervalSince1970: 1_700_000_000)
@State private var timeViewport = SCChartTimeViewport.starting(
at: Date(timeIntervalSince1970: 1_700_000_000),
duration: 7_200
)

let points = SCChartPoint.make(
labeledValues: [("Mon", 12), ("Tue", 18), ("Wed", 15), ("Thu", 20)]
Expand Down Expand Up @@ -394,14 +407,16 @@ struct RevenueExplorer: View {
points: points,
viewport: $viewport,
scrollBehavior: .continuous(.points(3)),
zoomBehavior: .init(minimumVisibleLength: 2, maximumVisibleLength: 7),
gestureConfiguration: .interactive,
yAxisFormat: .number(precision: 0)
)

SCScrollableTimeSeriesChart(
points: history,
scrollPosition: $scrollPosition,
viewport: $timeViewport,
scrollBehavior: .timeWindow(seconds: 7_200),
zoomBehavior: .init(minimumVisibleLength: 1_800, maximumVisibleLength: 14_400),
xAxisFormat: .hourMinute,
gestureConfiguration: .scrollOnly,
yAxisFormat: .compact
Expand Down
6 changes: 6 additions & 0 deletions Sources/SimpleChart/Native/Charts/SCHoverableCharts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Charts
import SwiftUI

@available(iOS 17, macOS 14, tvOS 17, watchOS 10, macCatalyst 17, *)
/// A line chart wrapper with pointer-hover inspection support.
public struct SCHoverableLineChart: View {
public let points: [SCChartPoint]
public let seriesStyle: SCChartSeriesStyle
Expand All @@ -20,6 +21,7 @@ public struct SCHoverableLineChart: View {

@Binding private var hoverState: SCChartHoverState?

/// Creates a hoverable line chart bound to external hover state.
public init(
points: [SCChartPoint],
hoverState: Binding<SCChartHoverState?>,
Expand Down Expand Up @@ -153,6 +155,7 @@ public struct SCHoverableLineChart: View {
}

@available(iOS 17, macOS 14, tvOS 17, watchOS 10, macCatalyst 17, *)
/// A bar chart wrapper with pointer-hover inspection support.
public struct SCHoverableBarChart: View {
public let points: [SCChartPoint]
public let seriesStyle: SCChartSeriesStyle
Expand All @@ -163,6 +166,7 @@ public struct SCHoverableBarChart: View {

@Binding private var hoverState: SCChartHoverState?

/// Creates a hoverable bar chart bound to external hover state.
public init(
points: [SCChartPoint],
hoverState: Binding<SCChartHoverState?>,
Expand Down Expand Up @@ -270,6 +274,7 @@ public struct SCHoverableBarChart: View {
}

@available(iOS 17, macOS 14, tvOS 17, watchOS 10, macCatalyst 17, *)
/// A scatter chart wrapper with pointer-hover inspection support.
public struct SCHoverableScatterChart: View {
public let points: [SCChartScatterPoint]
public let seriesStyle: SCChartSeriesStyle
Expand All @@ -280,6 +285,7 @@ public struct SCHoverableScatterChart: View {

@Binding private var hoverState: SCChartHoverState?

/// Creates a hoverable scatter chart bound to external hover state.
public init(
points: [SCChartScatterPoint],
hoverState: Binding<SCChartHoverState?>,
Expand Down
4 changes: 4 additions & 0 deletions Sources/SimpleChart/Native/Charts/SCInspectionWrappers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ public struct SCCrosshairScatterChart: View {
}

@available(iOS 17, macOS 14, tvOS 17, watchOS 10, macCatalyst 17, *)
/// A time-series wrapper that always shows inspector-style selection callouts.
public struct SCInspectorTimeSeriesChart: View {
public let points: [SCChartTimePoint]
public let seriesStyle: SCChartSeriesStyle
Expand All @@ -326,6 +327,7 @@ public struct SCInspectorTimeSeriesChart: View {

@Binding private var selection: SCChartSelection?

/// Creates an inspector-style time-series wrapper bound directly to an optional selection.
public init(
points: [SCChartTimePoint],
selection: Binding<SCChartSelection?>,
Expand Down Expand Up @@ -367,6 +369,7 @@ public struct SCInspectorTimeSeriesChart: View {
}

@available(iOS 17, macOS 14, tvOS 17, watchOS 10, macCatalyst 17, *)
/// A time-series wrapper that always shows crosshair-style selection guides.
public struct SCCrosshairTimeSeriesChart: View {
public let points: [SCChartTimePoint]
public let seriesStyle: SCChartSeriesStyle
Expand All @@ -381,6 +384,7 @@ public struct SCCrosshairTimeSeriesChart: View {

@Binding private var selection: SCChartSelection?

/// Creates a crosshair-style time-series wrapper bound directly to an optional selection.
public init(
points: [SCChartTimePoint],
selection: Binding<SCChartSelection?>,
Expand Down
10 changes: 10 additions & 0 deletions Sources/SimpleChart/Native/Charts/SCNative3DCharts.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@

import SwiftUI

#if compiler(>=6.3)
@available(iOS 26.0, macOS 26.0, visionOS 26.0, *)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
/// A 3D point chart wrapper built on the package's composed 3D mark layer.
public struct SCNative3DPointChart: View {
public let points: [SCChart3DPoint]
public let style: SCChart3DSeriesStyle
public let pose: SCChart3DPoseStyle

/// Creates a 3D point chart from prebuilt 3D points.
public init(
points: [SCChart3DPoint],
style: SCChart3DSeriesStyle = .init(),
Expand All @@ -36,11 +39,13 @@ public struct SCNative3DPointChart: View {
@available(iOS 26.0, macOS 26.0, visionOS 26.0, *)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
/// A 3D rectangle chart wrapper built on the package's composed 3D mark layer.
public struct SCNative3DRectangleChart: View {
public let points: [SCChart3DPoint]
public let style: SCChart3DSeriesStyle
public let pose: SCChart3DPoseStyle

/// Creates a 3D rectangle chart from prebuilt 3D points.
public init(
points: [SCChart3DPoint],
style: SCChart3DSeriesStyle = .init(),
Expand All @@ -62,11 +67,13 @@ public struct SCNative3DRectangleChart: View {
@available(iOS 26.0, macOS 26.0, visionOS 26.0, *)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
/// A 3D rule chart wrapper built on the package's composed 3D mark layer.
public struct SCNative3DRuleChart: View {
public let points: [SCChart3DPoint]
public let style: SCChart3DSeriesStyle
public let pose: SCChart3DPoseStyle

/// Creates a 3D rule chart from prebuilt 3D points.
public init(
points: [SCChart3DPoint],
style: SCChart3DSeriesStyle = .init(),
Expand All @@ -88,6 +95,7 @@ public struct SCNative3DRuleChart: View {
@available(iOS 26.0, macOS 26.0, visionOS 26.0, *)
@available(tvOS, unavailable)
@available(watchOS, unavailable)
/// A 3D surface chart wrapper that samples a function across the rendered surface.
public struct SCNativeSurfacePlotChart: View {
public let xTitle: String
public let yTitle: String
Expand All @@ -96,6 +104,7 @@ public struct SCNativeSurfacePlotChart: View {
public let pose: SCChart3DPoseStyle
public let function: @Sendable (Double, Double) -> Double

/// Creates a 3D surface chart from axis titles, style, and a z-value function.
public init(
xTitle: String,
yTitle: String,
Expand Down Expand Up @@ -127,3 +136,4 @@ public struct SCNativeSurfacePlotChart: View {
)
}
}
#endif
3 changes: 3 additions & 0 deletions Sources/SimpleChart/Native/Charts/SCNativeAreaChart.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@

import SwiftUI

/// A ready-made single-series categorical area chart backed by composed marks.
public struct SCNativeAreaChart: View {
public let points: [SCChartPoint]
public let seriesStyle: SCChartSeriesStyle
public let axesStyle: SCChartAxesStyle
public let domain: SCChartDomain?
public let referenceLines: [SCChartReferenceLine]

/// Creates an area chart from prebuilt categorical points.
public init(
points: [SCChartPoint],
seriesStyle: SCChartSeriesStyle = .area(),
Expand All @@ -28,6 +30,7 @@ public struct SCNativeAreaChart: View {
self.referenceLines = referenceLines
}

/// Creates an area chart from floating-point values and optional labels.
public init<T: BinaryFloatingPoint>(
values: [T],
labels: [String]? = nil,
Expand Down
4 changes: 4 additions & 0 deletions Sources/SimpleChart/Native/Charts/SCNativeBandChart.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import Charts
import SwiftUI

/// A chart that renders one or more highlighted y-range bands across shared categories.
public struct SCNativeBandChart: View {
public let categories: [String]
public let bands: [SCChartBand]
Expand All @@ -18,6 +19,7 @@ public struct SCNativeBandChart: View {
public let plotStyle: SCChartPlotStyle
public let domain: SCChartDomain?

/// Creates a band chart from explicit categories and prebuilt bands.
public init(
categories: [String],
bands: [SCChartBand],
Expand All @@ -44,6 +46,7 @@ public struct SCNativeBandChart: View {
)
}

/// Creates a band chart from floating-point band tuples.
public init<T: BinaryFloatingPoint>(
categories: [String],
bands: [(String, T, T)],
Expand Down Expand Up @@ -72,6 +75,7 @@ public struct SCNativeBandChart: View {
)
}

/// Creates a band chart from integer band tuples.
public init<T: BinaryInteger>(
categories: [String],
bands: [(String, T, T)],
Expand Down
3 changes: 3 additions & 0 deletions Sources/SimpleChart/Native/Charts/SCNativeGoalChart.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import SwiftUI

/// A composed chart that overlays goal reference lines on top of bar values.
public struct SCNativeGoalChart: View {
public let points: [SCChartPoint]
public let goal: SCChartReferenceLine
Expand All @@ -15,6 +16,7 @@ public struct SCNativeGoalChart: View {
public let axesStyle: SCChartAxesStyle
public let domain: SCChartDomain?

/// Creates a goal chart from prebuilt categorical points and goal lines.
public init(
points: [SCChartPoint],
goal: SCChartReferenceLine,
Expand All @@ -32,6 +34,7 @@ public struct SCNativeGoalChart: View {
self.domain = domain ?? .auto(values: points.map(\.value) + referenceValues, baseZero: true)
}

/// Creates a goal chart from floating-point values, optional labels, and goal lines.
public init<T: BinaryFloatingPoint>(
values: [T],
labels: [String]? = nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import Charts
import SwiftUI

/// A multi-series grouped area chart built from named line-series models.
public struct SCNativeGroupedAreaChart: View {
public let series: [SCChartLineSeries]
public let axesStyle: SCChartAxesStyle
Expand All @@ -16,6 +17,7 @@ public struct SCNativeGroupedAreaChart: View {
public let foregroundStyleScale: SCChartForegroundStyleScale
public let referenceLines: [SCChartReferenceLine]

/// Creates a grouped area chart from prebuilt line-series values.
public init(
series: [SCChartLineSeries],
axesStyle: SCChartAxesStyle = .standard(),
Expand Down
Loading
Loading