A lightweight sparkline component for macOS, iOS and tvOS
Sparklines for macOS, iOS and tvOS
A lightweight sparkline component, supporting Swift, SwiftUI, macCatalyst and Objective-C.
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
IBDesignable
support 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
- NSAttributedString support
TL;DR - Show me something!
Create a retina-scale (144dpi) bitmap with a simple line overlay graph// 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)
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)
}
}
Building your sparkline
You can find a lot of examples of sparklines in projects in the Demos/Samples
subfolder.
There's a simple Xcode Playground available in the Demos/Playground
subfolder.
Using overlays
There are three fundamental building blocks for an overlay sparkline. Overlay sparklines are more flexible and configurable than the pre-built views, but are more complex to set up and provides no support for @IBDesignable.
- A surface - where it will draw
- A datasource - the set of values to draw
- One or more overlays - the 'layers' which render different components of the sparkline
Using prebuilt views
A prebuilt view is useful to quickly add a sparkline via Interface Builder (while providing previews using @IBDesignable) or SwiftUI. These views provide hard-coded styling (beyond the simple graph color) and a limit set of customizations.
- A datasource - the set of values to draw
- A prebuilt view type - the NSView/UIView/SwiftUI view to draw your sparkline
If you've used DSFSparklines
prior to v4, these are the original view types that you used to display your sparklines.
Surface
A surface represents a destination for a sparkline. This library provides a number of built-in surfaces
DSFSparklineSurfaceView
- AnNSView
/UIView
surface for displaying a sparklineDSFSparklineSurface.SwiftUI
- A SwiftUIView
surface.DSFSparklineSurface.Bitmap
- ANSImage
/UIImage
/CGImage
/NSAttributedString
surface for creating a bitmap from a sparkline.
DataSource
A data source provides data for a sparkline. A datasource can be shared between multiple overlays or prebuilt types (see below) to provide different 'views' of the data contained within the source. And if a DataSource
is updated, all sparkline ovelays observing that source will be automatically re-rendered.
There are currently two types of datasource available
DSFSparkline.DataSource
A DataSource that contains values that can be updated by pushing new values into the source.
More detailsWindowSize
The DataSource defines a 'windowSize' - the maximum number of values to be drawn on the overlay. As values are pushed into the DataSource, any values that no longer fit
within the DataSource window are discarded.
- 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);
Y-range
The range defines the upper and lower values to be displayed in the sparkline. Any values pushed into the datasource will be capped when drawn to this range.
If the range is not set (ie nil), then any overlays will automatically resize to fit the entire range of values within the source. For example, with values as [1, 2, 3, 4] the range is implicitly set as 1 ... 4. If the values are [-10, 100, 33] the range is implicitly set as -10 ... 100
Code example/// Swift
dataSource.range = -1.0 ... 1.0
/// Objective-C
[dataSource setRangeWithLowerBound:-1.0 upperBound:1.0];
Zero-line value
The zero-line defines the point the sparkline overlays should consider to be 'zero'. For example, graphs that can be centered (line, bar and stackline) use the zero-line value to define where the graph is centered around.
The zero-line value defaults to zero.
You can draw a zero-line for a sparkline by adding a DSFSparklineOverlay.ZeroLine
to your surface.
/// Swift
dataSource.zeroLineValue = 0.2
/// Objective-C
[dataSource setZeroLineValue:0.2];
Adding values
You can push new values into the datasource using the push
functions. Values in the datasource older than the datasource's windowSize
are discarded.
As values are pushed into the datasource, any overlays assigned this datasource will automatically update.
Code example/// Swift
dataSource.push(value: 4.5)
dataSource.push(values: [6, 7, 8])
/// Objective-C
[dataSource pushWithValue:@(4.5)];
You replace all the values in a datasource the set
functions. The set function also changes the windowSize
for the datasource to the size of the values array passed in.
Any overlays assigned this datasource will automatically update.
Code example/// Swift
datasource.set(values: [
0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0,
0.0, -0.1, -0.2, -0.3, -0.4, -0.5, -0.6, -0.7, -0.8, -0.9, -1.0
])
/// Objective-C
[datasource setWithValues:
@[@(0.0), @(0.1), @(0.2), @(0.3), @(0.4), @(0.5), @(0.6), @(0.7), @(0.8), @(0.9), @(1),
@(0.0), @(-0.1), @(-0.2), @(-0.3), @(-0.4), @(-0.5), @(-0.6), @(-0.7), @(-0.8), @(-0.9), @(-1)]];
DSFSparkline.StaticDataSource
A datasource that contains a static set of values. Some types of sparkline use a single 'set' of data, providing no historical context.
More details/// Swift
let dataSource = DSFSparkline.StaticDataSource([1, 2, 3])
/// Objective-C
DSFSparklineStaticDataSource* dataSource = [[DSFSparklineStaticDataSource alloc] init: @[@(1), @(2), @(3)]];
Overlays
Overlays represent the individual visual components of a sparkline. You can add as many or as few to your surface in any order. For example, you could overlay two different graph types onto the same surface using the same. And as overlays can share their datasource, all overlays using the same source will automatically update if the data changes (for example, in reponse to a push
)
For example, there is an overlay that highlights a y-range of data. Or, if you want some grid lines, you can add them using the gridlines overlay.
You can add different instances of an overlay to the same sparkline. For example, if you want to add multiple range highlights you add multiple 'highlight' overlays to the sparkline surface.
The order in which the overlays are added determine where in the z-order that they appear in the sparkline. For example, you can choose to draw the grid on top of the graph if you want by adding the graph overlay BEFORE you add the grid overlay
The overlay allows your sparkline to be as complex or as simple as you want.
Graph types
Dynamic
A dynamic graph automatically updates its overlays as values are 'pushed' onto its datasource. As data is added the assigned overlay 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 datasource window is discarded.
This provides the ability to show a historical data set over the breadth of the graph.
`DSFSparklineOverlay.Line`let bitmap = DSFSparklineSurface.Bitmap() // Create a bitmap surface
let line = DSFSparklineOverlay.Line() // Create a line overlay
line.strokeWidth = 1
line.primaryFill = primaryFill
line.dataSource = source // Assign the datasource to the overlay
bitmap.addOverlay(line) // And add the overlay to the surface.
// Generate an image with retina scale
let image = bitmap.image(width: 50, height: 25, scale: 2)!
// Do something with 'image'
`DSFSparklineOverlay.StackLine` let bitmap = DSFSparklineSurface.Bitmap() // Create a bitmap surface
let stack = DSFSparklineOverlay.Stackline() // Create a stackline overlay
stack.dataSource = source // Assign the datasource to the overlay
stack.strokeWidth = 1
stack.primaryFill = primaryFill
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)!
// Do something with 'image'
`DSFSparklineOverlay.Bar` let bitmap = DSFSparklineSurface.Bitmap() // Create a bitmap surface
let bar = DSFSparklineOverlay.Bar() // Create a bar overlay
bar.dataSource = source // Assign the datasource to the overlay
bar.primaryFill = primaryFill
bitmap.addOverlay(bar) // And add the overlay to the surface.
// Generate an image with retina scale
let image = bitmap.image(width: 50, height: 25, scale: 2)!
// Do something with 'image'
`DSFSparklineOverlay.Dot` let bitmap = DSFSparklineSurface.Bitmap() // Create a bitmap surface
let dot = DSFSparklineOverlay.Dot() // Create a dot graph overlay
dot = biggersource // Assign the datasource to the overlay
bitmap.addOverlay(dot) // And add the overlay to the surface.
// Generate an image with retina scale
let image = bitmap.image(width: 50, height: 32, scale: 2)!
// Do something with 'image'
`DSFSparklineOverlay.WinLossTie` let bitmap = DSFSparklineSurface.Bitmap() // Create a bitmap surface
let winLossTie = DSFSparklineOverlay.WinLossTie() // Create a win-loss-tie overlay
winLossTie.dataSource = winloss // Assign the datasource
bitmap.addOverlay(winLossTie) // And add the overlay to the surface.
// Generate an image with retina scale
let image = bitmap.image(width: 75, height: 12, scale: 2)!
// Do something with 'image'
`DSFSparklineOverlay.Tablet` let bitmap = DSFSparklineSurface.Bitmap() // Create a bitmap surface
let stack = DSFSparklineOverlay.Tablet() // Create a tablet overlay
stack.dataSource = winloss // Assign a 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: 90, height: 16, scale: 2)!
// Do something with 'image'
`DSFSparklineOverlay.Stripes` let bitmap = DSFSparklineSurface.Bitmap() // Create a bitmap surface
let stack = DSFSparklineOverlay.Stripes() // Create a stripes overlay
stack.dataSource = .init(values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
bitmap.addOverlay(stack) // And add the overlay to the surface.
// Generate an image with retina scale
let image = bitmap.image(width: 90, height: 16, scale: 2)
// Do something with 'image'
Static
A static graph has a fixed set of values (for example, a pie chart). The overlays update when a new static data source is assigned to it.
`DSFSparklineOverlay.Pie`let bitmap = DSFSparklineSurface.Bitmap()
let pie = DSFSparklineOverlay.Pie()
pie.dataSource = DSFSparkline.StaticDataSource([10, 55, 20])
pie.lineWidth = 0.5
pie.strokeColor = CGColor.black
bitmap.addOverlay(pie)
// Generate an image with retina scale
let image = bitmap.image(width: 18, height: 18, scale: 2)!
// Do something with 'image'
`DSFSparklineOverlay.DataBar` let bitmap = DSFSparklineSurface.Bitmap()
let stack = DSFSparklineOverlay.DataBar()
stack.dataSource = DSFSparkline.StaticDataSource([10, 20, 30])
stack.lineWidth = 0.5
stack.strokeColor = CGColor.black
bitmap.addOverlay(stack)
// Generate an image with retina scale
let image = bitmap.image(width: 50, height: 18, scale: 2)!
// Do something with 'image'
Component types
A component represents an overlay that isn't a graph in itself. Examples are grid lines, zero-lines, highlights etc. A component uses the same datasource so that it aligns with the graph it is associated with.
Name | Description |
---|---|
DSFSparklineOverlay.ZeroLine |
Draw a horizontal line at the 'zero-line' position of the sparkline. The zero-line is defined by the datasource and is by default zero, however this can be changed. |
DSFSparklineOverlay.RangeHighlight |
Highlight a range of y-values on the sparkline |
DSFSparklineOverlay.GridLines |
Draw lines at specified y-values on the sparkline |
DSFSparklineLineGraphView
/DSFSparklineLineGraphView.SwiftUI
DSFSparklineStackLineGraphView
/DSFSparklineLineGraphView.SwiftUI
DSFSparklineBarGraphView
/DSFSparklineBarGraphView.SwiftUI
DSFSparklineStripesGraphView
/DSFSparklineStripesGraphView.SwiftUI
DSFSparklineDotGraphView
/DSFSparklineDotGraphView.SwiftUI
DSFSparklineWinLossGraphView
/DSFSparklineWinLossGraphView.SwiftUI
DSFSparklineTabletGraphView
/DSFSparklineTabletGraphView.SwiftUI
DSFSparklinePieGraphView
/DSFSparklinePieGraphView.SwiftUI
DSFSparklineDataBarGraphView
/DSFSparklineDataBarGraphView.SwiftUI
// Create the view
let sparklineView = DSFSparklineLineGraphView(…)
sparklineView.graphColor = UIColor.blue
sparklineView.showZeroLine = 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
Sample SwiftUI code
struct SparklineView: View {
let leftDataSource: DSFSparkline.DataSource
let rightDataSource: DSFSparkline.DataSource
let BigCyanZeroLine = DSFSparkline.ZeroLineDefinition(
color: .cyan,
lineWidth: 3,
lineDashStyle: [4,1,2,1]
)
var body: some View {
HStack {
DSFSparklineLineGraphView.SwiftUI(
dataSource: leftDataSource,
graphColor: DSFColor.red,
interpolated: true)
DSFSparklineBarGraphView.SwiftUI(
dataSource: rightDataSource,
graphColor: DSFColor.blue,
lineWidth: 2,
showZeroLine: true,
zeroLineDefinition: BigCyanZeroLine)
}
}
}
Using prebuilt views
DSFSparkline has a number of 'prebuilt' sparkline views available with a more limited scope, designed to be quicker to add to your project, especially relating to Interface Builder (the pre-built types provide an @IBDesignable
interface) so you can design the look of your graph from directly within Interface Builder.
Every prebuilt sparkline view has a SwiftUI companion view.
Prebuilt customizationsView Types and settings
Represents the viewable settings and display. The current view types available are :-
Common display customizations
Setting | Type | Description |
---|---|---|
graphColor |
NSColor UIColor |
The color to use when drawing the sparkline |
Common elements for graphs that can display a zero line (Line/Bar/Stackline)
Setting | Type | Description |
---|---|---|
dataSource |
DSFDataSource |
The source of data for the graph |
showZeroLine |
Bool |
Draw a dotted line at the zero line point on the y-axis |
zeroLineColor |
NSColor UIColor |
The color of the 'zero line' on the y-axis. |
zeroLineWidth |
CGFloat |
The width of the 'zero line' on the y-axis |
zeroLineDashStyle |
[CGFloat] |
The dash pattern to use when drawing the zero line |
Common elements for graphs that can be centered around the zero-line (Line/Bar/Stackline)
Setting | Type | Description |
---|---|---|
centeredAtZeroLine |
Bool |
Should the graph be centered at the zero line? |
lowerGraphColor |
NSColor UIColor |
The color used to draw values below the zero line. If nil, is the same as the graph color |
Line graph customizations (DSFSparklineLineGraphView
)
A simple line graph
Setting | Type | Description |
---|---|---|
dataSource |
DSFDataSource |
The source of data for the graph |
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 |
markerSize |
CGFloat |
(optional) Draw a marker of the specified size at every data point in the graph using the line color at that point |
Bar graph customizations (DSFSparklineBarGraphView
)
A simple bar graph
Setting | Type | Description |
---|---|---|
dataSource |
DSFDataSource |
The source of data for the graph |
lineWidth |
CGFloat |
The width of the line |
barSpacing |
CGFloat |
The spacing between each bar |
Stripes graph customizations (DSFSparklineStripesGraphView
)
A stripes graph. A good example of a stripes graph is the 'warming stripes' climate graph.
Values from the datasource are mapped to a supplied gradient
Setting | Type | Description |
---|---|---|
dataSource |
DSFDataSource |
The source of data for the graph |
integral |
Bool |
If true, draws the bars on pixel boundaries to get nice clean lines |
gradient |
DSFGradient |
The color gradient to use when mapping datasource values to colors. |
Dot graph customizations (DSFSparklineDotGraphView
)
A dot graph reminiscent of Activity Viewer
Setting | Type | Description |
---|---|---|
dataSource |
DSFDataSource |
The source of data for the graph |
upsideDown |
Bool |
If true, draws from the top of the graph downwards |
unsetGraphColor |
NSColor UIColor |
The color to use when drawing the background |
Win/Loss graph customizations (DSFSparklineWinLossGraphView
)
A win-loss graph, where positive values in the datasource are represented as a 'win', negative values represented as a 'loss', and zero values are a 'tie'.
Setting | Type | Description |
---|---|---|
dataSource |
DSFDataSource |
The source of data for the graph |
lineWidth |
CGFloat |
The line width for the stroke |
barSpacing |
CGFloat |
The spacing between each bar |
winColor |
NSColor UIColor |
The color to use for a 'win' |
lossColor |
NSColor UIColor |
The color to use for a 'loss' |
tieColor |
NSColor UIColor |
(optional) The color to use for a 'tie'. If nil, tie (0) values are not drawn By default, 'tie' values are not drawn. |
Tablet graph customizations (DSFSparklineTabletGraphView
)
A tablet graph, where positive values in the datasource are represented as a filled circle, negative values represented as an unfilled circle. The concept is identical to the win/loss graph except the renderering is different.
Setting | Type | Description |
---|---|---|
dataSource |
DSFDataSource |
The source of data for the graph |
lineWidth |
CGFloat |
The line width for the stroke |
barSpacing |
CGFloat |
The spacing between each bar |
winColor |
NSColor UIColor |
The color to draw the filled circle for a 'win' |
lossColor |
NSColor UIColor |
The color to draw the filled circle for a 'loss' |
Pie graph customizations (DSFSparklinePieGraphView
)
Setting | Type | Description |
---|---|---|
dataSource |
[CGFloat] |
The data to display in the pie chart |
palette |
DSFSparklinePalette |
The palette to use when drawing the chart |
strokeColor |
NSColor UIColor |
(optional) The color of the line to draw between each segment. If nil, no line is drawn |
lineWidth |
CGFloat |
The width of the lines to draw between each segment |
animated |
Bool |
If true, when the data source is set the segments animate into view |
animationDuration |
CGFloat |
The duration of the animation |
The majority of these settings are available both programatically and via @IBInspectable
in Interface Builder.
Databar graph customizations (DSFSparklineDataBarGraphView
)
Setting | Type | Description |
---|---|---|
dataSource |
[CGFloat] |
The data to display in the pie chart |
maximumTotalValue |
CGFloat |
If <= 0 the data represents a percentage of the total, if > 0 represents the rightmost value to the databar |
palette |
DSFSparklinePalette |
The palette to use when drawing. |
strokeColor |
NSColor UIColor |
(optional) The color of the line to draw between each segment. If nil, no line is drawn |
lineWidth |
CGFloat |
The width of the lines to draw between each segment |
unsetColor |
NSColor UIColor |
(optional) If the maximum value is set, if the segments don't fit the total this color is used as the background color |
animated |
Bool |
If true, when the data source is set the segments animate into view |
animationDuration |
CGFloat |
The duration of the animation |
The majority of these settings are available both programatically and via @IBInspectable
in Interface Builder.
Available graph types
Line
Standard | Centered |
---|---|
Interpolated | Interpolated Centered |
---|---|
Standard Markers | Interpolated Markers |
---|---|
Bar
Standard | Centered |
---|---|
Stackline
Standard | Centered |
---|---|
Stripes
Standard | Integral (pixel boundaries) |
---|---|
Dot
Standard | Inverted |
---|---|
Win/Loss
Win/Loss | Win/Loss/Tie |
---|---|
Tablet
Standard |
---|
Pie
Standard |
---|
DataBar
Percent | Total |
---|---|
Integration
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.
Import the library into your source files
Cocoapods
pod 'DSFSparkline', :git => 'https://github.com/dagronf/DSFSparkline/'
Swift package manager
Add https://github.com/dagronf/DSFSparkline
to your project.
Screenshots
In app
macOS dark | macOS light | iOS |
---|---|---|
Interface Builder
macOS | tvOS |
---|---|
SwiftUI
NSAttributedString support
Animated
Changes
4.1.0
- Embed sparklines in NSAttributedString.
4.0.0
Substantial re-architect of the drawing code (that used to be directly in the views) into overlays and surfaces that are far more flexible (for example, being able to draw a sparkline bitmap without having to create a view)
The previous view/swiftui types are still available - they have been rebuilt on using the new overlay scheme and are referred to in documentation as 'prebuilt' types. This allowed backwards compatibility with previous versions of the library. Note however that given that the prebuilt views have been re-written there is a possibility of slight visual differences.
3.7.0
- Added stripe graph
3.6.1
- Fixed animations on iOS/tvOS
3.6.0
- Added pie chart, databar chart.
- Added ability to show data markers for line graphs
3.5.2
- Fixed Objective-C Demo app
- Added
snapshot
method to the base sparkline view class to produce an NSImage/UIImage version of the sparkline for embedded sparklines in text etc.
3.5.1
- Fixed version in podspec
3.5.0
- Added stackline sparkline type
- Added win/loss/tie sparkline type
- Added tablet sparkline type
3.4.0
- Added support for centering line and bar graphs around their zero-line value.
3.3.0
- Fixed issue where iOS background wasn't being drawn correctly in some cases.
- Fixed rare crash where a line graph with < 2 points would crash.
3.2.0
- Changed the zero-line definition class to
DSFSparklineZeroLineDefinition
for clarity. - More documentation, especially around SwiftUI. Attempted to make the documentation clearer around drawing parameters.
3.1.0
- Add the ability to customize the zero-line display (Tito Ciuro)
- Changed
showZero
toshowZeroLine
for consistency with the new zero-line display values
3.0.0
- 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.
2.0.0
-
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 coreDSFSparklineDataSourceView
.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