[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-6832":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":15,"stars30d":15,"stars90d":15,"forks30d":15,"starsTrendScore":15,"compositeScore":16,"rankGlobal":9,"rankLanguage":9,"license":17,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":20,"hasPages":18,"topics":21,"createdAt":9,"pushedAt":9,"updatedAt":22,"readmeContent":23,"aiSummary":24,"trendingCount":15,"starSnapshotCount":15,"syncStatus":25,"lastSyncTime":26,"discoverSource":27},6832,"ScrollableGraphView","philackm\u002FScrollableGraphView","philackm","An adaptive scrollable graph view for iOS to visualise simple discrete datasets. Written in Swift.",null,"Swift",5294,462,119,55,0,39,"MIT License",false,"master",true,[],"2026-06-12 02:01:30","# ScrollableGraphView\n\n## Announcements\n\n### 9-7-2017 - Version 4: \n\nVersion 4 was released which adds multiple plots, dynamic reloading of values, more reference line customisation options and various bug fixes. \n\nYou can see the major changes in the API [here](APIv4.md).\n\nThe public interface is incompatible with previous versions. If you prefer to keep using the older version, make sure to specify version 3 in your podfile or downloaded the classes from a pre-v4 release.\n\n## About\n\n![Example Application Usage](readme_images\u002FIMG_5814_small.jpg)\n\nAn adaptive scrollable graph view for iOS to visualise simple discrete datasets. Written in Swift. Originally written for a small personal project.\n\nThe main goal of the this graph component is to visualise simple discrete datasets and allow the the user to scroll through the graph.\n\n![Init Animation](readme_images\u002Finit_anim_high_fps.gif)\n\n### Contribution\n\nAll pull requests are welcome. There is a list of features people would like on the issues page, ranging from simple changes to quite complex. Feel free to jump on in.\n\n## Sponsors\n\nDevelopment of this component has been sponsored by **Anomaly**. Check them out [here](https:\u002F\u002Fwww.anomaly.net.au\u002F).\n\n## Contents\n\n- [Features](#features)\n- [Basic Usage](#usage)\n- [Customisation](#customisation)\n- [Customisation Examples](#customisation-examples)\n- [Improvements](#improvements)\n- [Other](#other)\n\n## Features\n\n| Feature List |\n|--------|\n| Initialisation animations and range adaption animations. \u003Cbr>\u003Cbr> ![Animating](readme_images\u002Fanimating.gif)|\n| Multiple plots and dynamic reloading of the values. \u003Cbr>\u003Cbr> ![dynamic-reload](readme_images\u002Fdynamic-reload.gif)|\n| Range adaption when scrolling through the graph. The range of the y-axis will automatically adapt to to the min and max of the visible points. \u003Cbr>\u003Cbr> ![Adapting](readme_images\u002Fadapting.gif)|\n| Smooth scrolling around the graph. \u003Cbr>\u003Cbr> ![Scrolling](readme_images\u002Fscrolling.gif)|\n| Handles as many points as you can throw at it. \u003Cbr>\u003Cbr> ![More_Scrolling](readme_images\u002Fmore_scrolling.gif)|\n| Many customisation options. (Check the customisation section) \u003Cbr>\u003Cbr> ![Customising](readme_images\u002Fcustomising.gif)|\n\n## Usage\n\n### Adding the ScrollableGraphView to your project:\n\nAdd the ```ScrollableGraphView``` class to your project. There are two ways to add the ScrollableGraphView to your project.\n\n#### Manually\nAdd all of the files in the [Classes](Classes\u002F) directory to your project in Xcode to your project in Xcode.\n\n#### CocoaPods\nAdd ```pod 'ScrollableGraphView'``` to your Podfile and then make sure to ```import ScrollableGraphView``` in your code.\n\n#### Carthage\nAdd `github \"philackm\u002FScrollableGraphView\" ~> 4.0.2` to your Cartfile and then make sure to link the frameworks and `import ScrollableGraphView` in your code.\n\n### Creating a graph and providing it with data.\n\n1. Create a ScrollableGraphView instance. The graph requires a data source, which is an object that conforms to the `ScrollableGraphViewDataSource` protocol.\n\n    ```swift\n    \u002F\u002F Compose the graph view by creating a graph, then adding any plots\n    \u002F\u002F and reference lines before adding the graph to the view hierarchy.\n    let graphView = ScrollableGraphView(frame: frame, dataSource: self)\n    \n    let linePlot = LinePlot(identifier: \"line\") \u002F\u002F Identifier should be unique for each plot.\n    let referenceLines = ReferenceLines()\n    \n    graphView.addPlot(plot: linePlot)\n    graphView.addReferenceLines(referenceLines: referenceLines)\n    ```  \n\n2. Ensure the dataSource object conforms to the `ScrollableGraphViewDataSource` protocol and implements the following three methods like so:\n\n    ```swift\n    func value(forPlot plot: Plot, atIndex pointIndex: Int) -> Double {\n        \u002F\u002F Return the data for each plot.\n        switch(plot.identifier) { \n        case \"line\":\n            return linePlotData[pointIndex]\n        default:\n            return 0\n        }\n    }\n    \n    func label(atIndex pointIndex: Int) -> String {\n        return \"FEB \\(pointIndex)\"\n    }\n    \n    func numberOfPoints() -> Int {\n        return numberOfDataPointsInGraph\n    }\n    ```\n\n3. Finally, add the ScrollableGraphView to the view hierarchy.\n\n    ```swift\n    someViewController.view.addSubview(graphView)\n    ```\n\nThis will create a graph that looks something like:\n\n![SimpleGraph](readme_images\u002Fsimple.png)\n\n### Interface Builder support\n\nThere is now support for Interface Builder (from CocoaPod version 2.0.0). See the example project in the folder: [graphview_example_ib](graphview_example_ib\u002F)\n\n### Things you *could* use it for:\n\n- ✔ Study applications to show time studied\u002Fetc\n- ✔ Weather applications\n- ✔ Prototyping\n- ✔ *Simple* data visualisation\n\n### Things you **shouldn't\u002Fcannot** use it for:\n\n- ✘ Rigorous statistical software\n- ✘ Important & complex data visualisation\n- ✘ Graphing continuous mathematical functions\n\n## Customisation\n\nThe entire graph is composed by initially creating an empty `ScrollableGraphView` object and progressively adding whatever plots and reference lines you require. \n\nCreate a plot using the any of the `LinePlot`, `DotPlot`, `BarPlot` constructors. Create reference lines using the `ReferenceLines()` constructor. Before adding the `ScrollableGraphView` object to the view hierarchy, add the plots and reference lines to the graph using the `addPlot` and `addReferenceLines` methods. You can add multiple plots (examples are shown below). Each plot _must_ have the same number of data points.\n\nIn the case of interface builder, graph customisation is performed via the properties pane, whilst plots and reference lines customisation is done in the corresponding view controller. See the example project in the folder: [graphview_example_ib](graphview_example_ib\u002F)\n\n## Graph Customisation\n\nThese settings can be set directly on the `ScrollableGraphView` object before adding it to the view hierarchy.\n\n#### Adapting & Animations\n| Property                                                | Description                                                                                                                                                                                                                                                                                            |\n|---------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| **shouldAdaptRange**: Bool                                  | Whether or not the y-axis' range should adapt to the points that are visible on screen. This means if there are only 5 points visible on screen at any given time, the maximum on the y-axis will be the maximum of those 5 points. This is updated automatically as the user scrolls along the graph. ![Adapting](readme_images\u002Fadapting.gif)|\n| **shouldAnimateOnAdapt**: Bool                              | If `shouldAdaptRange` is set to true then this specifies whether or not the points on the graph should animate to their new positions. Default is set to `true`. Looks very janky if set to `false`.                                                                                                         |\n| **shouldAnimateOnStartup**: Bool                            | Whether or not the graph should animate to their positions when the graph is first displayed.                                                                                                                                                                                                          |\n\n#### Spacing\n![spacing](readme_images\u002Fspacing.png)\n\n| Property              | Description                                                                                                                                                                                                                                                                                                |\n|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| **topMargin**: CGFloat             | How far the \"maximum\" reference line is from the top of the view's frame. In points.                                                                                                                                                                                                                       |\n| **bottomMargin**: CGFloat          | How far the \"minimum\" reference line is from the bottom of the view's frame. In points.                                                                                                                                                                                                                    |\n| **leftmostPointPadding**: CGFloat  | How far the first point on the graph should be placed from the left hand side of the view.                                                                                                                                                                                                                 |\n| **rightmostPointPadding**: CGFloat | How far the final point on the graph should be placed from the right hand side of the view.                                                                                                                                                                                                                |\n| **dataPointSpacing**: CGFloat      | How much space should be between each data point.                                                                                                                                                                                                                                                          |\n| **direction**: ScrollableGraphViewDirection             | Which way the user is expected to scroll from. Possible values: \u003Cul>\u003Cli>`ScrollableGraphViewDirection.leftToRight`\u003C\u002Fli>\u003Cli>`ScrollableGraphViewDirection.rightToLeft`\u003C\u002Fli>\u003C\u002Ful>For example, if it is set to `.rightToLeft`, the graph will start on the \"right hand side\" of the graph and the user will have to scroll towards the left. |\n\n#### Graph Range\n| Property                       | Description                                                                                                                                                                                                |\n|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| **rangeMin**: Double                       | The minimum value for the y-axis. This is ignored when `shouldAdaptRange` = `true`                                                                                           |\n| **rangeMax**: Double                       | The maximum value for the y-axis. This is ignored when `shouldAdaptRange` = `true`                                                                                           |\n| **shouldRangeAlwaysStartAtZero**: Bool   | Forces the graph's minimum to always be zero. Used in conjunction with `shouldAdaptRange`, if you want to force the minimum to stay at 0 rather than the detected minimum. |\n\n\n## Plot Customisation\n\n\nFor all plots you can specify animation related information for when the plot first appears and during adaptions.\n\n#### Animation\n| Property                                                | Description                                                                                                                                                                                                                                                                                            |\n|---------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| **animationDuration**: Double                               | How long the animation should take. Affects both the startup animation and the animation when the range of the y-axis adapts to onscreen points.                                                                                                                                                       |\n| **adaptAnimationType**: ScrollableGraphViewAnimationType    | The animation style. Possible values: \u003Cul>\u003Cli>`ScrollableGraphViewAnimationType.easeOut`\u003C\u002Fli>\u003Cli>`ScrollableGraphViewAnimationType.elastic`\u003C\u002Fli>\u003Cli>`ScrollableGraphViewAnimationType.custom`\u003C\u002Fli>\u003C\u002Ful>                                                                                                                                          |\n| **customAnimationEasingFunction**: ((t: Double) -> Double)? | If `adaptAnimationType` is set to `.custom`, then this is the easing function you would like applied for the animation.                                                                                                                                                                                    |\n\n### LinePlot\n\nLine plot specific customisation options. These options are available on any `LinePlot` object.\n\n#### Line Styles\n| Property  | Description                                                                                                                                                                        |\n|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| **lineWidth**: CGFloat | Specifies how thick the graph of the line is. In points.                                                                                                                           |\n| **lineColor**: UIColor | The color of the graph line. UIColor.                                                                                                                                              |\n| **lineStyle**: ScrollableGraphViewLineStyle | Whether or not the line should be rendered using bezier curves are straight lines. Possible values: \u003Cul>\u003Cli>`ScrollableGraphViewLineStyle.straight`\u003C\u002Fli>\u003Cli>`ScrollableGraphViewLineStyle.smooth`\u003C\u002Fli>\u003C\u002Ful> |\n| **lineJoin**  | How each segment in the line should connect. Takes any of the Core Animation LineJoin values.                                                                                      |\n| **lineCap**   | The line caps. Takes any of the Core Animation LineCap values.                                                                                                                     |\n\n#### Fill Styles\n| Property               | Description                                                                                                                                                                                                         |\n|------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| **shouldFill**: Bool             | Specifies whether or not the plotted graph should be filled with a colour or gradient.                                                                                                                              |\n| **fillType**: ScrollableGraphViewFillType               | Specifies whether to fill the graph with a solid colour or gradient. Possible values: \u003Cul>\u003Cli>`ScrollableGraphViewFillType.solid`\u003C\u002Fli> \u003Cli>`ScrollableGraphViewFillType.gradient`\u003C\u002Fli>\u003C\u002Ful>                                                         |\n| **fillColor**: UIColor              | If `fillType` is set to `.solid` then this colour will be used to fill the graph.                                                                                                                                       |\n| **fillGradientStartColor**: UIColor | If `fillType` is set to `.gradient` then this will be the starting colour for the gradient.                                                                                                                             |\n| **fillGradientEndColor**: UIColor   | If `fillType` is set to `.gradient`, then this will be the ending colour for the gradient.                                                                                                                              |\n| **fillGradientType**:ScrollableGraphViewGradientType       | If `fillType` is set to `.gradient`, then this defines whether the gradient is rendered as a linear gradient or radial gradient. Possible values: \u003Cul>\u003Cli>`ScrollableGraphViewGradientType.linear`\u003C\u002Fli>\u003Cli>`ScrollableGraphViewGradientType.radial`\u003C\u002Fli>\u003C\u002Ful> |\n\n### DotPlot\n\nDot plot specific customisation options. These options are available on any `DotPlot` object.\n\n| Property                                                  | Description                                                                                                                                                                                                                                                                 |\n|-----------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| **dataPointType**: ScrollableGraphViewDataPointType           | The shape to draw for each data point. Possible values: \u003Cul>\u003Cli>`ScrollableGraphViewDataPointType.circle`\u003C\u002Fli>\u003Cli>`ScrollableGraphViewDataPointType.square`\u003C\u002Fli>\u003Cli>`ScrollableGraphViewDataPointType.custom`\u003C\u002Fli>\u003C\u002Ful>                                                                                               |\n| **dataPointSize**: CGFloat                                    | The size of the shape to draw for each data point.                                                                                                                                                                                                                          |\n| **dataPointFillColor**: UIColor                               | The colour with which to fill the shape.                                                                                                                                                                                                                                    |\n| **customDataPointPath**: ((centre: CGPoint) -> UIBezierPath)? | If `dataPointType` is set to `.custom` then you,can provide a closure to create any kind of shape you would like to be displayed instead of just a circle or square. The closure takes a `CGPoint` which is the centre of the shape and it should return a complete `UIBezierPath`. |\n\n### BarPlot\n\nBar plot specific customisation options. These options are available on any `BarPlot` object.\n\n| Property                              | Description|\n|---------------------------------------|------------|\n| **barWidth**: CGFloat                 | The width of an individual bar on the graph.|\n| **barColor**: UIColor                 | The actual colour of the bar.|\n| **barLineWidth**: CGFloat             | The width of the outline of the bar.|\n| **barLineColor**: UIColor             | The colour of the bar outline.|\n| **shouldRoundBarCorners**: Bool       | Whether or not to use rounded corners for the bars.|\n\n\n## Reference Line Customisation\n\n\nThese options are set on the `ReferenceLines` object before adding it to the graph view.\n\n### Reference Lines\n\n| Property                                                        | Description|\n|-----------------------------------------------------------------|------------|\n| **shouldShowReferenceLines**: Bool                                  | Whether or not to show the y-axis reference lines and labels.|\n| **positionType**: ReferenceLinePositioningType         | Whether the reference lines should be placed relatively, (for example at 0%, 20%, 40%, 60%, 80% and 100% of the max y-axis value), or absolutely at specific values on the y-axis. Possible values: \u003Cul>\u003Cli>`ReferenceLinePositioningType.relative`\u003C\u002Fli>\u003Cli>`ReferenceLinePositioningType.absolute`\u003C\u002Fli>\u003C\u002Ful>|\n| **relativePositions**: [Double]                         | An array of positions where the reference lines should be placed. Used if `positionType == .relative`. For example, assigning a value of [0, 0.5, 1] will add 3 reference lines to the graph, one at the bottom of the y-axis (0%), one in the middle of the y-axis (50%) and one at the top (100%). All values in the array should be between 0 and 1. |\n| **absolutePositions**: [Double]                         | An array of absolute positions where the reference lines should be placed. Used if `positionType == .absolute`. For example, assigning a value of [10, 35] will add 2 reference lines to the graph, one at the value of 10 on the y-axis, one at the value of 35 on the y-axis. |\n| **includeMinMax**: Bool                         | Whether or not you want to render the minimum and maximum reference line. If this is true, the min and max reference lines are always rendered. Set this to false if you want to specify only one, or neither, with `relativePositions` or `absolutePositions`. |\n| **referenceLineColor**: UIColor                                     | The colour for the reference lines.|\n| **referenceLineThickness**: CGFloat                                 | The thickness of the reference lines.|\n| **referenceLinePosition**: ScrollableGraphViewReferenceLinePosition | Where the labels should be displayed on the reference lines. Possible values: \u003Cul>\u003Cli>`ScrollableGraphViewReferenceLinePosition.left`\u003C\u002Fli>\u003Cli>`ScrollableGraphViewReferenceLinePosition.right`\u003C\u002Fli>\u003Cli>`ScrollableGraphViewReferenceLinePosition.both`\u003C\u002Fli>\u003C\u002Ful>|\n| **shouldAddLabelsToIntermediateReferenceLines**: Bool               | Whether or not to add labels to the intermediate (between min and max) reference lines.|\n| **shouldAddUnitsToIntermediateReferenceLineLabels**: Bool           | Whether or not to add units specified by the `referenceLineUnits` variable to the labels on the intermediate reference lines.|\n\n### Reference Line Labels (y-axis)\n\n| Property                                              | Description                                                                             |\n|-------------------------------------------------------|-----------------------------------------------------------------------------------------|\n| **referenceLineLabelFont**: UIFont                    | The font to be used for the reference line labels.                                      |\n| **referenceLineLabelColor**: UIColor                  | The colour of the reference line labels.                                                |\n| **shouldShowReferenceLineUnits**: Bool                | Whether or not to show the units on the reference lines.                                |\n| **referenceLineUnits**: String?                       | The units that the y-axis is in. This string is used for labels on the reference lines. |\n| **referenceLineNumberOfDecimalPlaces**: Int           | The number of decimal places that should be shown on the reference line labels.         |\n| **referenceLineNumberStyle**: NSNumberFormatterStyle  | The number style that should be shown on the reference line labels.                     |\n\n### Data Point Labels (x-axis)\n\n| Property                                | Description                                                                         |\n|-----------------------------------------|-------------------------------------------------------------------------------------|\n| **shouldShowLabels**: Bool              | Whether or not to show the labels on the x-axis for each point.                     |\n| **dataPointLabelTopMargin**: CGFloat    | How far from the \"minimum\" reference line the data point labels should be rendered. |\n| **dataPointLabelBottomMargin**: CGFloat | How far from the bottom of the view the data point labels should be rendered.       |\n| **dataPointLabelFont**: UIFont?         | The font for the data point labels.                                                 |\n| **dataPointLabelColor**: UIColor        | The colour for the data point labels.                                               |\n| **dataPointLabelsSparsity**: Int        | Used to force the graph to show every n-th dataPoint label                          |\n\n\n\n## Customisation Examples\n\nAll of these examples can be seen in action in the example project: [graphview_example_code](graphview_example_code\u002F) \n\nOpen the project in Xcode and hit run.\n\n_Note: Examples here use a \"colorFromHex\" extension for UIColor._\n\n### Default\n![simple](readme_images\u002Fgallery-v4\u002Fsimple.png)\n```swift\nlet graphView = ScrollableGraphView(frame: frame, dataSource: self)\n\nlet linePlot = LinePlot(identifier: \"simple\") \u002F\u002F Identifier should be unique for each plot.\nlet referenceLines = ReferenceLines()\n\ngraphView.addPlot(plot: linePlot)\ngraphView.addReferenceLines(referenceLines: referenceLines)\n```\n\n### Bar Dark (Bar layer thanks to [@RedBlueThing](https:\u002F\u002Ftwitter.com\u002FRedBlueThing))\n![bar-dark](readme_images\u002Fgallery-v4\u002Fbar-dark.png)\n```swift\nlet graphView = ScrollableGraphView(frame: frame, dataSource: self)\n\n\u002F\u002F Setup the plot\nlet barPlot = BarPlot(identifier: \"bar\")\n\nbarPlot.barWidth = 25\nbarPlot.barLineWidth = 1\nbarPlot.barLineColor = UIColor.colorFromHex(hexString: \"#777777\")\nbarPlot.barColor = UIColor.colorFromHex(hexString: \"#555555\")\n\nbarPlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic\nbarPlot.animationDuration = 1.5\n\n\u002F\u002F Setup the reference lines\nlet referenceLines = ReferenceLines()\n\nreferenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 8)\nreferenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.2)\nreferenceLines.referenceLineLabelColor = UIColor.white\n\nreferenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(0.5)\n\n\u002F\u002F Setup the graph\ngraphView.backgroundFillColor = UIColor.colorFromHex(hexString: \"#333333\")\n\ngraphView.shouldAnimateOnStartup = true\n\ngraphView.rangeMax = 100\ngraphView.rangeMin = 0\n\n\u002F\u002F Add everything\ngraphView.addPlot(plot: barPlot)\ngraphView.addReferenceLines(referenceLines: referenceLines)\nreturn graphView\n```\n\n### Smooth Dark\n![line-dark-smooth](readme_images\u002Fgallery-v4\u002Fline-dark-smooth.png)\n```swift\nlet graphView = ScrollableGraphView(frame: frame, dataSource: self)\n\n\u002F\u002F Setup the line plot.\nlet linePlot = LinePlot(identifier: \"darkLine\")\n\nlinePlot.lineWidth = 1\nlinePlot.lineColor = UIColor.colorFromHex(hexString: \"#777777\")\nlinePlot.lineStyle = ScrollableGraphViewLineStyle.smooth\n\nlinePlot.shouldFill = true\nlinePlot.fillType = ScrollableGraphViewFillType.gradient\nlinePlot.fillGradientType = ScrollableGraphViewGradientType.linear\nlinePlot.fillGradientStartColor = UIColor.colorFromHex(hexString: \"#555555\")\nlinePlot.fillGradientEndColor = UIColor.colorFromHex(hexString: \"#444444\")\n\nlinePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic\n\nlet dotPlot = DotPlot(identifier: \"darkLineDot\") \u002F\u002F Add dots as well.\ndotPlot.dataPointSize = 2\ndotPlot.dataPointFillColor = UIColor.white\n\ndotPlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic\n\n\u002F\u002F Setup the reference lines.\nlet referenceLines = ReferenceLines()\n\nreferenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 8)\nreferenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.2)\nreferenceLines.referenceLineLabelColor = UIColor.white\n\nreferenceLines.positionType = .absolute\n\u002F\u002F Reference lines will be shown at these values on the y-axis.\nreferenceLines.absolutePositions = [10, 20, 25, 30]\nreferenceLines.includeMinMax = false\n\nreferenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(0.5)\n\n\u002F\u002F Setup the graph\ngraphView.backgroundFillColor = UIColor.colorFromHex(hexString: \"#333333\")\ngraphView.dataPointSpacing = 80\n\ngraphView.shouldAnimateOnStartup = true\ngraphView.shouldAdaptRange = true\ngraphView.shouldRangeAlwaysStartAtZero = true\n\ngraphView.rangeMax = 50\n\n\u002F\u002F Add everything to the graph.\ngraphView.addReferenceLines(referenceLines: referenceLines)\ngraphView.addPlot(plot: linePlot)\ngraphView.addPlot(plot: dotPlot)\n```\n\n\n\n### Dot\n![dot](readme_images\u002Fgallery-v4\u002Fdot.png)\n```swift\nlet graphView = ScrollableGraphView(frame: frame, dataSource: self)\n\n\u002F\u002F Setup the plot\nlet plot = DotPlot(identifier: \"dot\")\n\nplot.dataPointSize = 5\nplot.dataPointFillColor = UIColor.white\n\n\u002F\u002F Setup the reference lines\nlet referenceLines = ReferenceLines()\nreferenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 10)\nreferenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.5)\nreferenceLines.referenceLineLabelColor = UIColor.white\nreferenceLines.referenceLinePosition = ScrollableGraphViewReferenceLinePosition.both\n\nreferenceLines.shouldShowLabels = false\n\n\u002F\u002F Setup the graph\ngraphView.backgroundFillColor = UIColor.colorFromHex(hexString: \"#00BFFF\")\ngraphView.shouldAdaptRange = false\ngraphView.shouldAnimateOnAdapt = false\ngraphView.shouldAnimateOnStartup = false\n\ngraphView.dataPointSpacing = 25\ngraphView.rangeMax = 50\ngraphView.rangeMin = 0\n\n\u002F\u002F Add everything\ngraphView.addPlot(plot: plot)\ngraphView.addReferenceLines(referenceLines: referenceLines)\n```\n\n### Pink\n![line-pink-straight](readme_images\u002Fgallery-v4\u002Fline-pink-straight.png)\n```swift\nlet graphView = ScrollableGraphView(frame: frame, dataSource: self)\n\n\u002F\u002F Setup the plot\nlet linePlot = LinePlot(identifier: \"pinkLine\")\n\nlinePlot.lineColor = UIColor.clear\nlinePlot.shouldFill = true\nlinePlot.fillColor = UIColor.colorFromHex(hexString: \"#FF0080\")\n\n\u002F\u002F Setup the reference lines\nlet referenceLines = ReferenceLines()\n\nreferenceLines.referenceLineThickness = 1\nreferenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 10)\nreferenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.5)\nreferenceLines.referenceLineLabelColor = UIColor.white\nreferenceLines.referenceLinePosition = ScrollableGraphViewReferenceLinePosition.both\n\nreferenceLines.dataPointLabelFont = UIFont.boldSystemFont(ofSize: 10)\nreferenceLines.dataPointLabelColor = UIColor.white\nreferenceLines.dataPointLabelsSparsity = 3\n\n\u002F\u002F Setup the graph\ngraphView.backgroundFillColor = UIColor.colorFromHex(hexString: \"#222222\")\n\ngraphView.dataPointSpacing = 60\ngraphView.shouldAdaptRange = true\n\n\u002F\u002F Add everything\ngraphView.addPlot(plot: linePlot)\ngraphView.addReferenceLines(referenceLines: referenceLines)\n```\n\n### Multiple Plots v1\n![multi-v1](readme_images\u002Fgallery-v4\u002Fmulti1.png)\n```swift\n\u002F\u002F Setup the line plot.\nlet blueLinePlot = LinePlot(identifier: \"multiBlue\")\n\nblueLinePlot.lineWidth = 1\nblueLinePlot.lineColor = UIColor.colorFromHex(hexString: \"#16aafc\")\nblueLinePlot.lineStyle = ScrollableGraphViewLineStyle.smooth\n\nblueLinePlot.shouldFill = true\nblueLinePlot.fillType = ScrollableGraphViewFillType.solid\nblueLinePlot.fillColor = UIColor.colorFromHex(hexString: \"#16aafc\").withAlphaComponent(0.5)\n\nblueLinePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic\n\n\u002F\u002F Setup the second line plot.\nlet orangeLinePlot = LinePlot(identifier: \"multiOrange\")\n\norangeLinePlot.lineWidth = 1\norangeLinePlot.lineColor = UIColor.colorFromHex(hexString: \"#ff7d78\")\norangeLinePlot.lineStyle = ScrollableGraphViewLineStyle.smooth\n\norangeLinePlot.shouldFill = true\norangeLinePlot.fillType = ScrollableGraphViewFillType.solid\norangeLinePlot.fillColor = UIColor.colorFromHex(hexString: \"#ff7d78\").withAlphaComponent(0.5)\n\norangeLinePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic\n\n\u002F\u002F Setup the reference lines.\nlet referenceLines = ReferenceLines()\n\nreferenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 8)\nreferenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.2)\nreferenceLines.referenceLineLabelColor = UIColor.white\n\nreferenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(1)\n\n\u002F\u002F Setup the graph\ngraphView.backgroundFillColor = UIColor.colorFromHex(hexString: \"#333333\")\n\ngraphView.dataPointSpacing = 80\ngraphView.shouldAnimateOnStartup = true\ngraphView.shouldAdaptRange = true\n\ngraphView.shouldRangeAlwaysStartAtZero = true\n\n\u002F\u002F Add everything to the graph.\ngraphView.addReferenceLines(referenceLines: referenceLines)\ngraphView.addPlot(plot: blueLinePlot)\ngraphView.addPlot(plot: orangeLinePlot)\n```\n\n### Multiple Plots v2\n\nIt is possible to combine multiple plots to get different looks. We use the the dot plot to add markers to the line plot in this case:\n\n![multi-v2](readme_images\u002Fgallery-v4\u002Fmulti2.png)\n\n```swift\nlet graphView = ScrollableGraphView(frame: frame, dataSource: self)\n\n\u002F\u002F Setup the first plot.\nlet blueLinePlot = LinePlot(identifier: \"multiBlue\")\n\nblueLinePlot.lineColor = UIColor.colorFromHex(hexString: \"#16aafc\")\nblueLinePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic\n\n\u002F\u002F dots on the line\nlet blueDotPlot = DotPlot(identifier: \"multiBlueDot\")\nblueDotPlot.dataPointType = ScrollableGraphViewDataPointType.circle\nblueDotPlot.dataPointSize = 5\nblueDotPlot.dataPointFillColor = UIColor.colorFromHex(hexString: \"#16aafc\")\n\nblueDotPlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic\n\n\u002F\u002F Setup the second plot.\nlet orangeLinePlot = LinePlot(identifier: \"multiOrange\")\n\norangeLinePlot.lineColor = UIColor.colorFromHex(hexString: \"#ff7d78\")\norangeLinePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic\n\n\u002F\u002F squares on the line\nlet orangeSquarePlot = DotPlot(identifier: \"multiOrangeSquare\")\norangeSquarePlot.dataPointType = ScrollableGraphViewDataPointType.square\norangeSquarePlot.dataPointSize = 5\norangeSquarePlot.dataPointFillColor = UIColor.colorFromHex(hexString: \"#ff7d78\")\n\norangeSquarePlot.adaptAnimationType = ScrollableGraphViewAnimationType.elastic\n\n\u002F\u002F Setup the reference lines.\nlet referenceLines = ReferenceLines()\n\nreferenceLines.referenceLineLabelFont = UIFont.boldSystemFont(ofSize: 8)\nreferenceLines.referenceLineColor = UIColor.white.withAlphaComponent(0.2)\nreferenceLines.referenceLineLabelColor = UIColor.white\nreferenceLines.relativePositions = [0, 0.2, 0.4, 0.6, 0.8, 1]\n\nreferenceLines.dataPointLabelColor = UIColor.white.withAlphaComponent(1)\n\n\u002F\u002F Setup the graph\ngraphView.backgroundFillColor = UIColor.colorFromHex(hexString: \"#333333\")\n\ngraphView.dataPointSpacing = 80\n\ngraphView.shouldAnimateOnStartup = true\ngraphView.shouldAdaptRange = true\ngraphView.shouldRangeAlwaysStartAtZero = true\n\n\u002F\u002F Add everything to the graph.\ngraphView.addReferenceLines(referenceLines: referenceLines)\ngraphView.addPlot(plot: blueLinePlot)\ngraphView.addPlot(plot: blueDotPlot)\ngraphView.addPlot(plot: orangeLinePlot)\ngraphView.addPlot(plot: orangeSquarePlot)\n```\n\n## Known Issues\n\n- Some aspects of the graph cannot be customised _after_ it has been added to the view hierarchy.\n- Reloading the graph with a different number of data items is currently not supported.\n- Performance in the simulator is not great.\n\nIf you find any bugs please create an issue on Github.\n\n## Other\n\n[Follow me on twitter](https:\u002F\u002Ftwitter.com\u002Fphilackm) for interesting updates (read: gifs) about other things that I make.\n","ScrollableGraphView 是一个用于iOS平台的可滚动图表视图，旨在可视化简单的离散数据集，采用Swift编写。该项目支持多条曲线绘制、动态重载数值、自适应Y轴范围调整以及多种定制选项等功能，同时具备平滑滚动和初始化动画等特性。适用于需要展示时间序列数据或任何类型离散数据的应用场景中，如健康监测应用、金融分析工具等。通过CocoaPods、Carthage或手动添加方式即可轻松集成到项目里。",2,"2026-06-11 03:09:07","top_language"]