Charts: рднрд░рд╛ рд▓рд╛рдЗрди рдЪрд╛рд░реНрдЯ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 10 рдЕрдХреНрддреВре░ 2017  ┬╖  17рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: danielgindi/Charts

рдореИрдВ рдПрдХ рднрд░рд╛ рд╣реБрдЖ рд░реЗрдЦрд╛ рдЪрд╛рд░реНрдЯ рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдЖрдк рд▓реЛрдЧ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рдЪрд┐рддреНрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред
screen shot 2017-10-09 at 23 02 38
рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рдЙрджрд╛рд╣рд░рдг рджреЗрдЦрд╛ рдФрд░ рд╡реЗ рд╡рд╛рдИ-рдЕрдХреНрд╖ рд╕реНрдерд┐рддрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП IFillFormatter рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдЬрд╣рд╛рдВ рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреА рднрд░реА рд╣реБрдИ рд░реЗрдЦрд╛ рд╕рдорд╛рдкреНрдд рд╣реЛрддреА рд╣реИред рд▓реЗрдХрд┐рди, рдпрд╣ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реНрдерд┐рддрд┐ рдереА, рдЧрддрд┐рд╢реАрд▓ рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВред рдореИрдВ рдпрд╣ рд╕реНрдерд┐рддрд┐ рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдкрд░ рдХреИрд╕реЗ рдирд┐рд░реНрднрд░ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ == 0 рд╣реИ рддреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рднрд░реА рд╣реБрдИ рд╕реНрдерд┐рддрд┐ A рдХрд╛ рдЕрдВрдд рд╣реИ, рдпрджрд┐ рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ == 1 рд╣реИ рддреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рднрд░реА рд╣реБрдИ рд╕реНрдерд┐рддрд┐ рдХрд╛ рдПрдХ рдЕрд▓рдЧ рдЕрдВрдд рдореВрд▓реНрдп рд╣реИред
рдпрд╛, рдКрдкрд░ рджрд┐рдП рдЧрдП рдЪрд┐рддреНрд░ рдХреА рддрд░рд╣ рдЪрд╛рд░реНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдЕрдиреНрдп рд╕реБрдЭрд╛рд╡ред

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдореИрдВрдиреЗ LineChartRenderer рдХреЛ рдЙрдк-рд╡рд░реНрдЧреАрдХреГрдд рдХрд░рдХреЗ @ liuxuan30 рдХреЗ рд╕реБрдЭрд╛рд╡реЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдХреЗ рдФрд░ IFillFormatter рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ рдЪрд░ рдЬреЛрдбрд╝рдХрд░ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдмреА рд╣рд╛рд╕рд┐рд▓ рдХреА, рдЬреЛ рдореБрдЭреЗ рдлрд┐рд▓ рд▓рд╛рдЗрди рдХреЗ рд▓рд┐рдП рд╕рдВрдХреЗрддрдХ рдХреЗ рд░реВрдк рдореЗрдВ рджреВрд╕рд░рд╛ рдбреЗрдЯрд╛ рд╕реЗрдЯ рдкрд╛рд╕ рдХрд░рдиреЗ рджреЗрддрд╛ рд╣реИ рдФрд░ рддрджрдиреБрд╕рд╛рд░ рдкрде рдмрдирд╛рдПрдВ (рдХреЗрд╡рд▓ рд░реИрдЦрд┐рдХ рдХреЗ рд▓рд┐рдП, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдмреЗрдЬрд┐рдпрд░ рдХреЗ рд▓рд┐рдП рднреА рдРрд╕рд╛ рд╣реА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)ред

class AreaFillFormatter: IFillFormatter {

    var fillLineDataSet: LineChartDataSet?

    init(fillLineDataSet: LineChartDataSet) {
        self.fillLineDataSet = fillLineDataSet
    }

    public func getFillLinePosition(dataSet: ILineChartDataSet, dataProvider: LineChartDataProvider) -> CGFloat {
        return 0.0
    }

    public func getFillLineDataSet() -> LineChartDataSet {
        return fillLineDataSet ?? LineChartDataSet()
    }

}
class CustomLineChartRenderer: LineChartRenderer {

