SwiftUICharts

repository·main·Indexed 21 days ago

https://github.com/willdale/swiftuicharts

A comprehensive charting and plotting library for SwiftUI supporting macOS, iOS, watchOS, and tvOS. It provides various chart types including Line (Standard, Filled, Multi, Ranged), Bar (Standard, Range, Grouped, Stacked), and circular charts (Pie, Doughnut). The library features built-in accessibility for VoiceOver, localization support, and extensive customization via view modifiers for touch overlays, info boxes, average lines, trend lines, and axis configuration.

Tokens
3K
Snippets
10
Records
12
Agent score
26%

What's inside SwiftUICharts

  1. Implement Touch Overlay and Info Boxes

    main

    To enable interactive data inspection, use the following modifiers. Note that the visual behavior (where the box appears) is controlled by ChartStyle -> infoBoxPlacement within your chart data setup.

    • .touchOverlay(...): Detects touch or pointer input to find the nearest data point. Requires setup in Chart Data -> Chart Style.
    • .infoBox(chartData:): Displays information from the touch overlay if infoBoxPlacement is set to .infoBox.
    • .floatingInfoBox(chartData:): Displays information from the touch overlay if infoBoxPlacement is set to .floating.
    • .headerBox(chartData:): Displays metadata (from Chart Data -> ChartMetadata) and touch overlay info if infoBoxPlacement is set to .header.

    Touch Overlay Parameters:

    • chartData: The chart data model.
    • specifier: Decimal precision for labels.
    • unit: Unit to display before or after the value.
    .touchOverlay(chartData: CTChartData, specifier: String, unit: TouchUnit)
  2. Configure LineChartData and LineChartStyle

    main

    To initialize a LineChart, you must provide a LineChartData object. This object is composed of:

    1. Data Sets (LineDataSet): Contains LineChartDataPoint objects (value, xAxisLabel, description) and styling like LineStyle.
    2. Metadata (ChartMetadata): Provides the chart title and subtitle.
    3. Chart Style (LineChartStyle): Defines the visual configuration, including:
      • infoBoxPlacement: Where the info box appears.
      • markerType: The visual style of markers.
      • xAxisGridStyle / yAxisGridStyle: Styling for grid lines.
      • xAxisLabelPosition / yAxisLabelPosition: Placement of labels.
      • baseline / topLine: Defines the Y-axis range limits.
      • globalAnimation: The animation type for data transitions.
    let data = LineDataSet(dataPoints: [
        LineChartDataPoint(value: 12000, xAxisLabel: "M", description: "Monday"),
        LineChartDataPoint(value: 10000, xAxisLabel: "T", description: "Tuesday")
    ], 
    legendTitle: "Steps",
    pointStyle: PointStyle(),
    style: LineStyle(lineColour: ColourStyle(colour: .red), lineType: .curvedLine))
    
    let metadata = ChartMetadata(title: "Step Count", subtitle: "Over a Week")
    
    let chartStyle = LineChartStyle(
        infoBoxPlacement: .infoBox(isStatic: false),
        markerType: .vertical(attachment: .line(dot: .style(DotStyle()))),
        xAxisGridStyle: gridStyle,
        yAxisNumberOfLabels: 7,
        baseline: .minimumWithMaximum(of: 5000),
        topLine: .maximum(of: 20000),
        globalAnimation: .easeOut(duration: 1)
    )
    
    let chartData = LineChartData(dataSets: data, metadata: metadata, chartStyle: chartStyle)
  3. Install SwiftUICharts via Swift Package Manager

    main

    To use SwiftUICharts in your project, add it as a Swift Package dependency using the following steps:

    1. In Xcode, go to File > Swift Packages > Add Package Dependency....
    2. Add the repository URL for SwiftUICharts.
    3. Import the module in your Swift files:
    import SwiftUICharts
  4. Troubleshoot view updates with .id()

    main

    If your chart views are not updating correctly when the underlying data changes, apply the .id() modifier to the chart view using a unique identifier from your data model. This forces SwiftUI to treat the view as a new identity and re-render it.

    LineChart(chartData: LineChartData)
        .id(LineChartData.id)
  5. Create a Line Chart with View Modifiers

    main

    You can build highly customized Line Charts by applying a series of view modifiers to a LineChart instance. These modifiers allow you to add point markers, touch overlays, Point of Interest (POI) markers, average lines, grid lines, axis labels, info boxes, headers, and legends.

    Key modifiers include:

    • .pointMarkers(chartData:): Displays markers at data points.
    • .touchOverlay(chartData:specifier:): Enables touch interaction to show values.
    • .yAxisPOI(chartData:markerName:markerValue:...): Adds a horizontal reference line at a specific value.
    • .averageLine(chartData:strokeStyle:): Draws a line representing the average value.
    • .xAxisGrid(chartData:) / .yAxisGrid(chartData:): Displays grid lines.
    • .xAxisLabels(chartData:) / .yAxisLabels(chartData:): Displays axis labels.
    • .infoBox(chartData:) / .headerBox(chartData:): Adds informational or header boxes.
    • .legends(chartData:columns:): Displays the chart legend.
    LineChart(chartData: data)
        .pointMarkers(chartData: data)
        .touchOverlay(chartData: data, specifier: "%.0f")
        .yAxisPOI(chartData: data,
                  markerName: "Step Count Aim",
                  markerValue: 15_000,
                  labelPosition: .center(specifier: "%.0f"),
                  labelColour: Color.black,
                  labelBackground: Color(red: 1.0, green: 0.75, blue: 0.25),
                  lineColour: Color(red: 1.0, green: 0.75, blue: 0.25),
                  strokeStyle: StrokeStyle(lineWidth: 3, dash: [5,10]))
        .averageLine(chartData: data, strokeStyle: StrokeStyle(lineWidth: 3, dash: [5,10]))
        .xAxisGrid(chartData: data)
        .yAxisGrid(chartData: data)
        .xAxisLabels(chartData: data)
        .yAxisLabels(chartData: data)
        .infoBox(chartData: data)
        .headerBox(chartData: data)
        .legends(chartData: data, columns: [GridItem(.flexible()), GridItem(.flexible())])
  6. Add Trend Lines and Point Markers

    main

    Visual enhancements for line charts:

    • .linearTrendLine(...): Draws a line showing the trend between firstValue and lastValue.
    • .pointMarkers(chartData:): Places markers over each data point. Setup is done via Data Set -> PointStyle.
    • .filledTopLine(...): (For FilledLineChart) Adds an independent line on top of the filled area with a semi-opaque fill.
  7. Configure Axis Grids and Labels

    main

    Customize the axes of your line and bar charts. Most of these are configured via ChartData -> ChartStyle:

    • .xAxisGrid(chartData:): Adds vertical grid lines.
    • .yAxisGrid(chartData:): Adds horizontal grid lines.
    • .xAxisLabels(chartData:): Displays labels for the X axis.
    • .yAxisLabels(chartData:specifier:): Automatically generates numeric labels for the Y axis.
      • Use specifier for decimal precision.
      • The type of labels is controlled by yAxisLabelType (.numeric or .custom). Custom labels are provided via ChartData -> yAxisLabels.
  8. Add Average Lines and Points of Interest to Line/Bar Charts

    main

    Enhance line and bar charts with reference lines:

    • .averageLine(...): Draws a line at the average of all data points.
      • markerName: Title for the legend.
      • labelPosition: Where to display the value (e.g., .yAxis(specifier: "%.0f")).
      • lineColour: Color of the line.
      • strokeStyle: StrokeStyle for the line.
    • .yAxisPOI(...): Draws a configurable line at a specific value.
      • markerValue: The value to mark.
      • markerName: Title for the legend.
      • labelPosition: Position of the value label.
    .averageLine(chartData: CTLineBarChartDataProtocol,
                 markerName: "Average",
                 labelPosition: .yAxis(specifier: "%.0f"),
                 lineColour: .primary,
                 strokeStyle: StrokeStyle(lineWidth: 3, dash: [5,10]))
  9. Use Bar Charts

    main

    SwiftUICharts provides several types of bar charts, each requiring a specific data model:

    • Bar Chart: Standard bar plot. Uses BarChartData.
    • Range Bar Chart: Bars representing a range. Uses RangedBarChartData.
    • Grouped Bar Chart: Multiple bars grouped together. Uses GroupedBarChartData.
    • Stacked Bar Chart: Bars stacked on top of each other. Uses StackedBarChartData.

    Example usage:

    BarChart(chartData: BarChartData)
  10. Use Line Charts

    main

    SwiftUICharts provides several types of line charts, each requiring a specific data model:

    • Line Chart: Standard line plot. Uses LineChartData.
    • Filled Line Chart: Line plot with a semi-opaque fill. Uses LineChartData.
    • Multi Line Chart: Multiple lines on one chart. Uses MultiLineChartData.
    • Ranged Line Chart: Line chart showing ranges. Uses RangedLineChartData.

    Example usage:

    LineChart(chartData: LineChartData)
  11. Localize Accessibility labels for VoiceOver

    main

    SwiftUICharts includes built-in support for VoiceOver. To customize how the chart is read to visually impaired users, you can localize specific internal keys. The library uses these keys to construct descriptive sentences.

    Key VoiceOver patterns:

    • Data Points: <chart title>, <data point value>, <data point description>
    • POI Markers: <p o i marker>, <marker legend title>, <marker value>
    • Axis Labels: <axisLabel>, <marker value>
    • Legends: <chart type legend>, <legend title>

    To localize, provide translations for the following technical tokens in your localization files:

    // Data Point Description
    "%@ <local_description_of_a_data_point>" = "%@, <Description of a data point>";
    
    // POI Marker
    "P-O-I-Marker" = "P O I Marker";
    "Average" = "Average";
    "<local_marker_legend_title> %@" = "local_marker_legend_title, %@";
    
    // Axis Labels
    "X-Axis-Label" = "X Axis Label";
    "Y-Axis-Label" = "Y Axis Label";
    
    // Legends
    "Line-Chart-Legend" = "Line Chart Legend";
    "P-O-I-Marker-Legend" = "P O I Marker Legend";
    "Bar-Chart-Legend" = "Bar Chart Legend";
    "Pie-Chart-Legend" = "Pie Chart Legend";