" IOS-图表"不要绘制空值或零值。 &安培;在组合图表

时间:2016-08-29 06:52:03

标签: swift ios-charts

我的问题有两个,但逻辑可能相似。

我有一个简单的烛台图表,有两个不同的指标。一个位于底部,另一个位于烛台数据之上。 (见截图)

第一: 在下图中,我不想在计算之前绘制值。在这种情况下,简单移动平均线有14个周期。 (请参见黄色框的屏幕截图。不想绘制这些值)

第二: 在叠加层上我想要"打开",最低值,最高值和"关闭"最后一个酒吧。我想在这四点之间划一条线,忽略其间的所有数据。 (它应该看起来像截图中的黄线。)

如何重新设置设定图表功能以忽略下线图上14个周期之前的值?

如何忽略其他点并在组合视图的折线图上的四个值之间进行插值?

目前我必须设置我想要的值"忽略"零(1950年的截图,使其可读,而不是压扁),以摆脱界限错误。

试图尽可能地简化代码,使其更具可读性:

//
//  ViewController.swift
//

import Foundation
import Cocoa
import Charts

var yValuesIndicatorLower: [Double] = []
var yValuesIndicatorOverlay: [Double] = []

class ViewController: NSViewController {

    //Chart view outlets

    @IBOutlet weak var combinedChartView: CombinedChartView!

    @IBOutlet weak var lineChartView: LineChartView!

    // Zoom Buttons

    @IBAction func zoomAll(sender: AnyObject) {
        combinedChartView.fitScreen()
        lineChartView.fitScreen()
    }

    @IBAction func zoomIn(sender: AnyObject) {
        combinedChartView.zoomIn()
        lineChartView.zoomIn()
    }