    override open func drawLinearFill(context: CGContext, dataSet: ILineChartDataSet, trans: Transformer, bounds: XBounds) {
        guard let dataProvider = dataProvider else { return }

        let areaFillFormatter = dataSet.fillFormatter as? AreaFillFormatter

        let filled = generateFilledPath(
            dataSet: dataSet,
            fillMin: dataSet.fillFormatter?.getFillLinePosition(dataSet: dataSet, dataProvider: dataProvider) ?? 0.0,
            fillLineDataSet: areaFillFormatter?.getFillLineDataSet(),
            bounds: bounds,
            matrix: trans.valueToPixelMatrix)

        if dataSet.fill != nil
        {
            drawFilledPath(context: context, path: filled, fill: dataSet.fill!, fillAlpha: dataSet.fillAlpha)
        }
        else
        {
            drawFilledPath(context: context, path: filled, fillColor: dataSet.fillColor, fillAlpha: dataSet.fillAlpha)
        }
    }

    fileprivate func generateFilledPath(dataSet: ILineChartDataSet, fillMin: CGFloat, fillLineDataSet: ILineChartDataSet?, bounds: XBounds, matrix: CGAffineTransform) -> CGPath
    {
        let phaseY = animator?.phaseY ?? 1.0
        let isDrawSteppedEnabled = dataSet.mode == .stepped
        let matrix = matrix

        var e: ChartDataEntry!
        var fillLineE: ChartDataEntry?

        let filled = CGMutablePath()

        e = dataSet.entryForIndex(bounds.min)
        fillLineE = fillLineDataSet?.entryForIndex(bounds.min)

        if e != nil
        {
            if let fillLineE = fillLineE
            {
                filled.move(to: CGPoint(x: CGFloat(e.x), y: CGFloat(fillLineE.y * phaseY)), transform: matrix)
            }
            else
            {
                filled.move(to: CGPoint(x: CGFloat(e.x), y: fillMin), transform: matrix)
            }

            filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(e.y * phaseY)), transform: matrix)
        }

        // Create the path for the data set entries
        for x in stride(from: (bounds.min + 1), through: bounds.range + bounds.min, by: 1)
        {
            guard let e = dataSet.entryForIndex(x) else { continue }

            if isDrawSteppedEnabled
            {
                guard let ePrev = dataSet.entryForIndex(x-1) else { continue }
                filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(ePrev.y * phaseY)), transform: matrix)
            }

            filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(e.y * phaseY)), transform: matrix)
        }

        // Draw a path to the start of the fill line
        e = dataSet.entryForIndex(bounds.range + bounds.min)
        fillLineE = fillLineDataSet?.entryForIndex(bounds.range + bounds.min)
        if e != nil
        {
            if let fillLineE = fillLineE
            {
                filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(fillLineE.y * phaseY)), transform: matrix)
            }
            else
            {
                filled.addLine(to: CGPoint(x: CGFloat(e.x), y: fillMin), transform: matrix)
            }
        }

        // Draw the path for the fill line (backwards)
        if let fillLineDataSet = fillLineDataSet {
            for x in stride(from: (bounds.min + 1), through: bounds.range + bounds.min, by: 1).reversed()
            {
                guard let e = fillLineDataSet.entryForIndex(x) else { continue }

                if isDrawSteppedEnabled
                {
                    guard let ePrev = fillLineDataSet.entryForIndex(x-1) else { continue }
                    filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(ePrev.y * phaseY)), transform: matrix)
                }

                filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(e.y * phaseY)), transform: matrix)
            }
        }

        filled.closeSubpath()

        return filled
    }
}

рд╕рднреА 17 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

drawLinearFill рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ рдЬрд╣рд╛рдВ рдпрд╣ рднрд░рдг рд░реЗрдХреНрдЯ рдЦреАрдВрдЪрддрд╛ рд╣реИред рдпрд╣ generateFilledPath рдФрд░ getFillLinePosition рднреАрддрд░ рднрд░рдг рд░реЗрдХреНрдЯ рдХреА рдЧрдгрдирд╛ рдХрд░рддрд╛ рд╣реИред рдЖрджрд░реНрд╢ рд░реВрдк рд╕реЗ рдЖрдкрдХреЛ рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рдмреАрдЪ рдЕрдкрдирд╛ рд░реЗрдХреНрдЯ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрди рддрд░реАрдХреЛрдВ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЖрдк рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫреЗ рд╣реИрдВ

