ScrollableGraphView 4.0.6

ScrollableGraphView 4.0.6

Tests测试
Lang语言 SwiftSwift
许可证 MIT
Released最后发布2018年10月
SPM支持 SPM

Phillip 维护。



  • philackm

ScrollableGraphView

公告

2017年7月9日 - 寻找示例

如果你的应用程序使用此组件,并且你想展示它,请让我知道,我想要创建一个画廊。请创建一个 pull request,并更新 examples.md 中的应用程序名称和 URL。我将添加应用程序的截图到一个供所有人查看的画廊中。

2017年7月9日 - 版本 4

发布了版本 4,增加了多个绘图、动态重新加载值、更多参考线自定义选项以及各种错误修复。

您可以在这里看到 API 中的主要更改。

公共接口与旧版本不兼容。如果您希望继续使用旧版本,请确保在podfile中指定版本3或从预v4发布中下载类。

关于

Example Application Usage

适用于iOS的自适应可滚动图形视图,用于可视化简单的离散数据集。用Swift编写。最初是为一个小型个人项目编写的。

该图形组件的主要目标是可视化简单的离散数据集,并允许用户通过图形进行滚动。

Init Animation

贡献

欢迎所有拉取请求。在问题页面上有一份人们希望添加的功能列表,从简单的更改到相当复杂的功能都有。请随意参与。

赞助商