    @IBAction func zoomOut(sender: AnyObject) {
        combinedChartView.zoomOut()
        lineChartView.zoomOut()
    }


    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        view.wantsLayer = true
        view.layer?.backgroundColor = NSColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 0.95).CGColor

        combinedChartView.noDataText = "Loading data..."
        lineChartView.noDataText = "Loading data..."

        // Do any additional setup after loading the view.
        let xValues = ["05-16", "05-17", "05-18", "05-19", "05-20", "05-23", "05-24", "05-25", "05-26", "05-27", "05-31", "06-01", "06-02", "06-03", "06-06", "06-07", "06-08", "06-09", "06-10", "06-13", "06-14", "06-15", "06-16", "06-17", "06-20", "06-21", "06-22", "06-23", "06-24", "06-27", "06-28", "06-29", "06-30", "07-01", "07-05", "07-06", "07-07", "07-08", "07-11", "07-12", "07-13", "07-14", "07-15", "07-18", "07-19", "07-20", "07-21", "07-22", "07-25", "07-26", "07-27", "07-28", "07-29", "08-01", "08-02", "08-03"]

        ////Prices are ["Open"=[0], "High"=[1], "Low"=[2], "Last"[3]]
        let yValues: [[Double]] = [[2032.75, 2060.0, 2027.0, 2053.5], [2052.5, 2061.0, 2028.75, 2036.5], [2035.75, 2049.5, 2022.75, 2034.75], [2035.75, 2036.25, 2014.0, 2030.5], [2030.5, 2047.5, 2029.5, 2042.0], [2043.75, 2047.5, 2035.25, 2036.75], [2037.5, 2069.0, 2032.75, 2067.0], [2066.5, 2084.25, 2065.75, 2080.75], [2080.5, 2083.75, 2074.5, 2083.0], [2082.0, 2090.25, 2080.0, 2090.25], [2091.25, 2095.25, 2078.0, 2086.25], [2085.0, 2090.75, 2075.0, 2088.75], [2088.75, 2096.0, 2078.25, 2095.25], [2094.5, 2097.25, 2074.0, 2088.25], [2088.5, 2103.25, 2085.25, 2099.75], [2099.25, 2108.75, 2098.0, 2101.75], [2101.25, 2110.75, 2098.0, 2108.5], [2108.5, 2109.5, 2097.25, 2104.75], [2104.5, 2104.75, 2079.5, 2087.0], [2081.0, 2089.25, 2066.5, 2067.25], [2067.25, 2072.75, 2054.75, 2064.75], [2064.5, 2079.5, 2059.75, 2062.5], [2062.5, 2071.5, 2040.75, 2069.5], [2068.75, 2074.75, 2053.25, 2059.75], [2071.0, 2092.5, 2070.25, 2082.75], [2079.0, 2086.0, 2074.0, 2079.25], [2079.25, 2091.25, 2075.25, 2077.0], [2083.0, 2113.25, 2083.0, 2113.25], [2115.75, 2119.5, 1999.0, 2018.25], [2013.75, 2022.5, 1981.5, 1982.0], [1982.5, 2029.75, 1982.25, 2028.25], [2028.25, 2074.75, 2022.75, 2074.25], [2072.25, 2091.25, 2056.5, 2086.5], [2086.5, 2100.75, 2081.5, 2096.25], [2099.75, 2104.75, 2072.5, 2084.5], [2084.0, 2094.5, 2065.75, 2093.0], [2092.0, 2102.0, 2081.75, 2092.25], [2092.0, 2125.5, 2087.5, 2120.75], [2120.25, 2136.75, 2120.0, 2130.5], [2130.75, 2149.25, 2128.5, 2146.0], [2145.75, 2152.25, 2139.5, 2145.75], [2145.25, 2168.0, 2142.75, 2157.75], [2156.5, 2164.75, 2143.25, 2146.0], [2154.5, 2163.25, 2152.75, 2160.25], [2160.0, 2160.75, 2151.25, 2159.0], [2159.0, 2169.75, 2155.25, 2168.75], [2168.25, 2170.25, 2153.5, 2159.25], [2159.0, 2169.25, 2156.0, 2167.25], [2167.75, 2172.5, 2155.75, 2163.25], [2162.75, 2168.0, 2153.75, 2166.0], [2166.0, 2169.25, 2152.0, 2163.25], [2162.75, 2168.5, 2153.5, 2166.0], [2165.5, 2171.75, 2157.5, 2171.0], [2174.0, 2177.75, 2159.75, 2165.5], [2166.0, 2171.0, 2141.5, 2153.0], [2152.25, 2158.25, 2145.25, 2156.75]]

        //Pass values to indicators and get returned indicator values
        yValuesIndicatorOverlay = indicatorOverlay(yValues)
        yValuesIndicatorLower = indicatorLower(yValues)

        //Pass values to chart setting function
        setChart(xValues, valuesCandleChart: yValues, indicatorLowerValues: yValuesIndicatorLower, indicatorOverlayValues: yValuesIndicatorOverlay)
    }


    func indicatorOverlay(yValues: [[Double]]) -> [Double]{

        var highest = Double()
        var ZigZag: [Double] = []

        for i in 0..<yValues.count {
            highest = max(highest, yValues[i][1])
        }

        var lowest = highest
        for i in 0..<yValues.count {
            lowest = min(lowest, yValues[i][2])
        }

        for i in 0..<yValues.count {
            if i == 0 {
                ZigZag.append(yValues[i][0])
            }
            else if yValues[i][1] == highest {
                ZigZag.append(highest)
            }
            else if yValues[i][2] == lowest {
                ZigZag.append(lowest)
            }
            else if i == yValues.count-1 {
                ZigZag.append(yValues[i][3])
            }
            else {
                ZigZag.append(0)//These values should be ignored and then interpolated between other values.
            }
        }
        print(highest)
        print(lowest)

        return ZigZag

    }

    func indicatorLower(yValues: [[Double]]) -> [Double]{

        let peroid = 14.0

        var sum = 0.0
        var SMA: [Double] = []

        //Simple Moving Average
        for i in 0..<Int(peroid) {
            sum  += yValues[i][3]
            if i < Int(peroid)-1 {
                SMA.append(0)//These values are to be ignored
            }
        }
        SMA.append(sum/peroid)
        for i in Int(peroid)..<yValues.count {
            sum = (sum - yValues[i - Int(peroid)][3]) + yValues[i][3]
            SMA.append(sum/peroid)
        }

        return SMA

    }

    //Function to set chart values

    func setChart(xValues: [String], valuesCandleChart: [[Double]], indicatorLowerValues: [Double], indicatorOverlayValues: [Double]) {


        var yValsCandleChart : [CandleChartDataEntry] = []

        for i in 0..<valuesCandleChart.count {
            let high = valuesCandleChart[i][1]
            let low = valuesCandleChart[i][2]
            let open = valuesCandleChart[i][0]
            let close = valuesCandleChart[i][3]

            yValsCandleChart.append(CandleChartDataEntry(xIndex: i, shadowH: high, shadowL: low, open: open, close: close))
        }

        //How to ignore values that are "0" or below a set index?
        var indicatorLower_yValues: [ChartDataEntry] = []

        for i in 0..<xValues.count {
            let indicatorLower_yValue = ChartDataEntry(value: indicatorLowerValues[i], xIndex: i)
            indicatorLower_yValues.append(indicatorLower_yValue)
        }

        //How to use only vlaues that are calculated and not "0" to draw a ZigZag across the candlestick chart?
        var indicatorOverlay_yValues: [ChartDataEntry] = []

        for i in 0..<xValues.count {
            let indicatorOverlay_yValue = ChartDataEntry(value: indicatorOverlayValues[i], xIndex: i)
            indicatorOverlay_yValues.append(indicatorOverlay_yValue)
        }

        let candleChartDataSet = CandleChartDataSet(yVals: yValsCandleChart, label: "Price")
        let lineOverlayChartDataSet = LineChartDataSet(yVals: indicatorOverlay_yValues, label: "indicatorOverlay")

        let data: CombinedChartData = CombinedChartData(xVals: xValues)

        data.candleData = CandleChartData(xVals: xValues, dataSets: [candleChartDataSet])
        data.lineData = LineChartData(xVals: xValues, dataSets: [lineOverlayChartDataSet])
        combinedChartView.drawOrder = [3, 2]

        combinedChartView.data = data

        candleChartDataSet.decreasingColor = NSColor.redColor()
        candleChartDataSet.increasingColor = NSColor.greenColor()
        candleChartDataSet.neutralColor = NSColor.blueColor()
        candleChartDataSet.shadowColorSameAsCandle = true
        candleChartDataSet.shadowWidth = 1
        candleChartDataSet.decreasingFilled = true
        candleChartDataSet.increasingFilled = false
        candleChartDataSet.drawValuesEnabled = false
        combinedChartView.doubleTapToZoomEnabled = false
        lineOverlayChartDataSet.drawCirclesEnabled = false
        lineOverlayChartDataSet.drawValuesEnabled = false

        let lineChartDataSet = LineChartDataSet(yVals: indicatorLower_yValues, label: "indicatorLower")
        let lineChartData = LineChartData(xVals: xValues, dataSet: lineChartDataSet)
        lineChartView.data = lineChartData


        lineChartView.doubleTapToZoomEnabled = false
        lineChartDataSet.drawCirclesEnabled = false
        lineChartDataSet.drawValuesEnabled = false


    }

    override var representedObject: AnyObject? {
        didSet {
            // Update the view, if already loaded.
        }
    }


}