рдореИрдВрдиреЗ LineChartRenderer рдХреЛ рдЙрдк-рд╡рд░реНрдЧреАрдХреГрдд рдХрд░рдХреЗ @ liuxuan30 рдХреЗ рд╕реБрдЭрд╛рд╡реЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдХреЗ рдФрд░ IFillFormatter рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╡рд░реНрдЧ рдореЗрдВ рдПрдХ рдЪрд░ рдЬреЛрдбрд╝рдХрд░ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдмреА рд╣рд╛рд╕рд┐рд▓ рдХреА, рдЬреЛ рдореБрдЭреЗ рдлрд┐рд▓ рд▓рд╛рдЗрди рдХреЗ рд▓рд┐рдП рд╕рдВрдХреЗрддрдХ рдХреЗ рд░реВрдк рдореЗрдВ рджреВрд╕рд░рд╛ рдбреЗрдЯрд╛ рд╕реЗрдЯ рдкрд╛рд╕ рдХрд░рдиреЗ рджреЗрддрд╛ рд╣реИ рдФрд░ рддрджрдиреБрд╕рд╛рд░ рдкрде рдмрдирд╛рдПрдВ (рдХреЗрд╡рд▓ рд░реИрдЦрд┐рдХ рдХреЗ рд▓рд┐рдП, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЖрдк рдмреЗрдЬрд┐рдпрд░ рдХреЗ рд▓рд┐рдП рднреА рдРрд╕рд╛ рд╣реА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)ред

class AreaFillFormatter: IFillFormatter {

    var fillLineDataSet: LineChartDataSet?

    init(fillLineDataSet: LineChartDataSet) {
        self.fillLineDataSet = fillLineDataSet
    }

    public func getFillLinePosition(dataSet: ILineChartDataSet, dataProvider: LineChartDataProvider) -> CGFloat {
        return 0.0
    }

    public func getFillLineDataSet() -> LineChartDataSet {
        return fillLineDataSet ?? LineChartDataSet()
    }

}
class CustomLineChartRenderer: LineChartRenderer {

    override open func drawLinearFill(context: CGContext, dataSet: ILineChartDataSet, trans: Transformer, bounds: XBounds) {
        guard let dataProvider = dataProvider else { return }

        let areaFillFormatter = dataSet.fillFormatter as? AreaFillFormatter

        let filled = generateFilledPath(
            dataSet: dataSet,
            fillMin: dataSet.fillFormatter?.getFillLinePosition(dataSet: dataSet, dataProvider: dataProvider) ?? 0.0,
            fillLineDataSet: areaFillFormatter?.getFillLineDataSet(),
            bounds: bounds,
            matrix: trans.valueToPixelMatrix)

        if dataSet.fill != nil
        {
            drawFilledPath(context: context, path: filled, fill: dataSet.fill!, fillAlpha: dataSet.fillAlpha)
        }
        else
        {
            drawFilledPath(context: context, path: filled, fillColor: dataSet.fillColor, fillAlpha: dataSet.fillAlpha)
        }
    }

