DSFSparkline
A lightweight sparkline component for macOS, iOS and tvOS
Install / Use
/learn @dagronf/DSFSparklineREADME
Sparklines for macOS, iOS and tvOS
A lightweight sparkline component, supporting Swift, SwiftUI, macCatalyst and Objective-C.
<p align="center"> <img src="https://img.shields.io/github/v/tag/dagronf/DSFSparkline" /> <img src="https://img.shields.io/badge/macOS-10.13+-red" /> <img src="https://img.shields.io/badge/iOS-14.0+-blue" /> <img src="https://img.shields.io/badge/tvOS-14.0+-orange" /> <img src="https://img.shields.io/badge/SwiftUI-1.0+-green" /> <img src="https://img.shields.io/badge/macCatalyst-1.0+-purple" /> </p> <p align="center"> <img src="https://img.shields.io/badge/Swift-5-orange.svg" /> <img src="https://img.shields.io/badge/License-MIT-lightgrey" /> <img src="https://img.shields.io/badge/pod-compatible-informational" alt="CocoaPods" /> <a href="https://swift.org/package-manager"> <img src="https://img.shields.io/badge/spm-compatible-brightgreen.svg?style=flat" alt="Swift Package Manager" /> </a> </p> <center> <a href="https://github.com/dagronf/dagronf.github.io/raw/master/art/projects/DSFSparkline/reportview.png"> <img src="https://github.com/dagronf/dagronf.github.io/raw/master/art/projects/DSFSparkline/reportview.png" width="300"/></a> </center>What is a sparkline?
A sparkline is a very small chart, typically drawn without axes or coordinates. It presents the general shape of the variation (typically over time) in some measurement, such as temperature or stock market price, in a simple and highly condensed way. Sparklines are small enough to be embedded in text, or several sparklines may be grouped together as elements of a small multiple. Whereas the typical chart is designed to show as much data as possible, and is set off from the flow of text, sparklines are intended to be succinct, memorable, and located where they are discussed.
What ISN'T a sparkline?
DSFSparkline IS NOT designed to be a full-featured graphing library. It was built to be lightweight, to create small, memorable charts within an app.
If you need features like labelling, real-time updating, axis-labelling, interactivity, legends or beautiful charts at larger sizes, you might be better served by the Charts library, Core plot or SciChart (paid). You can find a whole lot more here.
Features
- Multiple graph styles support, such as line, bar, tablet etc.
- Support for sparkline customizations, such as zero-line, grid lines, highlighting.
- Prebuilt NSView/UIView/SwiftUI types for quick integration
- Independently scalable for sparklines at any size
- y-range can automatically grow or shrink to encompass the full y-range of data.
- y-range can be fixed and the sparkline will truncate to the specified range
- SwiftUI support for all sparkline types
- NSAttributedString support
IBDesignablesupport for prebuilt types so you can see and configure your sparklines in interface builder.- Optional drawing of a 'zero line' on the bar and line graphs (thanks Tito Ciuro)
- Playground support
TL;DR - Show me something!
<details> <summary>Create a retina-scale (144dpi) bitmap with a simple line overlay graph</summary>// A datasource with a simple set of data
let source = DSFSparkline.DataSource(values: [4, 1, 8, 7, 5, 9, 3], range: 0 ... 10)
let bitmap = DSFSparklineSurface.Bitmap() // Create a bitmap surface
let stack = DSFSparklineOverlay.Line() // Create a line overlay
stack.dataSource = source // Assign the datasource to the overlay
bitmap.addOverlay(stack) // And add the overlay to the surface.
// Generate an image with retina scale
let image = bitmap.image(width: 50, height: 25, scale: 2)
// Embed a sparkline in an NSAttributedString
let attributedString = bitmap.attributedString(size: CGSize(width: 40, height: 18), scale: 2)
<img src="https://github.com/dagronf/dagronf.github.io/raw/master/art/projects/DSFSparkline/types-new/line-simple-small.png" width="50"/>
</details>
<details>
<summary>Create a Swift-UI line graph sparkline with zero-line and highlight range overlays</summary>
fileprivate let SwiftUIDemoDataSource: DSFSparkline.DataSource = {
let d = DSFSparkline.DataSource(windowSize: 20, range: 0 ... 1, zeroLineValue: 0.5)
d.push(values: [
0.72, 0.84, 0.15, 0.16, 0.30, 0.58, 0.87, 0.44, 0.02, 0.27,
0.48, 0.16, 0.15, 0.14, 0.81, 0.53, 0.67, 0.52, 0.07, 0.50
])
return d
}()
struct SuperCoolLineSpark: View {
// The overlay representing the zero-line for the data source
var zeroOverlay: DSFSparklineOverlay = {
let zeroLine = DSFSparklineOverlay.ZeroLine()
zeroLine.dataSource = SwiftUIDemoDataSource
zeroLine.dashStyle = []
return zeroLine
}()
// The overlay to draw a highlight between range 0 ..< 0.2
var rangeOverlay: DSFSparklineOverlay = {
let highlight = DSFSparklineOverlay.RangeHighlight()
highlight.dataSource = SwiftUIDemoDataSource
highlight.highlightRange = 0.0 ..< 0.2
highlight.fill = DSFSparkline.Fill.Color(DSFColor.gray.withAlphaComponent(0.4).cgColor)
return highlight
}()
// The actual line graph
var lineOverlay: DSFSparklineOverlay = {
let lineOverlay = DSFSparklineOverlay.Line()
lineOverlay.dataSource = SwiftUIDemoDataSource
lineOverlay.primaryStrokeColor = DSFColor.systemBlue.cgColor
lineOverlay.primaryFill = DSFSparkline.Fill.Color(DSFColor.systemBlue.withAlphaComponent(0.3).cgColor)
lineOverlay.secondaryStrokeColor = DSFColor.systemYellow.cgColor
lineOverlay.secondaryFill = DSFSparkline.Fill.Color(DSFColor.systemYellow.withAlphaComponent(0.3).cgColor)
lineOverlay.strokeWidth = 1
lineOverlay.markerSize = 4
lineOverlay.centeredAtZeroLine = true
return lineOverlay
}()
var body: some View {
DSFSparklineSurface.SwiftUI([
rangeOverlay, // range highlight overlay
zeroOverlay, // zero-line overlay
lineOverlay, // line graph overlay
])
.frame(width: 150, height: 40)
}
}
<img src="https://github.com/dagronf/dagronf.github.io/raw/master/art/projects/DSFSparkline/swiftui-demo.png" width="165"/>
</details>
Integration
Use Swift Package Manager to integrate DSFSparkline into your project
Add https://github.com/dagronf/DSFSparkline to your project.
Note
When adding DSFSparkline to one of your projects, you need to choose a SINGLE 'package product' to
link to your target. Choosing multiple package products for your project will result in weird, inconsistent link errors.
| Package Product | Description |
|:-----------------------|:--------------------------------|
| DSFSparkline | The default style. If you are just trying this library out, this is the one to choose
| DSFSparkline-static | Add DSFSparkline as a STATIC library, meaning that all DSFSparkline code is linked directly into your target |
| DSFSparkline-shared | Add DSFSparkline as a SHARED library, meaning that you can use a single shared framework between multiple targets in your project to save space |
Available graph types
Line <img src="https://github.com/dagronf/dagronf.github.io/raw/master/art/projects/DSFSparkline/types-new/line-simple-small.png" width="50"/>
A simple line sparkline. The line can be centered around a zero line to indicate positive and negative values. You can also add (optional) markers to the data points.
You can custom-draw the markers by supplying a drawing callback block (markerDrawingBlock) where you can customize which markers are drawn (for example, just the min and max values) and how they are drawn.
| Standard | Centered | |------------|------------| |<img src="https://github.com/dagronf/dagronf.github.io/raw/master/art/projects/DSFSparkline/types-new/line-standard.png" width="400">|<img src="https://github.com/dagronf/dagronf.github.io/raw/master/art/projects/DSFSparkline/types-new/line-centered.png" width="400">|
| Interpolated | Interpolated Centered | |------------|------------| |<img src="https://github.com/dagronf/dagronf.github.io/raw/master/art/projects/DSFSparkline/types-new/line-interpolated.png" width="400">|<img src="https://github.com/dagronf/dagronf.github.io/raw/master/art/projects/DSFSparkline/types-new/line-interpolated-centered.png" width="400">|
| Standard Markers | Interpolated Markers | |------------|------------| |<img src="https://github.com/dagronf/dagronf.github.io/raw/master/art/projects/DSFSparkline/types-new/line-markers.png" width="400">|<img src="https://github.com/dagronf/dagronf.github.io/raw/master/art/projects/DSFSparkline/types-new/line-markers-centered.png" width="400">|
| Custom Markers (min/max only) | Custom Markers (Last 5 values) | |------------|------------| |<img src="https://github.com/dagronf/dagronf.github.io/raw/master/art/projects/DSFSparkline/types-new/line-custom-marker-1.png" width="400">|<img src="https://github.com/dagronf/dagronf.github.io/raw/master/art/projects/DSFSparkline/types-new/line-custom-marker-2.png" width="400">|
<details> <summary>Swift example using custom markers</summary>//
// A custom marker drawing function that draws the maximum value in green, the minimum value in red
//
self.myLineView.markerDrawingBlock = { context, markerFrames in
// Get the frames containing the minimum and maximum values
if let minMarker = markerFrames.min(by: { (a, b) -> Bool in a.value < b.value }),
let maxMarker = markerFrames.min(by: { (a, b) -> Bool in a.value > b.value }) {
// Draw minimum marker
context.setFillColor(DSFColor.system