Chart indicators markup

2 个答案:

答案 0 :(得分:1)

要100%精确并复制底部图表(即解决方案),必须添加以下行。如果不是MA将从左上角开始,两个图表之间的x轴将不再对齐。

lineChartView.xAxis.axisMinimum = 0.0 

答案 1 :(得分:0)

哇,真的很容易...... =]

显示我喜欢这个库的程度。

此处有关于此问题的建议:LineChartView avoid painting 0 values #830

我所要做的就是改变这些:

    //How to ignore values that are "0" or below a set index?
    var indicatorLower_yValues: [ChartDataEntry] = []

    for i in 0..<xValues.count {
        let indicatorLower_yValue = ChartDataEntry(value: indicatorLowerValues[i], xIndex: i)
        indicatorLower_yValues.append(indicatorLower_yValue)
    }

    //How to use only vlaues that are calculated and not "0" to draw a ZigZag across the candlestick chart?
    var indicatorOverlay_yValues: [ChartDataEntry] = []

    for i in 0..<xValues.count {
        let indicatorOverlay_yValue = ChartDataEntry(value: indicatorOverlayValues[i], xIndex: i)
        indicatorOverlay_yValues.append(indicatorOverlay_yValue)
    }

对于这些:

        //Ignore values that are "0"
        var indicatorLower_yValues: [ChartDataEntry] = []

        for i in 0..<xValues.count {
            if indicatorLowerValues[i] != 0 {//ADD: If clause to skip "0"
                let indicatorLower_yValue = ChartDataEntry(value: indicatorLowerValues[i], xIndex: i)
                indicatorLower_yValues.append(indicatorLower_yValue)
            }
        }

        //Use only vlaues that are not "0" to draw a ZigZag
        var indicatorOverlay_yValues: [ChartDataEntry] = []

        for i in 0..<xValues.count {
            if indicatorOverlayValues[i] != 0 {//ADD: If clause to skip "0"
                let indicatorOverlay_yValue = ChartDataEntry(value: indicatorOverlayValues[i], xIndex: i)
                indicatorOverlay_yValues.append(indicatorOverlay_yValue)
            }
        }

enter image description here