    fileprivate func generateFilledPath(dataSet: ILineChartDataSet, fillMin: CGFloat, fillLineDataSet: ILineChartDataSet?, bounds: XBounds, matrix: CGAffineTransform) -> CGPath
    {
        let phaseY = animator?.phaseY ?? 1.0
        let isDrawSteppedEnabled = dataSet.mode == .stepped
        let matrix = matrix

        var e: ChartDataEntry!
        var fillLineE: ChartDataEntry?

        let filled = CGMutablePath()

        e = dataSet.entryForIndex(bounds.min)
        fillLineE = fillLineDataSet?.entryForIndex(bounds.min)

        if e != nil
        {
            if let fillLineE = fillLineE
            {
                filled.move(to: CGPoint(x: CGFloat(e.x), y: CGFloat(fillLineE.y * phaseY)), transform: matrix)
            }
            else
            {
                filled.move(to: CGPoint(x: CGFloat(e.x), y: fillMin), transform: matrix)
            }

            filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(e.y * phaseY)), transform: matrix)
        }

        // Create the path for the data set entries
        for x in stride(from: (bounds.min + 1), through: bounds.range + bounds.min, by: 1)
        {
            guard let e = dataSet.entryForIndex(x) else { continue }

            if isDrawSteppedEnabled
            {
                guard let ePrev = dataSet.entryForIndex(x-1) else { continue }
                filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(ePrev.y * phaseY)), transform: matrix)
            }

            filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(e.y * phaseY)), transform: matrix)
        }

        // Draw a path to the start of the fill line
        e = dataSet.entryForIndex(bounds.range + bounds.min)
        fillLineE = fillLineDataSet?.entryForIndex(bounds.range + bounds.min)
        if e != nil
        {
            if let fillLineE = fillLineE
            {
                filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(fillLineE.y * phaseY)), transform: matrix)
            }
            else
            {
                filled.addLine(to: CGPoint(x: CGFloat(e.x), y: fillMin), transform: matrix)
            }
        }

        // Draw the path for the fill line (backwards)
        if let fillLineDataSet = fillLineDataSet {
            for x in stride(from: (bounds.min + 1), through: bounds.range + bounds.min, by: 1).reversed()
            {
                guard let e = fillLineDataSet.entryForIndex(x) else { continue }

                if isDrawSteppedEnabled
                {
                    guard let ePrev = fillLineDataSet.entryForIndex(x-1) else { continue }
                    filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(ePrev.y * phaseY)), transform: matrix)
                }

                filled.addLine(to: CGPoint(x: CGFloat(e.x), y: CGFloat(e.y * phaseY)), transform: matrix)
            }
        }

        filled.closeSubpath()

        return filled
    }
}

рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдорд╣рд╛рд░рдд рд╣рд╛рд╕рд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрджрд░реНрд╢ рдЙрджрд╛рд╣рд░рдг :)

рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдХреЛ рдХреИрд╕реЗ рд╣рд▓/рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ?

@ рд░реЛрдм-рдХреЗ рдХреНрдпрд╛ рдЖрдк рдЗрд╕рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд╛рди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ

рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдореИрдВ рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХрд░рддрд╛ рд╣реВрдВ:

let maxDataSet = LineChartDataSet()
let minDataSet = LineChartDataSet()

// ... fill the data sets

// Set the data
self.lineChart.data = LineChartData(dataSets: [maxDataSet, minDataSet])

// Set the custom line chart renderer
self.lineChart.renderer = CustomLineChartRenderer(dataProvider: self.lineChart, animator: self.lineChart.chartAnimator, viewPortHandler: self.lineChart.viewPortHandler)

maxDataSet.drawFilledEnabled = true
maxDataSet.fillFormatter = AreaFillFormatter(fillLineDataSet: minDataSet)

рдореИрдВрдиреЗ рдЗрд╕реЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдФрд░ рдЙрджрд╛рд╣рд░рдг рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рдг рдХрд╛ рдкрд╛рд▓рди рдХрд┐рдпрд╛, рдлрд┐рд░ рднреА рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИ @ рд░реЛрдм-рдХреЗ

@ рд░реЛрдм-рдХреЗ рдореИрдВрдиреЗ CustomLineChartRenderer рд╕реЗ рдХрд┐рд╕реА рднреА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдмреНрд░реЗрдХ рдкреЙрдЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреАрдмрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ

рдореИрдВрдиреЗ LineChartRenderer рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдЯрд┐рдкреНрдкрдгреА рдЕрдкрдбреЗрдЯ рдХреАред

рдЕрднреА рднреА рдХреЛрдИ рднрд╛рдЧреНрдп рдирд╣реАрдВ рд╣реИ рдпрд╛рд░ @ рд░реЛрдм-рдХреЗ

рдпрджрд┐ рдЖрдк ucbDataSet рдФрд░ lcbDataSet рдмреАрдЪ рдХрд╛ рд░рдВрдЧ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдЖрдкрдХреЛ рджреВрд╕рд░реЗ рдбреЗрдЯрд╛ рд╕реЗрдЯ рдХреЛ рдкрд╣рд▓реЗ рд╡рд╛рд▓реЗ рдХреЗ рдлрд╝реЙрд░реНрдореЗрдЯрд░ рдореЗрдВ рдкрд╛рд╕ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЖрдк рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЛ рд╕реНрд╡рдпрдВ рдХреЗ рдлрд╝реЙрд░реНрдореЗрдЯрд░ рдореЗрдВ рдкрд╛рд╕ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдирд┐рдореНрди рдХрд╛рд░реНрдп рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ:

