A lightweight sparkline component, supporting Swift, SwiftUI, macCatalyst and Objective-C.
Note that the 2.0.0 release has changes that will break your existing DSFSparkline code. Please see below for the changes.
- Simple bar, dot and line graph support.
IBDesignable
support so you can see your sparklines in interface builder.- 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
- Line graph can draw with discrete lines or fitted to a curve
- SwiftUI support
The library is split into a data model and a view model. A data source (model) is created and assigned to a view model in order to populate the sparkline.
So, a very simple example…
// Create the view
let sparklineView = DSFSparklineLineGraphView(…)
sparklineView.graphColor = UIColor.blue
sparklineView.showZero = true
// Create the datasource and assign to the view
let sparklineDataSource = DSFSparklineDataSource(windowSize: 30, range: -1.0 ... 1.0)
sparklineView.dataSource = sparklineDataSource
…
// Add a single new data element to the sparkline
sparklineDataSource.push(value: 0.7) // view automatically updates with new data
// Add a set of data to the sparkline
sparklineDataSource.push(values: [0.3, -0.2, 1.0]) // view automatically updates with new data
// Completely replace the sparkline data with a new set of data
sparklineDataSource.set(values: [0.2, -0.2, 0.0, 0.9, 0.8]) // view automatically resets to new data
Represents the data to be displayed.
The data source is assigned to the view model to provide data for drawing the sparkline. As data is changed the assigned view is automatically updated to reflect the new data. If more data is added via a push or set the data is added to the datasource, the associated view will automatically update to reflect the new data. Older data that no longer falls within the window is discarded.
An optional range can be set on the data source, which means that the view will automatically clip any incoming data to that range. Without a range specified, the sparkline's vertical range will grow and shrink to accomodate the full range of data.
Represents the viewable settings and display. The current view types available are :-
- DSFSparklineLineGraphView
- DSFSparklineBarGraphView
- DSFSparklineDotGraphView
Setting | Type | Description |
---|---|---|
graphColor |
NSColor /UIColor |
The color to use when drawing the sparkline |
showZero |
Bool |
Draw a dotted line at the zero line point on the y-axis |
Setting | Type | Description |
---|---|---|
lineWidth |
CGFloat |
The width of the line |
interpolation |
Bool |
Interpolate a curve between the points |
lineShading |
Bool |
Shade the area under the line |
shadowed |
Bool |
Draw a shadow under the line |
Setting | Type | Description |
---|---|---|
lineWidth |
CGFloat |
The width of the line |
barSpacing |
CGFloat |
The spacing between each bar |
Setting | Type | Description |
---|---|---|
upsideDown |
Bool |
If true, draws from the top of the graph downwards |
unsetGraphColor |
NSColor /UIColor |
The color to use when drawing the background |
There are demos available in the Demos
subfolder for each of the supported platforms. The demos use CocoaPods so you'll need to pod install
in the Demos folder.
pod 'DSFSparkline', :git => 'https://github.com/dagronf/DSFSparkline/'
Add https://github.com/dagronf/DSFSparkline
to your project.
/// Swift
import DSFSparkline
/// Objective-C
@import DSFSparkline;
- If the window size is reduced, stored data is truncated.
- If the window size is increased, the data store is padded with zeros
/// Swift
dataSource.windowSize = 30
assert(dataSource.windowSize == 30)
/// Objective-C
[dataSource setWindowSize:30];
assert([dataSource windowSize] == 30);
Changing the y-range does not change the stored data. The y-range is used during drawing to truncate to the upper and lower bounds, so the range can be changed safely at any time.
/// Swift
dataSource.range = -1.0 ... 1.0
/// Objective-C
[dataSource setRangeWithLowerBound:-1.0 upperBound:1.0];
The 'zero line' represents the dotted line that is drawn horizontally across the line and bar graphs. By default, this zero line is set at 0.0 within the graph's window values. You can set the 'zero' line at an arbitrary value using the zeroLineValue
on the data source.
// Initialize to draw a dotted line at 0.8
let datasource = DSFSparklineDataSource(range: 0 ... 1, zeroLineValue: 0.8)
// Change the data source to draw the zeroline at 0.9
myDataSource.zeroLineValue = 0.9
/// Swift
dataSource.data
/// Objective-C
[dataSource data];
Note that this does not change the range value if a range has been set. If values fall outside the y-range they will be truncated during drawing. If no range has been set then the sparkline is scaled to fit the full y-range.
/// Swift
dataSource.set(values: [1, 2, 3, 4, 5])
/// Objective-C
[dataSource setWithValues:@[@(1), @(2), @(3), @(4), @(5)]];
/// Swift
dataSource.push(value: 4.5)
/// Objective-C
[dataSource pushWithValue:@(4.5)];
dataSource.push(values: [x, y, z])
is equivalent to
dataSource.push(value: x)
dataSource.push(value: y)
dataSource.push(value: z)
/// Swift
dataSource.push(values: [4.5, 10.3, 11])
/// Objective-C
[dataSource pushWithValues:@[@(4.5), @(10.3), @(11)]];
Reset the data to the lower bound for all data points in the window. If no lower bound is set, all data values are set to zero.
/// Swift
dataSource.reset()
/// Objective-C
[dataSource reset];
Each graph type provides its own SwiftUI view (appending .SwiftUI
to the class name).
struct SparklineView: View {
let leftDataSource: DSFSparklineDataSource
let rightDataSource: DSFSparklineDataSource
var body: some View {
HStack {
DSFSparklineLineGraphView.SwiftUI(
dataSource: leftDataSource,
graphColor: UIColor.red,
showZero: false,
interpolated: true)
DSFSparklineLineGraphView.SwiftUI(
dataSource: rightDataSource,
graphColor: UIColor.blue,
showZero: true,
interpolated: true)
}
}
}
macOS dark | macOS light | iOS |
---|---|---|
macOS | tvOS |
---|---|
- Add the ability to set the 'zero' line value. Defaults to zero for backwards compatibility.
You can set where the 'zero' line draws via the zeroLineValue
on the datasource.
-
The primary views have been renamed with a
View
postfix. SoDSFSparklineLineGraph
->DSFSparklineLineGraphView
DSFSparklineBarGraph
->DSFSparklineBarGraphView
DSFSparklineDotGraph
->DSFSparklineDotGraphView
-
Renamed
SLColor
andSLView
toDSFColor
andDSFView
for module naming consistency. -
I removed
windowSize
from the coreDSFSparklineView
.windowSize
is related to data, and should never have been part of the UI definition. I've provided a replacement purely forIBDesignable
support calledgraphWindowSize
which should only be called from Interface Builder. If you want to set the windowSize from your xib file, set thegraphWindowSize
inspectable.If you see warnings in the log like
2020-12-07 18:22:51.619867+1100 iOS Sparkline Demo[75174:1459637] Failed to set (windowSize) user defined inspected property on (DSFSparkline.DSFSparklineBarGraphView): [<DSFSparkline.DSFSparklineBarGraphView 0x7fe2eb10f2b0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key windowSize.
it means that you have awindowSize
value set in your .xib file. Remove it and set thegraphWindowSize
value instead. -
For the Bar type,
lineWidth
andbarSpacing
now represent the pixel spacing between bars and the pixel width for the line. You may find that your line spacing and bar spacing are now incorrect if you have set fractional values for these in the past (for example, if you set lineWidth = 0.5). The reason for this change is to aid drawing lines on pixel boundaries and avoid antialiasing. -
Fix for zero line being upside-down
MIT License
Copyright (c) 2020 Darren Ford
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.