此组件的开发得到了Anomaly的支持。请访问[Anomaly](https://www.anomaly.net.au/)了解更多信息。

目录

功能

特性列表
初始化动画和范围适配动画。

Animating
多个图形和动态加载数值。

dynamic-reload
在图形中滚动时进行范围适配。y轴的范围将自动适应可见点的最小值和最大值。

Adapting
图形周围平滑滚动。

Scrolling
可以处理大量数据点。

More_Scrolling
许多自定义选项。(请参阅自定义部分)

Customising

使用方法

将 ScrollableGraphView 添加到你的项目中

ScrollableGraphView 类添加到你的项目中。有两种方法可以将 ScrollableGraphView 添加到你的项目中。

手动

Classes 目录下的所有文件添加到 Xcode 中的项目中。

CocoaPods

在 Podfile 中添加 pod 'ScrollableGraphView',然后确保在你的代码中 import ScrollableGraphView

Carthage

github "philackm/ScrollableGraphView" ~> 4.0.2 添加到你的 Cartfile 中,然后确保在你的代码中链接框架并 import ScrollableGraphView

创建图表并向其提供数据。

  1. 创建 ScrollableGraphView 实例。图表需要一个数据源,这是一个符合 ScrollableGraphViewDataSource 协议的对象。

    // Compose the graph view by creating a graph, then adding any plots
    // and reference lines before adding the graph to the view hierarchy.
    let graphView = ScrollableGraphView(frame: frame, dataSource: self)
    
    let linePlot = LinePlot(identifier: "line") // Identifier should be unique for each plot.
    let referenceLines = ReferenceLines()
    
    graphView.addPlot(plot: linePlot)
    graphView.addReferenceLines(referenceLines: referenceLines)
  2. 确保dataSource对象符合ScrollableGraphViewDataSource协议,并且按照以下方式实现以下三个方法

    func value(forPlot plot: Plot, atIndex pointIndex: Int) -> Double {
        // Return the data for each plot.
        switch(plot.identifier) { 
        case "line":
            return linePlotData[pointIndex]
        default:
            return 0
        }
    }
    
    func label(atIndex pointIndex: Int) -> String {
        return "FEB \(pointIndex)"
    }
    
    func numberOfPoints() -> Int {
        return numberOfDataPointsInGraph
    }
  3. 最后,将ScrollableGraphView添加到视图层次结构中。

    someViewController.view.addSubview(graphView)

这将创建一个看起来像这样的图表

SimpleGraph

Interface Builder支持

现在支持Interface Builder(从CocoaPod版本2.0.0)。请参阅文件夹中的示例项目:graphview_example_ib

你可以用它来做什么

  • ✔ 研究应用程序来显示学习时间等
  • ✔ 天气应用程序
  • ✔ 原型设计
  • 简单数据可视化

你不能用它来做什么

  • ✘ 精密统计软件
  • ✘ 重要且复杂的数据可视化
  • ✘ 绘制连续数学函数的图

定制

图表是通过首先创建一个空的ScrollableGraphView对象,并逐步添加所需的所有绘图和参考线来构成的。

使用任一LinePlotDotPlotBarPlot构造函数创建绘图。使用ReferenceLines()构造函数创建参考线。在将ScrollableGraphView对象添加到视图层次结构之前,使用addPlotaddReferenceLines方法将绘图和参考线添加到图表。您可以添加多个绘图(下面显示了示例)。每个绘图必须有相同数量的数据点。

在Interface Builder的情况下,图表的定制是通过属性表单完成的,而图表和参考线的定制是在相应的视图控制器中进行的。请参阅文件夹中的示例项目:graphview_example_ib

图自定义

这些设置可以直接在将其添加到视图层次结构之前设置在ScrollableGraphView对象上。

适应和动画

属性 描述
shouldAdaptRange: Bool 是否让y轴的范围适应屏幕上可见的点。这意味着如果任何给定时间内屏幕上只有5个点可见,y轴上的最大值将是这5个点中的最大值。这会随着用户在图表上滚动而自动更新。Adapting
shouldAnimateOnAdapt: Bool 如果将shouldAdaptRange设置为true,则指定是否使图表上的点动画到它们的新位置。默认设置为true。如果设置为false则会看起来非常糟糕。
shouldAnimateOnStartup: Bool 图形是否在图表首次显示时将其位置动画化。

空隙

spacing

属性 描述
topMargin: CGFloat “最大”参考线与视图边界顶部的距离。以点为单位。
bottomMargin: CGFloat “最小”参考线与视图边界底部的距离。以点为单位。
leftmostPointPadding: CGFloat 图表的第一个点应放置在视图左侧多远的地方。
rightmostPointPadding: CGFloat 图表的最后一个点应放置在视图右侧多远的地方。
dataPointSpacing: CGFloat 每个数据点之间应有多少空间。
direction: ScrollableGraphViewDirection 预计用户将从哪个方向滚动。可能的值
  • ScrollableGraphViewDirection.leftToRight
  • ScrollableGraphViewDirection.rightToLeft
例如,如果设置为.rightToLeft,则图表将从图表的“右侧”开始,用户需要向左滚动。

图范围

属性 描述
rangeMin: 双精度浮点数 y轴的最小值。当 shouldAdaptRange = true 时,此值被忽略
rangeMax: 双精度浮点数 y轴的最大值。当 shouldAdaptRange = true 时,此值被忽略
shouldRangeAlwaysStartAtZero: 布尔值 强制图形的最小值始终为零。与 shouldAdaptRange 结合使用,如果您想强制最小值保持在0而不是检测到的最小值。

绘图定制

对于所有绘图,您可以为绘图第一次出现和自适应过程中指定与动画相关的信息。

动画

属性 描述
animationDuration: 双精度浮点数 动画应持续多长时间。影响启动动画和y轴范围自适应到屏幕上的点的动画。
adaptAnimationType: 可滚动图形视图动画类型 动画风格。可能的值
  • 可滚动图形视图动画类型.easeOut
  • 可滚动图形视图动画类型.elastic
  • 可滚动图形视图动画类型.custom
customAnimationEasingFunction: ((t: Double) -> Double)? 如果 adaptAnimationType 设置为 .custom,则这是如果您想应用于动画的缓动函数。

折线图

折线图特定的自定义选项。这些选项在任意的 LinePlot 对象上可用。

线条样式

属性 描述
lineWidth: 常量浮点型尺寸 指定线条图形的厚度。以点到
lineColor: UIColor 图表线的颜色。UIColor类型。
lineStyle: ScrollableGraphViewLineStyle 是否使用贝塞尔曲线进行线的渲染或者为直线。可能的值
  • ScrollableGraphViewLineStyle.straight
  • ScrollableGraphViewLineStyle.smooth
lineJoin 线的每个部分是如何连接的。接受Core Animation中LineJoin的所有值。
lineCap 线的端点样式。接受Core Animation中LineCap的所有值。

填充样式

属性 描述
shouldFill: Bool 指定绘制的图表是否使用颜色或渐变进行填充。
fillType: ScrollableGraphViewFillType 指定是否用实色或渐变填充图表。可能的值
  • ScrollableGraphViewFillType.solid
  • ScrollableGraphViewFillType.gradient
fillColor: UIColor 如果fillType设置为.solid,则此颜色将用于填充图表。
fillGradientStartColor: UIColor 如果fillType设置为.gradient,则此颜色将是渐变的起始颜色。
fillGradientEndColor: UIColor 如果fillType设置为.gradient,则此颜色将是渐变的结束颜色。
fillGradientType: ScrollableGraphViewGradientType 如果fillType设置为.gradient,则此属性定义渐变是渲染为线性渐变还是辐射渐变。可能的值
  • ScrollableGraphViewGradientType.linear
  • ScrollableGraphViewGradientType.radial

点图

点图特定的自定义选项。这些选项适用于任何DotPlot对象。

属性 描述
dataPointType: ScrollableGraphViewDataPointType 绘制每个数据点的形状。可能的值
  • ScrollableGraphViewDataPointType.circle
  • ScrollableGraphViewDataPointType.square
  • ScrollableGraphViewDataPointType.custom
dataPointSize: CGFloat 绘制每个数据点形状的大小。
dataPointFillColor: UIColor 填充形状的颜色。
customDataPointPath: ((center: CGPoint) -> UIBezierPath)? 如果dataPointType设置为.custom,则可以提供一个闭包来创建任何想要的形状,而不是只是圆形或正方形。这个闭包接受一个CGPoint,它是形状的中心,并且应该返回一个完整的UIBezierPath

条形图

柱状图特定自定义选项。这些选项在任何 BarPlot 对象上都是可用的。

属性 描述
barWidth: CGFloat 图表中单个柱的宽度。
barColor: UIColor 柱的实际颜色。
barLineWidth: CGFloat 柱轮廓的宽度。
barLineColor: UIColor 柱轮廓的颜色。
shouldRoundBarCorners: Bool 是否使用圆角来处理柱。

参考线自定义

在将参考线添加到图表视图中之前,在 ReferenceLines 对象上设置这些选项。

参考线

属性 描述
shouldShowReferenceLines: Bool 是否显示y轴的参考线及标签。
positionType: ReferenceLinePositioningType 参考线应相对放置(例如在最大y轴值的0%,20%,40%,60%,80%和100%处),或者在y轴上特定值处绝对放置。可能的值
  • ReferenceLinePositioningType.relative
  • ReferenceLinePositioningType.absolute
relativePositions: [Double] 一个数组,指定参考线放置的位置。如果 positionType == .relative 时使用。例如,分配值 [0, 0.5, 1] 将在图表中添加3条参考线,一条位于y轴底部(0%),一条位于y轴中间(50%),一条位于顶部(100%)。数组中所有值应在0到1之间。
absolutePositions: [Double] 一个数组,指定参考线放置的绝对位置。如果 positionType == .absolute 时使用。例如,分配值 [10, 35] 将在图表中添加2条参考线,一条位于y轴值10处,一条位于y轴值35处。
includeMinMax: Bool 是否渲染最小和最大参考线。如果是true,则始终渲染最小和最大参考线。如果只想指定一个或两个(通过 relativePositionsabsolutePositions,则将其设置为false。
referenceLineColor: UIColor 参考线的颜色。
referenceLineThickness: CGFloat 参考线的厚度。
referenceLinePosition: ScrollableGraphViewReferenceLinePosition 在参考线上标签应显示的位置。可能的值
  • ScrollableGraphViewReferenceLinePosition.left
  • ScrollableGraphViewReferenceLinePosition.right
  • ScrollableGraphViewReferenceLinePosition.both
shouldAddLabelsToIntermediateReferenceLines: Bool 是否在中间参考线上添加标签(在最小值和最大值之间)。
shouldAddUnitsToIntermediateReferenceLineLabels: Bool 是否将由 referenceLineUnits 变量指定的单位添加到中间参考线上的标签。

参考线标签(y轴)

属性 描述
referenceLineLabelFont: UIFont 用于参考线标签的字体。
referenceLineLabelColor: UIColor 参考线标签的颜色。
shouldShowReferenceLineUnits: Bool 是否显示参考线上的单位。
referenceLineUnits: String? y轴的单位。此字符串用于参考线上的标签。
referenceLineNumberOfDecimalPlaces: Int 参考线标签上应显示的小数位数。
referenceLineNumberStyle: NSNumberFormatterStyle 参考线标签上应显示的数字格式。

数据点标签(x轴)

属性 描述
shouldShowLabels: Bool 是否在每一点上显示x轴的标签。
dataPointLabelTopMargin: CGFloat 数据点标签应渲染在“最小”参考线有多远。
dataPointLabelBottomMargin: CGFloat 数据点标签从视图的底部渲染有多远。
dataPointLabelFont: UIFont? 数据点标签的字体。
dataPointLabelColor: UIColor 数据点标签的颜色。
dataPointLabelsSparsity: Int 用于强制图形显示每n个数据点的标签。

自定义示例

所有这些示例都可以在示例项目中看到:graphview_example_code

在Xcode中打开项目并运行。

注意:此处使用的是 UIColor 的“colorFromHex”扩展。

默认

simple

let graphView = ScrollableGraphView(frame: frame, dataSource: self)

let linePlot = LinePlot(identifier: "simple") // Identifier should be unique for each plot.
let referenceLines = ReferenceLines()

graphView.addPlot(plot: linePlot)
graphView.addReferenceLines(referenceLines: referenceLines)

暗色条(感谢 @RedBlueThing 提供的条层)

bar-dark

let graphView = ScrollableGraphView(frame: frame, dataSource: self)

// Setup the plot
let barPlot = BarPlot(identifier: "bar")

barPlot.barWidth = 25
barPlot.barLineWidth = 1
barPlot.barLineColor = UIColor.colorFromHex(hexString: "#777777")
barPlot.barColor = UIColor.colorFromHex(hexString: "#555555")

barPlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic
barPlot.animationDuration = 1.5

// Setup the reference lines
let referenceLines = ReferenceLines()

referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 8)
referenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.2)
referenceLines.referenceLineLabelColor = UIColor.white

referenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(0.5)

// Setup the graph
graphView.backgroundFillColor = UIColor.colorFromHex(hexString: "#333333")

graphView.shouldAnimateOnStartup = true

graphView.rangeMax = 100
graphView.rangeMin = 0

// Add everything
graphView.addPlot(plot: barPlot)
graphView.addReferenceLines(referenceLines: referenceLines)
return graphView

平滑暗色

line-dark-smooth

let graphView = ScrollableGraphView(frame: frame, dataSource: self)

// Setup the line plot.
let linePlot = LinePlot(identifier: "darkLine")

linePlot.lineWidth = 1
linePlot.lineColor = UIColor.colorFromHex(hexString: "#777777")
linePlot.lineStyle = ScrollableGraphViewLineStyle.smooth

linePlot.shouldFill = true
linePlot.fillType = ScrollableGraphViewFillType.gradient
linePlot.fillGradientType = ScrollableGraphViewGradientType.linear
linePlot.fillGradientStartColor = UIColor.colorFromHex(hexString: "#555555")
linePlot.fillGradientEndColor = UIColor.colorFromHex(hexString: "#444444")

linePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic

let dotPlot = DotPlot(identifier: "darkLineDot") // Add dots as well.
dotPlot.dataPointSize = 2
dotPlot.dataPointFillColor = UIColor.white

dotPlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic

// Setup the reference lines.
let referenceLines = ReferenceLines()

referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 8)
referenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.2)
referenceLines.referenceLineLabelColor = UIColor.white

referenceLines.positionType = .absolute
// Reference lines will be shown at these values on the y-axis.
referenceLines.absolutePositions = [10, 20, 25, 30]
referenceLines.includeMinMax = false

referenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(0.5)

// Setup the graph
graphView.backgroundFillColor = UIColor.colorFromHex(hexString: "#333333")
graphView.dataPointSpacing = 80

graphView.shouldAnimateOnStartup = true
graphView.shouldAdaptRange = true
graphView.shouldRangeAlwaysStartAtZero = true

graphView.rangeMax = 50

// Add everything to the graph.
graphView.addReferenceLines(referenceLines: referenceLines)
graphView.addPlot(plot: linePlot)
graphView.addPlot(plot: dotPlot)

dot

let graphView = ScrollableGraphView(frame: frame, dataSource: self)

// Setup the plot
let plot = DotPlot(identifier: "dot")

plot.dataPointSize = 5
plot.dataPointFillColor = UIColor.white

// Setup the reference lines
let referenceLines = ReferenceLines()
referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 10)
referenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.5)
referenceLines.referenceLineLabelColor = UIColor.white
referenceLines.referenceLinePosition = ScrollableGraphViewReferenceLinePosition.both