ucbDataSet.fillFormatter = AreaFillFormatter(fillLineDataSet: lcbDataSet)

(рдпрд╛ рдлрд┐рд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд)

рдореИрдВ рдЬреЛ рд╕рдордЭрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рд╡рд╣ рдкрд╣рд▓реЗ рд╣реА рдХреЛрд╢рд┐рд╢ рдХрд░ рдЪреБрдХрд╛ рд╣реИ
рдореИрдВрдиреЗ CustomLineChartRenderer рдХреНрд▓рд╛рд╕ рд╕реЗ рдХрд┐рд╕реА рднреА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдмреНрд░реЗрдХ рдкреЙрдЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреАрдмрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдирд╣реАрдВ рдХрд┐рдпрд╛, рдЬрд┐рд╕реЗ рдХреЙрд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ

рдореИрдВ рджреЗрдЦ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рдХреЛрдб рдореЗрдВ рдмреЗрдЬрд┐рдпрд░ рдореЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣реЗ рд╣реИрдВ:

lineChartDataSet.mode = .horizontalBezier
ucbDataSet.mode = .horizontalBezier
lcbDataSet.mode = .horizontalBezier

рдореИрдВрдиреЗ рдЬреЛ рдХреЛрдб рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рд╣реИ рд╡рд╣ рдХреЗрд╡рд▓ рд░реИрдЦрд┐рдХ рдореЛрдб рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдЖрдкрдХреЛ рдореЛрдб рдХреЛ .linear рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛ рдпрд╛ drawHorizontalBezier рдУрд╡рд░рд░рд╛рдЗрдб рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рддрджрдиреБрд╕рд╛рд░ рдХреЛрдб рдХреЛ рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред

@ рд░реЛрдм-рдХреЗ рдиреЗ рдЗрд╕реЗ рдЕрднреА-рдЕрднреА рдХрд╛рдо рдХрд┐рдпрд╛ рд╣реИ рдзрдиреНрдпрд╡рд╛рдж рдЗрд╕реЗ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдмрд╣реБрдд рдЖрджрдореА

рдХреНрдпрд╛ рд╕рдВрдпреБрдХреНрдд рдЪрд╛рд░реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛?

рдХреНрдпрд╛ рд╕рдВрдпреБрдХреНрдд рдЪрд╛рд░реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛?

рдХреНрдпрд╛ рдЖрдкрдХреЛ рд╕рдорд╛рдзрд╛рди рдорд┐рд▓рд╛? рд╕рдВрдпреБрдХреНрдд рдЪрд╛рд░реНрдЯ рд╕рдВрдпреБрдХреНрдд рдЪрд╛рд░реНрдЯрд░реЗрдВрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рди рдХрд┐ LinearChartRender рдХрд╛, рдЗрд╕рд▓рд┐рдП рдХреЙрд▓ рдмреИрдХ рдХреЛ drawLinearFill рдирд╣реАрдВ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрд╣ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реЗрдВрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ

рд╡рд┐рдзрд┐ drawLinearFill рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ, рдЬрдм рдЖрдк рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдЦреЛрдЬ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдЗрд╕рдореЗрдВ рдХрдИ рдирдП рд░реЗрдВрдбрд░ рд▓рдЧрддреЗ рд╣реИрдВ

рдХреНрдпрд╛ рд╕рдВрдпреБрдХреНрдд рдЪрд╛рд░реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛?

рд╕рдорд╛рдзрд╛рди рд╕рдВрдпреБрдХреНрдд рдЪрд╛рд░реНрдЯ: https://github.com/PhilJay/MPAndroidChart/issues/338

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

valeIT picture valeIT  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

JW00332 picture JW00332  ┬╖  4рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

PrashantKT picture PrashantKT  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Shunshine07 picture Shunshine07  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

ahmedsafadii picture ahmedsafadii  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