referenceLines.shouldShowLabels = false

// Setup the graph
graphView.backgroundFillColor = UIColor.colorFromHex(hexString: "#00BFFF")
graphView.shouldAdaptRange = false
graphView.shouldAnimateOnAdapt = false
graphView.shouldAnimateOnStartup = false

graphView.dataPointSpacing = 25
graphView.rangeMax = 50
graphView.rangeMin = 0

// Add everything
graphView.addPlot(plot: plot)
graphView.addReferenceLines(referenceLines: referenceLines)

粉色

line-pink-straight

let graphView = ScrollableGraphView(frame: frame, dataSource: self)

// Setup the plot
let linePlot = LinePlot(identifier: "pinkLine")

linePlot.lineColor = UIColor.clear
linePlot.shouldFill = true
linePlot.fillColor = UIColor.colorFromHex(hexString: "#FF0080")

// Setup the reference lines
let referenceLines = ReferenceLines()

referenceLines.referenceLineThickness = 1
referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 10)
referenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.5)
referenceLines.referenceLineLabelColor = UIColor.white
referenceLines.referenceLinePosition = ScrollableGraphViewReferenceLinePosition.both

referenceLines.dataPointLabelFont = UIFont.boldSystemFont(ofSize: 10)
referenceLines.dataPointLabelColor = UIColor.white
referenceLines.dataPointLabelsSparsity = 3

// Setup the graph
graphView.backgroundFillColor = UIColor.colorFromHex(hexString: "#222222")

graphView.dataPointSpacing = 60
graphView.shouldAdaptRange = true

// Add everything
graphView.addPlot(plot: linePlot)
graphView.addReferenceLines(referenceLines: referenceLines)

多图 v1

multi-v1

// Setup the line plot.
let blueLinePlot = LinePlot(identifier: "multiBlue")

blueLinePlot.lineWidth = 1
blueLinePlot.lineColor = UIColor.colorFromHex(hexString: "#16aafc")
blueLinePlot.lineStyle = ScrollableGraphViewLineStyle.smooth

blueLinePlot.shouldFill = true
blueLinePlot.fillType = ScrollableGraphViewFillType.solid
blueLinePlot.fillColor = UIColor.colorFromHex(hexString: "#16aafc").withAlphaComponent(0.5)

blueLinePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic

// Setup the second line plot.
let orangeLinePlot = LinePlot(identifier: "multiOrange")

orangeLinePlot.lineWidth = 1
orangeLinePlot.lineColor = UIColor.colorFromHex(hexString: "#ff7d78")
orangeLinePlot.lineStyle = ScrollableGraphViewLineStyle.smooth

orangeLinePlot.shouldFill = true
orangeLinePlot.fillType = ScrollableGraphViewFillType.solid
orangeLinePlot.fillColor = UIColor.colorFromHex(hexString: "#ff7d78").withAlphaComponent(0.5)

orangeLinePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic

// Setup the reference lines.
let referenceLines = ReferenceLines()

referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 8)
referenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.2)
referenceLines.referenceLineLabelColor = UIColor.white

referenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(1)

// Setup the graph
graphView.backgroundFillColor = UIColor.colorFromHex(hexString: "#333333")

graphView.dataPointSpacing = 80
graphView.shouldAnimateOnStartup = true
graphView.shouldAdaptRange = true

graphView.shouldRangeAlwaysStartAtZero = true

// Add everything to the graph.
graphView.addReferenceLines(referenceLines: referenceLines)
graphView.addPlot(plot: blueLinePlot)
graphView.addPlot(plot: orangeLinePlot)

多图 v2

可以将多个图表组合起来以获得不同的外观。在此情况下,我们使用点图在折线图上添加标记。

multi-v2

let graphView = ScrollableGraphView(frame: frame, dataSource: self)

// Setup the first plot.
let blueLinePlot = LinePlot(identifier: "multiBlue")

blueLinePlot.lineColor = UIColor.colorFromHex(hexString: "#16aafc")
blueLinePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic

// dots on the line
let blueDotPlot = DotPlot(identifier: "multiBlueDot")
blueDotPlot.dataPointType = ScrollableGraphViewDataPointType.circle
blueDotPlot.dataPointSize = 5
blueDotPlot.dataPointFillColor = UIColor.colorFromHex(hexString: "#16aafc")

blueDotPlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic

// Setup the second plot.
let orangeLinePlot = LinePlot(identifier: "multiOrange")

orangeLinePlot.lineColor = UIColor.colorFromHex(hexString: "#ff7d78")
orangeLinePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic

// squares on the line
let orangeSquarePlot = DotPlot(identifier: "multiOrangeSquare")
orangeSquarePlot.dataPointType = ScrollableGraphViewDataPointType.square
orangeSquarePlot.dataPointSize = 5
orangeSquarePlot.dataPointFillColor = UIColor.colorFromHex(hexString: "#ff7d78")

orangeSquarePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic

// Setup the reference lines.
let referenceLines = ReferenceLines()

referenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 8)
referenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.2)
referenceLines.referenceLineLabelColor = UIColor.white
referenceLines.relativePositions = [0, 0.2, 0.4, 0.6, 0.8, 1]

referenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(1)

// Setup the graph
graphView.backgroundFillColor = UIColor.colorFromHex(hexString: "#333333")

graphView.dataPointSpacing = 80

graphView.shouldAnimateOnStartup = true
graphView.shouldAdaptRange = true
graphView.shouldRangeAlwaysStartAtZero = true

// Add everything to the graph.
graphView.addReferenceLines(referenceLines: referenceLines)
graphView.addPlot(plot: blueLinePlot)
graphView.addPlot(plot: blueDotPlot)
graphView.addPlot(plot: orangeLinePlot)
graphView.addPlot(plot: orangeSquarePlot)

已知问题

  • 图表加入视图层次结构后,某些方面无法自定义。
  • 目前不支持使用不同数量的数据项重新加载图表。
  • 在模拟器中的性能不佳。

如果您发现任何错误,请在 Github 上创建一个问题。

其他

关注我 Twitter 获取关于其他有趣内容的更新(也就是动态图)。