From 23bc57a85ab815ab290b7159bd4a5ababc7db826 Mon Sep 17 00:00:00 2001 From: thierryH91200 Date: Thu, 25 May 2017 17:55:47 +0200 Subject: [PATCH 1/8] add multi axis --- .../Charts/Charts/BarLineChartViewBase.swift | 489 +++++++++++++----- .../Charts/HorizontalBarChartView.swift | 142 ++++- Source/Charts/Components/AxisBase.swift | 42 +- Source/Charts/Components/YAxis.swift | 22 +- .../Charts/Highlight/ChartHighlighter.swift | 20 +- Source/Charts/Renderers/XAxisRenderer.swift | 104 ++-- .../XAxisRendererHorizontalBarChart.swift | 123 +++-- Source/Charts/Renderers/YAxisRenderer.swift | 219 +++++--- .../YAxisRendererHorizontalBarChart.swift | 187 +++++-- 9 files changed, 1005 insertions(+), 343 deletions(-) diff --git a/Source/Charts/Charts/BarLineChartViewBase.swift b/Source/Charts/Charts/BarLineChartViewBase.swift index 747120718f..cf04e10321 100644 --- a/Source/Charts/Charts/BarLineChartViewBase.swift +++ b/Source/Charts/Charts/BarLineChartViewBase.swift @@ -29,6 +29,8 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD fileprivate var _pinchZoomEnabled = false fileprivate var _doubleTapToZoomEnabled = true fileprivate var _dragEnabled = true + fileprivate var _dragYEnabled = true + fileprivate var _dragXEnabled = true fileprivate var _scaleXEnabled = true fileprivate var _scaleYEnabled = true @@ -48,7 +50,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD /// When enabled, the values will be clipped to contentRect, otherwise they can bleed outside the content rect. open var clipValuesToContentEnabled: Bool = false - + /// Sets the minimum offset (padding) around the chart, defaults to 10 open var minOffset = CGFloat(10.0) @@ -57,16 +59,22 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD open var keepPositionOnRotation: Bool = false /// the object representing the left y-axis - internal var _leftAxis: YAxis! + internal var _leftAxis : YAxis! + internal var _leftAxis1: YAxis! /// the object representing the right y-axis internal var _rightAxis: YAxis! - + internal var _rightAxis1: YAxis! + internal var _leftYAxisRenderer: YAxisRenderer! + internal var _leftYAxisRenderer1: YAxisRenderer! internal var _rightYAxisRenderer: YAxisRenderer! + internal var _rightYAxisRenderer1: YAxisRenderer! internal var _leftAxisTransformer: Transformer! + internal var _leftAxisTransformer1: Transformer! internal var _rightAxisTransformer: Transformer! + internal var _rightAxisTransformer1: Transformer! internal var _xAxisRenderer: XAxisRenderer! @@ -100,13 +108,21 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD super.initialize() _leftAxis = YAxis(position: .left) + _leftAxis1 = YAxis(position: .left1) _rightAxis = YAxis(position: .right) + _rightAxis1 = YAxis(position: .right1) _leftAxisTransformer = Transformer(viewPortHandler: _viewPortHandler) + _leftAxisTransformer1 = Transformer(viewPortHandler: _viewPortHandler) _rightAxisTransformer = Transformer(viewPortHandler: _viewPortHandler) + _rightAxisTransformer1 = Transformer(viewPortHandler: _viewPortHandler) + _leftYAxisRenderer = YAxisRenderer(viewPortHandler: _viewPortHandler, yAxis: _leftAxis, transformer: _leftAxisTransformer) + _leftYAxisRenderer1 = YAxisRenderer(viewPortHandler: _viewPortHandler, yAxis: _leftAxis1, transformer: _leftAxisTransformer1) _rightYAxisRenderer = YAxisRenderer(viewPortHandler: _viewPortHandler, yAxis: _rightAxis, transformer: _rightAxisTransformer) + _rightYAxisRenderer1 = YAxisRenderer(viewPortHandler: _viewPortHandler, yAxis: _rightAxis1, transformer: _rightAxisTransformer1) + _xAxisRenderer = XAxisRenderer(viewPortHandler: _viewPortHandler, xAxis: _xAxis, transformer: _leftAxisTransformer) @@ -125,7 +141,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD _doubleTapGestureRecognizer.isEnabled = _doubleTapToZoomEnabled _panGestureRecognizer.isEnabled = _dragEnabled - + #if !os(tvOS) _pinchGestureRecognizer = NSUIPinchGestureRecognizer(target: self, action: #selector(BarLineChartViewBase.pinchGestureRecognized(_:))) _pinchGestureRecognizer.delegate = self @@ -170,25 +186,32 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD let optionalContext = NSUIGraphicsGetCurrentContext() guard let context = optionalContext else { return } - + // execute all drawing commands drawGridBackground(context: context) - if _autoScaleMinMaxEnabled { autoScale() } - + if _leftAxis.isEnabled { _leftYAxisRenderer?.computeAxis(min: _leftAxis._axisMinimum, max: _leftAxis._axisMaximum, inverted: _leftAxis.isInverted) } + if _leftAxis1.isEnabled + { + _leftYAxisRenderer1?.computeAxis(min: _leftAxis1._axisMinimum, max: _leftAxis1._axisMaximum, inverted: _leftAxis1.isInverted) + } if _rightAxis.isEnabled { _rightYAxisRenderer?.computeAxis(min: _rightAxis._axisMinimum, max: _rightAxis._axisMaximum, inverted: _rightAxis.isInverted) } + if _rightAxis1.isEnabled + { + _rightYAxisRenderer1?.computeAxis(min: _rightAxis1._axisMinimum, max: _rightAxis1._axisMaximum, inverted: _rightAxis1.isInverted) + } if _xAxis.isEnabled { @@ -197,12 +220,16 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD _xAxisRenderer?.renderAxisLine(context: context) _leftYAxisRenderer?.renderAxisLine(context: context) + _leftYAxisRenderer1?.renderAxisLine(context: context) _rightYAxisRenderer?.renderAxisLine(context: context) - + _rightYAxisRenderer1?.renderAxisLine(context: context) + // The renderers are responsible for clipping, to account for line-width center etc. _xAxisRenderer?.renderGridLines(context: context) _leftYAxisRenderer?.renderGridLines(context: context) + _leftYAxisRenderer1?.renderGridLines(context: context) _rightYAxisRenderer?.renderGridLines(context: context) + _rightYAxisRenderer1?.renderGridLines(context: context) if _xAxis.isEnabled && _xAxis.isDrawLimitLinesBehindDataEnabled { @@ -213,11 +240,21 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { _leftYAxisRenderer?.renderLimitLines(context: context) } + if _leftAxis1.isEnabled && _leftAxis1.isDrawLimitLinesBehindDataEnabled + { + _leftYAxisRenderer1?.renderLimitLines(context: context) + } + if _rightAxis.isEnabled && _rightAxis.isDrawLimitLinesBehindDataEnabled { _rightYAxisRenderer?.renderLimitLines(context: context) } + if _rightAxis1.isEnabled && _rightAxis1.isDrawLimitLinesBehindDataEnabled + { + _rightYAxisRenderer1?.renderLimitLines(context: context) + } + // make sure the data cannot be drawn outside the content-rect context.saveGState() @@ -243,16 +280,28 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { _leftYAxisRenderer?.renderLimitLines(context: context) } + if _leftAxis1.isEnabled && !_leftAxis1.isDrawLimitLinesBehindDataEnabled + { + _leftYAxisRenderer1?.renderLimitLines(context: context) + } if _rightAxis.isEnabled && !_rightAxis.isDrawLimitLinesBehindDataEnabled { _rightYAxisRenderer?.renderLimitLines(context: context) } + if _rightAxis1.isEnabled && !_rightAxis1.isDrawLimitLinesBehindDataEnabled + { + _rightYAxisRenderer1?.renderLimitLines(context: context) + } + _xAxisRenderer.renderAxisLabels(context: context) _leftYAxisRenderer.renderAxisLabels(context: context) + _leftYAxisRenderer1.renderAxisLabels(context: context) + _rightYAxisRenderer.renderAxisLabels(context: context) - + _rightYAxisRenderer1.renderAxisLabels(context: context) + if clipValuesToContentEnabled { context.saveGState() @@ -266,9 +315,9 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { renderer!.drawValues(context: context) } - + _legendRenderer.renderLegend(context: context) - + drawDescription(context: context) drawMarkers(context: context) @@ -293,25 +342,37 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { _leftAxis.calculate(min: data.getYMin(axis: .left), max: data.getYMax(axis: .left)) } + if _leftAxis1.isEnabled + { + _leftAxis1.calculate(min: data.getYMin(axis: .left1), max: data.getYMax(axis: .left1)) + } if _rightAxis.isEnabled { _rightAxis.calculate(min: data.getYMin(axis: .right), max: data.getYMax(axis: .right)) } + if _rightAxis1.isEnabled + { + _rightAxis1.calculate(min: data.getYMin(axis: .right1), max: data.getYMax(axis: .right1)) + } calculateOffsets() } internal func prepareValuePxMatrix() { + _leftAxisTransformer.prepareMatrixValuePx (chartXMin: xAxis._axisMinimum, deltaX: CGFloat(xAxis.axisRange), deltaY: CGFloat(_leftAxis.axisRange), chartYMin: _leftAxis._axisMinimum) + _leftAxisTransformer1.prepareMatrixValuePx(chartXMin: xAxis._axisMinimum, deltaX: CGFloat(xAxis.axisRange), deltaY: CGFloat(_leftAxis1.axisRange), chartYMin: _leftAxis1._axisMinimum) _rightAxisTransformer.prepareMatrixValuePx(chartXMin: _xAxis._axisMinimum, deltaX: CGFloat(xAxis.axisRange), deltaY: CGFloat(_rightAxis.axisRange), chartYMin: _rightAxis._axisMinimum) - _leftAxisTransformer.prepareMatrixValuePx(chartXMin: xAxis._axisMinimum, deltaX: CGFloat(xAxis.axisRange), deltaY: CGFloat(_leftAxis.axisRange), chartYMin: _leftAxis._axisMinimum) + _rightAxisTransformer1.prepareMatrixValuePx(chartXMin: _xAxis._axisMinimum, deltaX: CGFloat(xAxis.axisRange), deltaY: CGFloat(_rightAxis1.axisRange), chartYMin: _rightAxis1._axisMinimum) } internal func prepareOffsetMatrix() { - _rightAxisTransformer.prepareMatrixOffset(inverted: _rightAxis.isInverted) _leftAxisTransformer.prepareMatrixOffset(inverted: _leftAxis.isInverted) + _leftAxisTransformer1.prepareMatrixOffset(inverted: _leftAxis1.isInverted) + _rightAxisTransformer.prepareMatrixOffset(inverted: _rightAxis.isInverted) + _rightAxisTransformer1.prepareMatrixOffset(inverted: _rightAxis1.isInverted) } open override func notifyDataSetChanged() @@ -321,7 +382,9 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD calcMinMax() _leftYAxisRenderer?.computeAxis(min: _leftAxis._axisMinimum, max: _leftAxis._axisMaximum, inverted: _leftAxis.isInverted) + _leftYAxisRenderer1?.computeAxis(min: _leftAxis1._axisMinimum, max: _leftAxis1._axisMaximum, inverted: _leftAxis1.isInverted) _rightYAxisRenderer?.computeAxis(min: _rightAxis._axisMinimum, max: _rightAxis._axisMaximum, inverted: _rightAxis.isInverted) + _rightYAxisRenderer1?.computeAxis(min: _rightAxis1._axisMinimum, max: _rightAxis1._axisMaximum, inverted: _rightAxis1.isInverted) if let data = _data { @@ -329,7 +392,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD min: _xAxis._axisMinimum, max: _xAxis._axisMaximum, inverted: false) - + if _legend !== nil { _legendRenderer?.computeLegend(data: data) @@ -348,7 +411,10 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD // calculate axis range (min / max) according to provided data _leftAxis.calculate(min: _data?.getYMin(axis: .left) ?? 0.0, max: _data?.getYMax(axis: .left) ?? 0.0) + _leftAxis1.calculate(min: _data?.getYMin(axis: .left1) ?? 0.0, max: _data?.getYMax(axis: .left1) ?? 0.0) _rightAxis.calculate(min: _data?.getYMin(axis: .right) ?? 0.0, max: _data?.getYMax(axis: .right) ?? 0.0) + _rightAxis1.calculate(min: _data?.getYMin(axis: .right1) ?? 0.0, max: _data?.getYMax(axis: .right1) ?? 0.0) + } internal func calculateLegendOffsets(offsetLeft: inout CGFloat, offsetTop: inout CGFloat, offsetRight: inout CGFloat, offsetBottom: inout CGFloat) @@ -389,18 +455,8 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { case .top: offsetTop += min(_legend.neededHeight, _viewPortHandler.chartHeight * _legend.maxSizePercent) + _legend.yOffset - if xAxis.isEnabled && xAxis.isDrawLabelsEnabled - { - offsetTop += xAxis.labelRotatedHeight - } - case .bottom: offsetBottom += min(_legend.neededHeight, _viewPortHandler.chartHeight * _legend.maxSizePercent) + _legend.yOffset - if xAxis.isEnabled && xAxis.isDrawLabelsEnabled - { - offsetBottom += xAxis.labelRotatedHeight - } - default: break } @@ -417,39 +473,142 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD var offsetTop = CGFloat(0.0) var offsetBottom = CGFloat(0.0) - calculateLegendOffsets(offsetLeft: &offsetLeft, - offsetTop: &offsetTop, - offsetRight: &offsetRight, - offsetBottom: &offsetBottom) + var offsetLeftLegend = CGFloat(0.0) + var offsetRightLegend = CGFloat(0.0) + var offsetTopLegend = CGFloat(0.0) + var offsetBottomLegend = CGFloat(0.0) + + calculateLegendOffsets(offsetLeft: &offsetLeftLegend, + offsetTop: &offsetTopLegend, + offsetRight: &offsetRightLegend, + offsetBottom: &offsetBottomLegend) + + let axisRectHeight = viewPortHandler.contentHeight + let axisRectTop = viewPortHandler.contentTop + let lineWidth : CGFloat = 1.0 + let stick : CGFloat = 5.0 // offsets for y-labels + // Space from left to right + // offsetLeft = offsetLeftLegend + leftAxis1.axisRectLeft.height + leftAxis.axisRectLeft.height + leftAxis.xOffset + + // rect axis + // 1 pixel : line width + // 5 pixels : stick + // n pixels : label width + // n pixels : name height + offsetLeft = offsetLeftLegend + leftAxis.xOffset + if leftAxis1.needsOffset + { + offsetLeft += lineWidth + stick + leftAxis1.requiredSize().width + if leftAxis1.nameAxisEnabled + { + let nameAxisHeight = leftAxis1.nameAxis.size(attributes: [NSFontAttributeName: leftAxis1.nameAxisFont]).height + let width = lineWidth + stick + leftAxis1.requiredSize().width + nameAxisHeight + + offsetLeft += nameAxisHeight + leftAxis1.axisRectLeft = CGRect(x: offsetLeftLegend, + y: axisRectTop, + width: width, + height: axisRectHeight) + } + } + if leftAxis.needsOffset { - offsetLeft += leftAxis.requiredSize().width + offsetLeft += lineWidth + stick + leftAxis.requiredSize().width + if leftAxis.nameAxisEnabled + { + let nameAxisHeight = leftAxis.nameAxis.size(attributes: [NSFontAttributeName: leftAxis.nameAxisFont]).height + let width = lineWidth + stick + nameAxisHeight + leftAxis.requiredSize().width + + offsetLeft += nameAxisHeight + leftAxis.axisRectLeft = CGRect(x: offsetLeftLegend + leftAxis1.axisRectLeft.width, + y: axisRectTop, + width: width, + height:axisRectHeight) + } + } + + // Space from right to left + offsetRight = offsetRightLegend + rightAxis.xOffset + if rightAxis1.needsOffset + { + offsetRight += lineWidth + stick + rightAxis1.requiredSize().width + if rightAxis1.nameAxisEnabled + { + let nameAxisHeight = rightAxis1.nameAxis.size(attributes: [NSFontAttributeName: rightAxis1.nameAxisFont]).height + let width = lineWidth + stick + nameAxisHeight + rightAxis1.requiredSize().width + + offsetRight += nameAxisHeight + rightAxis1.axisRectRight = CGRect(x: viewPortHandler.chartWidth - offsetRightLegend - width, + y: axisRectTop, + width: width, + height: axisRectHeight) + } } if rightAxis.needsOffset { - offsetRight += rightAxis.requiredSize().width + offsetRight += lineWidth + stick + rightAxis.requiredSize().width + if rightAxis.nameAxisEnabled + { + let nameAxisHeight = rightAxis.nameAxis.size(attributes: [NSFontAttributeName: rightAxis.nameAxisFont]).height + let width = lineWidth + stick + nameAxisHeight + rightAxis.requiredSize().width + + offsetRight += nameAxisHeight + rightAxis.axisRectRight = CGRect(x: viewPortHandler.chartWidth - offsetRightLegend - rightAxis1.axisRectRight.width - width, + y: viewPortHandler.contentTop, + width: width, + height: axisRectHeight) + } } - + if xAxis.isEnabled && xAxis.isDrawLabelsEnabled { - let xlabelheight = xAxis.labelRotatedHeight + xAxis.yOffset + var xlabelheight = (xAxis.labelRotationAngle != 0 ? xAxis.labelRotatedHeight : xAxis.labelHeight) + xlabelheight += xAxis.yOffset + + var namexAxisHeight = CGFloat(0.0) + var nameAxisRectWidth = CGFloat(0.0) + var nameAxisRectLeft = CGFloat(0.0) + if xAxis.nameAxisEnabled + { + namexAxisHeight = xAxis.nameAxis.size(attributes: [NSFontAttributeName: xAxis.nameAxisFont]).height + nameAxisRectWidth = viewPortHandler.contentWidth + nameAxisRectLeft = viewPortHandler.contentLeft + } // offsets for x-labels if xAxis.labelPosition == .bottom { - offsetBottom += xlabelheight + offsetBottom = offsetBottomLegend + xlabelheight + namexAxisHeight + xAxis.axisRectBottom = CGRect(x: nameAxisRectLeft, + y: viewPortHandler.chartHeight - offsetBottomLegend - namexAxisHeight, + width: nameAxisRectWidth, + height: namexAxisHeight) } else if xAxis.labelPosition == .top { - offsetTop += xlabelheight + offsetTop = offsetTopLegend + xlabelheight + namexAxisHeight + xAxis.axisRectTop = CGRect(x: nameAxisRectLeft, + y: offsetTop - namexAxisHeight - xlabelheight, + width: nameAxisRectWidth, + height: namexAxisHeight) } else if xAxis.labelPosition == .bothSided { - offsetBottom += xlabelheight - offsetTop += xlabelheight + offsetBottom = offsetBottomLegend + xlabelheight + namexAxisHeight + xAxis.axisRectBottom = CGRect(x: nameAxisRectLeft, + y: viewPortHandler.chartHeight - offsetBottomLegend - namexAxisHeight, + width: nameAxisRectWidth, + height: namexAxisHeight) + + offsetTop = offsetTopLegend + xlabelheight + namexAxisHeight + xAxis.axisRectTop = CGRect(x: nameAxisRectLeft, + y: offsetTopLegend, + width: nameAxisRectWidth, + height: namexAxisHeight) } } @@ -457,7 +616,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD offsetRight += self.extraRightOffset offsetBottom += self.extraBottomOffset offsetLeft += self.extraLeftOffset - + _viewPortHandler.restrainViewPort( offsetLeft: max(self.minOffset, offsetLeft), offsetTop: max(self.minOffset, offsetTop), @@ -638,8 +797,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD } else { - location.y = -(_viewPortHandler.chartHeight - location.y - _viewPortHandler.offsetBottom) - } + location.y = -(_viewPortHandler.chartHeight - location.y - _viewPortHandler.offsetBottom) } let scaleX = canZoomMoreX ? recognizer.nsuiScale : 1.0 let scaleY = canZoomMoreY ? recognizer.nsuiScale : 1.0 @@ -853,8 +1011,11 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { if gestureRecognizer == _panGestureRecognizer { + let velocity = _panGestureRecognizer.velocity(in: self) if _data === nil || !_dragEnabled || - (self.hasNoDragOffset && self.isFullyZoomedOut && !self.isHighlightPerDragEnabled) + (self.hasNoDragOffset && self.isFullyZoomedOut && !self.isHighlightPerDragEnabled) || + (!_dragYEnabled && fabs(velocity.y) > fabs(velocity.x)) || + (!_dragXEnabled && fabs(velocity.y) < fabs(velocity.x)) { return false } @@ -871,19 +1032,18 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD } #endif } - return true } #if !os(OSX) open override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { - if !super.gestureRecognizerShouldBegin(gestureRecognizer) - { - return false - } - - return nsuiGestureRecognizerShouldBegin(gestureRecognizer) + if !super.gestureRecognizerShouldBegin(gestureRecognizer) + { + return false + } + + return nsuiGestureRecognizerShouldBegin(gestureRecognizer) } #endif @@ -924,7 +1084,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { scrollView = superViewOfScrollView } - + var foundScrollView = scrollView as? NSUIScrollView if foundScrollView !== nil && !foundScrollView!.nsuiIsScrollEnabled @@ -971,7 +1131,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD calculateOffsets() setNeedsDisplay() } - + /// Zooms out by 0.7, from the charts center. open func zoomOut() { @@ -979,7 +1139,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD let matrix = _viewPortHandler.zoomOut(x: center.x, y: -center.y) let _ = _viewPortHandler.refresh(newMatrix: matrix, chart: self, invalidate: false) - + // Range might have changed, which means that Y-axis labels could have changed in size, affecting Y-axis size. So we need to recalculate offsets. calculateOffsets() setNeedsDisplay() @@ -995,7 +1155,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD calculateOffsets() setNeedsDisplay() } - + /// Zooms in or out by the given scale factor. x and y are the coordinates /// (in pixels) of the zoom center. /// @@ -1005,9 +1165,9 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD /// - parameter y: open func zoom( scaleX: CGFloat, - scaleY: CGFloat, - x: CGFloat, - y: CGFloat) + scaleY: CGFloat, + x: CGFloat, + y: CGFloat) { let matrix = _viewPortHandler.zoom(scaleX: scaleX, scaleY: scaleY, x: x, y: -y) let _ = _viewPortHandler.refresh(newMatrix: matrix, chart: self, invalidate: false) @@ -1027,10 +1187,10 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD /// - parameter axis: open func zoom( scaleX: CGFloat, - scaleY: CGFloat, - xValue: Double, - yValue: Double, - axis: YAxis.AxisDependency) + scaleY: CGFloat, + xValue: Double, + yValue: Double, + axis: YAxis.AxisDependency) { let job = ZoomViewJob( viewPortHandler: viewPortHandler, @@ -1053,7 +1213,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD /// - parameter axis: open func zoomToCenter( scaleX: CGFloat, - scaleY: CGFloat) + scaleY: CGFloat) { let center = centerOffsets let matrix = viewPortHandler.zoom( @@ -1102,7 +1262,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD zoomOriginY: origin.y, duration: duration, easing: easing) - + addViewportJob(job) } @@ -1190,7 +1350,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD let xScale = _xAxis.axisRange / minXRange _viewPortHandler.setMaximumScaleX(CGFloat(xScale)) } - + /// Limits the maximum and minimum value count that can be visible by pinching and zooming. /// /// e.g. minRange=10, maxRange=100 no less than 10 values and no more that 100 values can be viewed @@ -1225,7 +1385,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD let yScale = getAxisRange(axis: axis) / minYRange _viewPortHandler.setMaximumScaleY(CGFloat(yScale)) } - + /// Limits the maximum and minimum y range that can be visible by pinching and zooming. /// /// - parameter minYRange: @@ -1251,10 +1411,10 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD addViewportJob(job) } - + /// Centers the viewport to the specified y-value on the y-axis. /// This also refreshes the chart by calling setNeedsDisplay(). - /// + /// /// - parameter yValue: /// - parameter axis: - which axis should be used as a reference for the y-axis open func moveViewToY(_ yValue: Double, axis: YAxis.AxisDependency) @@ -1270,10 +1430,10 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD addViewportJob(job) } - + /// This will move the left side of the current viewport to the specified x-value on the x-axis, and center the viewport to the specified y-value on the y-axis. /// This also refreshes the chart by calling setNeedsDisplay(). - /// + /// /// - parameter xValue: /// - parameter yValue: /// - parameter axis: - which axis should be used as a reference for the y-axis @@ -1452,7 +1612,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { centerViewToAnimated(xValue: xValue, yValue: yValue, axis: axis, duration: duration, easingOption: .easeInOutSine) } - + /// Sets custom offsets for the current `ChartViewPort` (the offsets on the sides of the actual chart window). Setting this will prevent the chart from automatically calculating it's offsets. Use `resetViewPortOffsets()` to undo this. /// ONLY USE THIS WHEN YOU KNOW WHAT YOU ARE DOING, else use `setExtraOffsets(...)`. open func setViewPortOffsets(left: CGFloat, top: CGFloat, right: CGFloat, bottom: CGFloat) @@ -1472,42 +1632,44 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD }) } } - + /// Resets all custom offsets set via `setViewPortOffsets(...)` method. Allows the chart to again calculate all offsets automatically. open func resetViewPortOffsets() { _customViewPortEnabled = false calculateOffsets() } - + // MARK: - Accessors /// - returns: The range of the specified axis. open func getAxisRange(axis: YAxis.AxisDependency) -> Double { - if axis == .left - { + switch axis { + case .left: return leftAxis.axisRange - } - else - { + case .left1: + return leftAxis1.axisRange + case .right: return rightAxis.axisRange + case .right1: + return rightAxis1.axisRange } } - + /// - returns: The position (in pixels) the provided Entry has inside the chart view open func getPosition(entry e: ChartDataEntry, axis: YAxis.AxisDependency) -> CGPoint { var vals = CGPoint(x: CGFloat(e.x), y: CGFloat(e.y)) - + getTransformer(forAxis: axis).pointValueToPixel(&vals) - + return vals } - + /// is dragging enabled? (moving the chart with the finger) for the chart (this does not affect scaling). open var dragEnabled: Bool - { + { get { return _dragEnabled @@ -1517,10 +1679,34 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD if _dragEnabled != newValue { _dragEnabled = newValue + _dragYEnabled = newValue + _dragXEnabled = newValue } } } + open var dragYEnabled: Bool { + get + { + return _dragYEnabled + } + set + { + _dragYEnabled = newValue + } + } + + open var dragXEnabled: Bool { + get + { + return _dragXEnabled + } + set + { + _dragXEnabled = newValue + } + } + /// is dragging enabled? (moving the chart with the finger) for the chart (this does not affect scaling). open var isDragEnabled: Bool { @@ -1541,7 +1727,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD } open var scaleXEnabled: Bool - { + { get { return _scaleXEnabled @@ -1559,7 +1745,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD } open var scaleYEnabled: Bool - { + { get { return _scaleYEnabled @@ -1581,7 +1767,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD /// flag that indicates if double tap zoom is enabled or not open var doubleTapToZoomEnabled: Bool - { + { get { return _doubleTapToZoomEnabled @@ -1608,7 +1794,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD /// If set to true, highlighting per dragging over a fully zoomed out chart is enabled /// You might want to disable this when using inside a `NSUIScrollView` - /// + /// /// **default**: true open var isHighlightPerDragEnabled: Bool { @@ -1628,7 +1814,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { return drawBordersEnabled } - + /// - returns: The x and y values in the chart at the given touch point /// (encapsulated in a `CGPoint`). This method transforms pixel coordinates to /// coordinates / values in the chart. This is the opposite method to @@ -1637,7 +1823,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { return getTransformer(forAxis: axis).valueForTouchPoint(pt) } - + /// Transforms the given chart values into pixels. This is the opposite /// method to `valueForTouchPoint(...)`. open func pixelForValues(x: Double, y: Double, axis: YAxis.AxisDependency) -> CGPoint @@ -1665,7 +1851,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD } return nil } - + /// - returns: The current x-scale factor open var scaleX: CGFloat { @@ -1675,7 +1861,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD } return _viewPortHandler.scaleX } - + /// - returns: The current y-scale factor open var scaleY: CGFloat { @@ -1685,38 +1871,53 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD } return _viewPortHandler.scaleY } - + /// if the chart is fully zoomed out, return true open var isFullyZoomedOut: Bool { return _viewPortHandler.isFullyZoomedOut } - + /// - returns: The left y-axis object. In the horizontal bar-chart, this is the /// top axis. open var leftAxis: YAxis { return _leftAxis } - + /// - returns: The left y-axis object. In the horizontal bar-chart, this is the + /// top axis. + open var leftAxis1: YAxis + { + return _leftAxis1 + } + /// - returns: The right y-axis object. In the horizontal bar-chart, this is the /// bottom axis. open var rightAxis: YAxis { return _rightAxis } - + + /// - returns: The right y-axis object. In the horizontal bar-chart, this is the + /// bottom axis. + open var rightAxis1: YAxis { return _rightAxis1 } + + /// - returns: The y-axis object to the corresponding AxisDependency. In the /// horizontal bar-chart, LEFT == top, RIGHT == BOTTOM open func getAxis(_ axis: YAxis.AxisDependency) -> YAxis { - if axis == .left + switch axis { + case .left: return _leftAxis - } - else - { + case .left1: + return _leftAxis1 + case .right: return _rightAxis + case .right1: + return _rightAxis1 + } } /// flag that indicates if pinch-zoom is enabled. if true, both x and y axis can be scaled simultaneously with 2 fingers, if false, x and y axis can be scaled separately open var pinchZoomEnabled: Bool - { + { get { return _pinchZoomEnabled @@ -1732,33 +1933,33 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD } } } - + /// **default**: false /// - returns: `true` if pinch-zoom is enabled, `false` ifnot open var isPinchZoomEnabled: Bool { return pinchZoomEnabled } - + /// Set an offset in dp that allows the user to drag the chart over it's /// bounds on the x-axis. open func setDragOffsetX(_ offset: CGFloat) { _viewPortHandler.setDragOffsetX(offset) } - + /// Set an offset in dp that allows the user to drag the chart over it's /// bounds on the y-axis. open func setDragOffsetY(_ offset: CGFloat) { _viewPortHandler.setDragOffsetY(offset) } - + /// - returns: `true` if both drag offsets (x and y) are zero or smaller. open var hasNoDragOffset: Bool { return _viewPortHandler.hasNoDragOffset } - + /// The X axis renderer. This is a read-write property so you can set your own custom renderer here. /// **default**: An instance of XAxisRenderer /// - returns: The current set X axis renderer open var xAxisRenderer: XAxisRenderer - { + { get { return _xAxisRenderer } set { _xAxisRenderer = newValue } } @@ -1767,7 +1968,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD /// **default**: An instance of YAxisRenderer /// - returns: The current set left Y axis renderer open var leftYAxisRenderer: YAxisRenderer - { + { get { return _leftYAxisRenderer } set { _leftYAxisRenderer = newValue } } @@ -1776,7 +1977,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD /// **default**: An instance of YAxisRenderer /// - returns: The current set right Y axis renderer open var rightYAxisRenderer: YAxisRenderer - { + { get { return _rightYAxisRenderer } set { _rightYAxisRenderer = newValue } } @@ -1785,7 +1986,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { return max(leftAxis._axisMaximum, rightAxis._axisMaximum) } - + open override var chartYMin: Double { return min(leftAxis._axisMinimum, rightAxis._axisMinimum) @@ -1794,13 +1995,13 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD /// - returns: `true` if either the left or the right or both axes are inverted. open var isAnyAxisInverted: Bool { - return _leftAxis.isInverted || _rightAxis.isInverted + return _leftAxis.isInverted || _rightAxis1.isInverted || _rightAxis.isInverted || _rightAxis1.isInverted } /// flag that indicates if auto scaling on the y axis is enabled. /// if yes, the y axis automatically adjusts to the min and max y values of the current x axis range whenever the viewport changes open var autoScaleMinMaxEnabled: Bool - { + { get { return _autoScaleMinMaxEnabled } set { _autoScaleMinMaxEnabled = newValue } } @@ -1812,13 +2013,16 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD /// Sets a minimum width to the specified y axis. open func setYAxisMinWidth(_ axis: YAxis.AxisDependency, width: CGFloat) { - if axis == .left + switch axis { + case .left: _leftAxis.minWidth = width - } - else - { + case .left1: + _leftAxis1.minWidth = width + case .right: _rightAxis.minWidth = width + case .right1: + _rightAxis1.minWidth = width } } @@ -1826,26 +2030,34 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD /// - returns: The (custom) minimum width of the specified Y axis. open func getYAxisMinWidth(_ axis: YAxis.AxisDependency) -> CGFloat { - if axis == .left + switch axis { + case .left: return _leftAxis.minWidth - } - else - { + case .left1: + return _leftAxis1.minWidth + case .right: return _rightAxis.minWidth + case .right1: + return _rightAxis1.minWidth } } + /// Sets a maximum width to the specified y axis. /// Zero (0.0) means there's no maximum width open func setYAxisMaxWidth(_ axis: YAxis.AxisDependency, width: CGFloat) { - if axis == .left + switch axis { + case .left: _leftAxis.maxWidth = width - } - else - { + case .left1: + _leftAxis1.maxWidth = width + case .right: _rightAxis.maxWidth = width + case .right1: + _rightAxis1.maxWidth = width + } } @@ -1855,26 +2067,32 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD /// - returns: The (custom) maximum width of the specified Y axis. open func getYAxisMaxWidth(_ axis: YAxis.AxisDependency) -> CGFloat { - if axis == .left + switch axis { + case .left: return _leftAxis.maxWidth - } - else - { + case .left1: + return _leftAxis1.maxWidth + case .right: return _rightAxis.maxWidth + case .right1: + return _rightAxis1.maxWidth } } - + /// - returns the width of the specified y axis. open func getYAxisWidth(_ axis: YAxis.AxisDependency) -> CGFloat { - if axis == .left + switch axis { + case .left: return _leftAxis.requiredSize().width - } - else - { + case .left1: + return _leftAxis1.requiredSize().width + case .right: return _rightAxis.requiredSize().width + case .right1: + return _rightAxis1.requiredSize().width } } @@ -1885,19 +2103,22 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD /// backwards. open func getTransformer(forAxis axis: YAxis.AxisDependency) -> Transformer { - if axis == .left + switch axis { + case .left: return _leftAxisTransformer - } - else - { + case .left1: + return _leftAxisTransformer1 + case .right: return _rightAxisTransformer + case .right1: + return _rightAxisTransformer1 } } /// the number of maximum visible drawn values on the chart only active when `drawValuesEnabled` is enabled open override var maxVisibleCount: Int - { + { get { return _maxVisibleCount @@ -1933,7 +2154,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD y: viewPortHandler.contentBottom) getTransformer(forAxis: .left).pixelToValues(&pt) - + return min(xAxis._axisMaximum, Double(pt.x)) } } diff --git a/Source/Charts/Charts/HorizontalBarChartView.swift b/Source/Charts/Charts/HorizontalBarChartView.swift index 06863ee619..7da8b86aaf 100644 --- a/Source/Charts/Charts/HorizontalBarChartView.swift +++ b/Source/Charts/Charts/HorizontalBarChartView.swift @@ -24,11 +24,19 @@ open class HorizontalBarChartView: BarChartView super.initialize() _leftAxisTransformer = TransformerHorizontalBarChart(viewPortHandler: _viewPortHandler) + _leftAxisTransformer1 = TransformerHorizontalBarChart(viewPortHandler: _viewPortHandler) + _rightAxisTransformer = TransformerHorizontalBarChart(viewPortHandler: _viewPortHandler) + _rightAxisTransformer1 = TransformerHorizontalBarChart(viewPortHandler: _viewPortHandler) renderer = HorizontalBarChartRenderer(dataProvider: self, animator: _animator, viewPortHandler: _viewPortHandler) - _leftYAxisRenderer = YAxisRendererHorizontalBarChart(viewPortHandler: _viewPortHandler, yAxis: _leftAxis, transformer: _leftAxisTransformer) + + _leftYAxisRenderer = YAxisRendererHorizontalBarChart( viewPortHandler: _viewPortHandler, yAxis: _leftAxis, transformer: _leftAxisTransformer) + _leftYAxisRenderer1 = YAxisRendererHorizontalBarChart( viewPortHandler: _viewPortHandler, yAxis: _leftAxis1, transformer: _leftAxisTransformer1) + _rightYAxisRenderer = YAxisRendererHorizontalBarChart(viewPortHandler: _viewPortHandler, yAxis: _rightAxis, transformer: _rightAxisTransformer) + _rightYAxisRenderer1 = YAxisRendererHorizontalBarChart(viewPortHandler: _viewPortHandler, yAxis: _rightAxis1, transformer: _rightAxisTransformer1) + _xAxisRenderer = XAxisRendererHorizontalBarChart(viewPortHandler: _viewPortHandler, xAxis: _xAxis, transformer: _leftAxisTransformer, chart: self) self.highlighter = HorizontalBarHighlighter(chart: self) @@ -41,39 +49,142 @@ open class HorizontalBarChartView: BarChartView offsetTop: CGFloat = 0.0, offsetBottom: CGFloat = 0.0 - calculateLegendOffsets(offsetLeft: &offsetLeft, - offsetTop: &offsetTop, - offsetRight: &offsetRight, - offsetBottom: &offsetBottom) + var offsetLeftLegend = CGFloat(0.0) + var offsetRightLegend = CGFloat(0.0) + var offsetTopLegend = CGFloat(0.0) + var offsetBottomLegend = CGFloat(0.0) + + calculateLegendOffsets(offsetLeft: &offsetLeftLegend, + offsetTop: &offsetTopLegend, + offsetRight: &offsetRightLegend, + offsetBottom: &offsetBottomLegend) + + let axisRectWidth = viewPortHandler.contentWidth + let axisRectLeft = viewPortHandler.contentLeft + + let lineWidth : CGFloat = 1.0 + let stick : CGFloat = 5.0 // offsets for y-labels - if _leftAxis.needsOffset + // Space from top to bottom + // offsetTop = offsetTopLegend + leftAxis1.axisRectTop.height + leftAxis.axisRectTop.height + leftAxis.yOffset + + // rect axis + // 1 pixel : line width + // 5 pixels : stick + // n pixels : label width + // n pixels : name height + offsetTop = offsetTopLegend + leftAxis.yOffset + if leftAxis1.needsOffset { - offsetTop += _leftAxis.getRequiredHeightSpace() + offsetTop += leftAxis1.getRequiredHeightSpace() + if leftAxis1.nameAxisEnabled + { + let nameAxisHeight = leftAxis.nameAxis.size(attributes: [NSFontAttributeName: leftAxis.nameAxisFont]).height + let height = lineWidth + stick + nameAxisHeight + leftAxis1.getRequiredHeightSpace() + + offsetTop += height + leftAxis.axisRectTop = CGRect(x: axisRectLeft, + y: offsetTop - offsetTopLegend, + width: axisRectWidth, + height: height) + } } - if _rightAxis.needsOffset + if leftAxis.needsOffset { - offsetBottom += _rightAxis.getRequiredHeightSpace() + offsetTop += leftAxis.getRequiredHeightSpace() + if leftAxis.nameAxisEnabled + { + let nameAxisHeight = leftAxis.nameAxis.size(attributes: [NSFontAttributeName: leftAxis.nameAxisFont]).height + let height = lineWidth + stick + nameAxisHeight + leftAxis.getRequiredHeightSpace() + + offsetTop += height + leftAxis.axisRectTop = CGRect(x: axisRectLeft, + y: offsetTop - height, + width: axisRectWidth, + height: height) + } } + offsetTop += leftAxis.yOffset + + // Space from bottom to top + offsetBottom = offsetBottomLegend + rightAxis.yOffset + if rightAxis1.needsOffset + { + offsetBottom += rightAxis1.getRequiredHeightSpace() + if rightAxis1.nameAxisEnabled + { + let nameAxisHeight = rightAxis1.nameAxis.size(attributes: [NSFontAttributeName: rightAxis1.nameAxisFont]).height + let height = lineWidth + stick + nameAxisHeight + rightAxis1.getRequiredHeightSpace() + + offsetBottom += height + rightAxis1.axisRectBottom = CGRect(x: axisRectLeft, + y: viewPortHandler.chartHeight - offsetBottom + height, + width: axisRectWidth, + height: height) + } + } + + if rightAxis.needsOffset + { + offsetBottom += rightAxis.getRequiredHeightSpace() + if rightAxis.nameAxisEnabled + { + let nameAxisHeight = rightAxis.nameAxis.size(attributes: [NSFontAttributeName: rightAxis.nameAxisFont]).height + let height = lineWidth + stick + nameAxisHeight + rightAxis.getRequiredHeightSpace() + + offsetBottom += height + rightAxis.axisRectBottom = CGRect(x: axisRectLeft, + y: viewPortHandler.chartHeight - offsetBottom, + width: axisRectWidth, + height: height) + } + } + offsetBottom += leftAxis.yOffset let xlabelwidth = _xAxis.labelRotatedWidth if _xAxis.isEnabled { + var namexAxisHeight = CGFloat(0.0) + if xAxis.nameAxisEnabled + { + namexAxisHeight = xAxis.nameAxis.size(attributes: [NSFontAttributeName: xAxis.nameAxisFont]).height + } + // offsets for x-labels + offsetLeft = offsetLeftLegend + offsetRight = offsetRightLegend if _xAxis.labelPosition == .bottom { - offsetLeft += xlabelwidth + offsetLeft += xlabelwidth + namexAxisHeight + xAxis.axisRectLeft = CGRect(x: offsetLeft - xlabelwidth - namexAxisHeight, + y:viewPortHandler.contentTop, + width: namexAxisHeight, + height:viewPortHandler.contentHeight) } else if _xAxis.labelPosition == .top { - offsetRight += xlabelwidth + offsetRight += xlabelwidth + namexAxisHeight + xAxis.axisRectRight = CGRect(x: viewPortHandler.contentRight + xlabelwidth, + y: viewPortHandler.contentTop, + width: namexAxisHeight, + height: viewPortHandler.contentHeight) } else if _xAxis.labelPosition == .bothSided { - offsetLeft += xlabelwidth - offsetRight += xlabelwidth + offsetLeft += xlabelwidth + namexAxisHeight + xAxis.axisRectLeft = CGRect(x: offsetLeft - xlabelwidth - namexAxisHeight, + y:viewPortHandler.contentTop, + width: namexAxisHeight, + height:viewPortHandler.contentHeight) + + offsetRight += xlabelwidth + namexAxisHeight + xAxis.axisRectRight = CGRect(x: viewPortHandler.contentRight + xlabelwidth, + y: viewPortHandler.contentTop, + width: namexAxisHeight, + height: viewPortHandler.contentHeight) } } @@ -95,7 +206,10 @@ open class HorizontalBarChartView: BarChartView internal override func prepareValuePxMatrix() { _rightAxisTransformer.prepareMatrixValuePx(chartXMin: _rightAxis._axisMinimum, deltaX: CGFloat(_rightAxis.axisRange), deltaY: CGFloat(_xAxis.axisRange), chartYMin: _xAxis._axisMinimum) + _rightAxisTransformer1.prepareMatrixValuePx(chartXMin: _rightAxis1._axisMinimum, deltaX: CGFloat(_rightAxis1.axisRange), deltaY: CGFloat(_xAxis.axisRange), chartYMin: _xAxis._axisMinimum) + _leftAxisTransformer.prepareMatrixValuePx(chartXMin: _leftAxis._axisMinimum, deltaX: CGFloat(_leftAxis.axisRange), deltaY: CGFloat(_xAxis.axisRange), chartYMin: _xAxis._axisMinimum) + _leftAxisTransformer1.prepareMatrixValuePx(chartXMin: _leftAxis1._axisMinimum, deltaX: CGFloat(_leftAxis1.axisRange), deltaY: CGFloat(_xAxis.axisRange), chartYMin: _xAxis._axisMinimum) } open override func getMarkerPosition(highlight: Highlight) -> CGPoint @@ -135,7 +249,7 @@ open class HorizontalBarChartView: BarChartView return vals } - + open override func getHighlightByTouchPoint(_ pt: CGPoint) -> Highlight? { if _data === nil diff --git a/Source/Charts/Components/AxisBase.swift b/Source/Charts/Components/AxisBase.swift index 160872e097..0c57c56d31 100644 --- a/Source/Charts/Components/AxisBase.swift +++ b/Source/Charts/Components/AxisBase.swift @@ -41,32 +41,43 @@ open class AxisBase: ComponentBase open var drawGridLinesEnabled = true open var drawAxisLineEnabled = true + open var nameAxis = "" + open var nameAxisFont = NSUIFont.systemFont(ofSize: 12.0) + open var nameAxisEnabled = false + + open var axisRectBottom = CGRect() + open var axisRectTop = CGRect() + open var axisRectLeft = CGRect() + open var axisRectRight = CGRect() + + fileprivate var _nameAxisTextColor = Int(6) + /// flag that indicates of the labels of this axis should be drawn or not open var drawLabelsEnabled = true fileprivate var _centerAxisLabelsEnabled = false - + /// Centers the axis labels instead of drawing them at their original position. /// This is useful especially for grouped BarChart. open var centerAxisLabelsEnabled: Bool - { + { get { return _centerAxisLabelsEnabled && entryCount > 0 } set { _centerAxisLabelsEnabled = newValue } } open var isCenterAxisLabelsEnabled: Bool - { + { get { return centerAxisLabelsEnabled } } - + /// array of limitlines that can be set for the axis fileprivate var _limitLines = [ChartLimitLine]() /// Are the LimitLines drawn behind the data or in front of the data? - /// + /// /// **default**: false open var drawLimitLinesBehindDataEnabled = false - + /// the flag can be used to turn off the antialias for grid lines open var gridAntialiasEnabled = true @@ -100,7 +111,7 @@ open class AxisBase: ComponentBase /// /// **default**: 1.0 open var granularity: Double - { + { get { return _granularity @@ -116,7 +127,7 @@ open class AxisBase: ComponentBase /// The minimum interval between axis values. open var isGranularityEnabled: Bool - { + { get { return granularityEnabled @@ -158,7 +169,7 @@ open class AxisBase: ComponentBase /// If no formatter is set, the chart will automatically determine a reasonable formatting (concerning decimals) for all the values that are drawn inside the chart. /// Use `nil` to use the formatter calculated by the chart. open var valueFormatter: IAxisValueFormatter? - { + { get { if _axisValueFormatter == nil || @@ -184,7 +195,7 @@ open class AxisBase: ComponentBase open var isDrawLabelsEnabled: Bool { return drawLabelsEnabled } /// Are the LimitLines drawn behind the data or in front of the data? - /// + /// /// **default**: false open var isDrawLimitLinesBehindDataEnabled: Bool { return drawLimitLinesBehindDataEnabled } @@ -213,13 +224,14 @@ open class AxisBase: ComponentBase /// the total range of values this axis covers open var axisRange = Double(0) + /// the number of label entries the axis should have /// max = 25, /// min = 2, /// default = 6, /// be aware that this number is not fixed and can only be approximated open var labelCount: Int - { + { get { return _labelCount @@ -302,7 +314,7 @@ open class AxisBase: ComponentBase /// This property is deprecated - Use `axisMinimum` instead. @available(*, deprecated: 1.0, message: "Use axisMinimum instead.") open var axisMinValue: Double - { + { get { return axisMinimum } set { axisMinimum = newValue } } @@ -310,7 +322,7 @@ open class AxisBase: ComponentBase /// This property is deprecated - Use `axisMaximum` instead. @available(*, deprecated: 1.0, message: "Use axisMaximum instead.") open var axisMaxValue: Double - { + { get { return axisMaximum } set { axisMaximum = newValue } } @@ -319,7 +331,7 @@ open class AxisBase: ComponentBase /// If set, this value will not be calculated automatically depending on the provided data. /// Use `resetCustomAxisMin()` to undo this. open var axisMinimum: Double - { + { get { return _axisMinimum @@ -336,7 +348,7 @@ open class AxisBase: ComponentBase /// If set, this value will not be calculated automatically depending on the provided data. /// Use `resetCustomAxisMax()` to undo this. open var axisMaximum: Double - { + { get { return _axisMaximum diff --git a/Source/Charts/Components/YAxis.swift b/Source/Charts/Components/YAxis.swift index 54dfe4b924..e5cad75bba 100644 --- a/Source/Charts/Components/YAxis.swift +++ b/Source/Charts/Components/YAxis.swift @@ -35,7 +35,9 @@ open class YAxis: AxisBase public enum AxisDependency: Int { case left + case left1 case right + case right1 } /// indicates if the bottom y-label entry is drawn or not @@ -63,10 +65,10 @@ open class YAxis: AxisBase /// I.e. [2, 3] will paint [-- -- ] /// [1, 3, 4, 2] will paint [- ---- - ---- ] open var zeroLineDashLengths: [CGFloat]? - + /// axis space from the largest value to the top in percent of the total axis range open var spaceTop = CGFloat(0.1) - + /// axis space from the smallest value to the bottom in percent of the total axis range open var spaceBottom = CGFloat(0.1) @@ -77,13 +79,13 @@ open class YAxis: AxisBase fileprivate var _axisDependency = AxisDependency.left /// the minimum width that the axis should take - /// + /// /// **default**: 0.0 open var minWidth = CGFloat(0) /// the maximum width that the axis can take. /// use Infinity for disabling the maximum. - /// + /// /// **default**: CGFloat.infinity open var maxWidth = CGFloat(CGFloat.infinity) @@ -91,7 +93,7 @@ open class YAxis: AxisBase { super.init() - self.yOffset = 0.0 + // self.yOffset = 0.0 why ??? } public init(position: AxisDependency) @@ -100,7 +102,7 @@ open class YAxis: AxisBase _axisDependency = position - self.yOffset = 0.0 + // self.yOffset = 0.0 why ?? } open var axisDependency: AxisDependency @@ -120,7 +122,11 @@ open class YAxis: AxisBase open func getRequiredHeightSpace() -> CGFloat { - return requiredSize().height + if isEnabled + { + return requiredSize().height + } + return 0 } /// - returns: `true` if this axis needs horizontal offset, `false` ifno offset is needed. @@ -175,5 +181,5 @@ open class YAxis: AxisBase open var isDrawBottomYLabelEntryEnabled: Bool { return drawBottomYLabelEntryEnabled } open var isDrawTopYLabelEntryEnabled: Bool { return drawTopYLabelEntryEnabled } - + } diff --git a/Source/Charts/Highlight/ChartHighlighter.swift b/Source/Charts/Highlight/ChartHighlighter.swift index dd94263899..53a8edcbe9 100644 --- a/Source/Charts/Highlight/ChartHighlighter.swift +++ b/Source/Charts/Highlight/ChartHighlighter.swift @@ -57,10 +57,22 @@ open class ChartHighlighter : NSObject, IHighlighter return nil } - let leftAxisMinDist = getMinimumDistance(closestValues: closestValues, y: y, axis: YAxis.AxisDependency.left) - let rightAxisMinDist = getMinimumDistance(closestValues: closestValues, y: y, axis: YAxis.AxisDependency.right) + var axisMinDist : [CGFloat] = [] + let axisDepency = [YAxis.AxisDependency.left , YAxis.AxisDependency.right, YAxis.AxisDependency.left1, YAxis.AxisDependency.right1] - let axis = leftAxisMinDist < rightAxisMinDist ? YAxis.AxisDependency.left : YAxis.AxisDependency.right + let leftAxisMinDist = getMinimumDistance(closestValues: closestValues, y: y, axis: YAxis.AxisDependency.left) + let rightAxisMinDist = getMinimumDistance(closestValues: closestValues, y: y, axis: YAxis.AxisDependency.right) + let leftAxisMinDist1 = getMinimumDistance(closestValues: closestValues, y: y, axis: YAxis.AxisDependency.left1) + let rightAxisMinDist1 = getMinimumDistance(closestValues: closestValues, y: y, axis: YAxis.AxisDependency.right1) + + axisMinDist.append(leftAxisMinDist) + axisMinDist.append(rightAxisMinDist) + axisMinDist.append(leftAxisMinDist1) + axisMinDist.append(rightAxisMinDist1) + + let mini = axisMinDist.min() + let index = axisMinDist.index(of: mini!) + let axis = axisDepency [index!] let detail = closestSelectionDetailByPixel(closestValues: closestValues, x: x, y: y, axis: axis, minSelectionDistance: chart.maxHighlightDistance) @@ -132,7 +144,7 @@ open class ChartHighlighter : NSObject, IHighlighter return highlights } - + // - MARK: - Utilities /// - returns: The `ChartHighlight` of the closest value on the x-y cartesian axes diff --git a/Source/Charts/Renderers/XAxisRenderer.swift b/Source/Charts/Renderers/XAxisRenderer.swift index 7bec034e63..24ee184cb3 100644 --- a/Source/Charts/Renderers/XAxisRenderer.swift +++ b/Source/Charts/Renderers/XAxisRenderer.swift @@ -101,7 +101,9 @@ open class XAxisRenderer: AxisRendererBase if xAxis.labelPosition == .top { - drawLabels(context: context, pos: viewPortHandler.contentTop - yOffset, anchor: CGPoint(x: 0.5, y: 1.0)) + let pos = viewPortHandler.contentTop - yOffset + drawLabels(context: context, pos: pos, anchor: CGPoint(x: 0.5, y: 1.0)) + drawNameXAxis(context: context, nameRect: xAxis.axisRectTop) } else if xAxis.labelPosition == .topInside { @@ -109,7 +111,9 @@ open class XAxisRenderer: AxisRendererBase } else if xAxis.labelPosition == .bottom { - drawLabels(context: context, pos: viewPortHandler.contentBottom + yOffset, anchor: CGPoint(x: 0.5, y: 0.0)) + let pos = viewPortHandler.contentBottom + yOffset + drawLabels(context: context, pos: pos, anchor: CGPoint(x: 0.5, y: 0.0)) + drawNameXAxis(context: context, nameRect: xAxis.axisRectBottom) } else if xAxis.labelPosition == .bottomInside { @@ -117,11 +121,45 @@ open class XAxisRenderer: AxisRendererBase } else { // BOTH SIDED - drawLabels(context: context, pos: viewPortHandler.contentTop - yOffset, anchor: CGPoint(x: 0.5, y: 1.0)) - drawLabels(context: context, pos: viewPortHandler.contentBottom + yOffset, anchor: CGPoint(x: 0.5, y: 0.0)) + // top + var pos = viewPortHandler.contentTop - yOffset + drawLabels(context: context, pos: pos, anchor: CGPoint(x: 0.5, y: 1.0)) + drawNameXAxis ( context: context, nameRect: xAxis.axisRectTop) + + // bottom + pos = viewPortHandler.contentBottom + yOffset + drawLabels(context: context, pos: pos, anchor: CGPoint(x: 0.5, y: 0.0)) + drawNameXAxis ( context: context, nameRect: xAxis.axisRectBottom) } } + /// draws the x-name + open func drawNameXAxis ( context: CGContext, nameRect: CGRect) + { + guard + let xAxis = self.axis as? XAxis + else { return } + + if xAxis.nameAxisEnabled == false + { + return + } + + #if os(OSX) + let paraStyle = NSParagraphStyle.default().mutableCopy() as! NSMutableParagraphStyle + #else + let paraStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle + #endif + + paraStyle.alignment = .center + let labelAttrs = [NSFontAttributeName: xAxis.nameAxisFont, + NSForegroundColorAttributeName: xAxis.labelTextColor, + NSParagraphStyleAttributeName: paraStyle] as [String : NSObject] + let text = xAxis.nameAxis + + text.draw(in: nameRect, withAttributes: labelAttrs) + } + fileprivate var _axisLineSegmentsBuffer = [CGPoint](repeating: CGPoint(), count: 2) open override func renderAxisLine(context: CGContext) @@ -191,12 +229,12 @@ open class XAxisRenderer: AxisRendererBase paraStyle.alignment = .center let labelAttrs = [NSFontAttributeName: xAxis.labelFont, - NSForegroundColorAttributeName: xAxis.labelTextColor, - NSParagraphStyleAttributeName: paraStyle] as [String : NSObject] + NSForegroundColorAttributeName: xAxis.labelTextColor, + NSParagraphStyleAttributeName: paraStyle] as [String : NSObject] let labelRotationAngleRadians = xAxis.labelRotationAngle * ChartUtils.Math.FDEG2RAD let centeringEnabled = xAxis.isCenterAxisLabelsEnabled - + let valueToPixelMatrix = transformer.valueToPixelMatrix var position = CGPoint(x: 0.0, y: 0.0) @@ -227,7 +265,7 @@ open class XAxisRenderer: AxisRendererBase if viewPortHandler.isInBoundsX(position.x) { let label = xAxis.valueFormatter?.stringForValue(xAxis.entries[i], axis: xAxis) ?? "" - + let labelns = label as NSString if xAxis.isAvoidFirstLastClippingEnabled @@ -440,44 +478,44 @@ open class XAxisRenderer: AxisRendererBase if limitLine.labelPosition == .rightTop { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: position.x + xOffset, - y: viewPortHandler.contentTop + yOffset), - align: .left, - attributes: [NSFontAttributeName: limitLine.valueFont, NSForegroundColorAttributeName: limitLine.valueTextColor]) + text: label, + point: CGPoint( + x: position.x + xOffset, + y: viewPortHandler.contentTop + yOffset), + align: .left, + attributes: [NSFontAttributeName: limitLine.valueFont, NSForegroundColorAttributeName: limitLine.valueTextColor]) } else if limitLine.labelPosition == .rightBottom { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: position.x + xOffset, - y: viewPortHandler.contentBottom - labelLineHeight - yOffset), - align: .left, - attributes: [NSFontAttributeName: limitLine.valueFont, NSForegroundColorAttributeName: limitLine.valueTextColor]) + text: label, + point: CGPoint( + x: position.x + xOffset, + y: viewPortHandler.contentBottom - labelLineHeight - yOffset), + align: .left, + attributes: [NSFontAttributeName: limitLine.valueFont, NSForegroundColorAttributeName: limitLine.valueTextColor]) } else if limitLine.labelPosition == .leftTop { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: position.x - xOffset, - y: viewPortHandler.contentTop + yOffset), - align: .right, - attributes: [NSFontAttributeName: limitLine.valueFont, NSForegroundColorAttributeName: limitLine.valueTextColor]) + text: label, + point: CGPoint( + x: position.x - xOffset, + y: viewPortHandler.contentTop + yOffset), + align: .right, + attributes: [NSFontAttributeName: limitLine.valueFont, NSForegroundColorAttributeName: limitLine.valueTextColor]) } else { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: position.x - xOffset, - y: viewPortHandler.contentBottom - labelLineHeight - yOffset), - align: .right, - attributes: [NSFontAttributeName: limitLine.valueFont, NSForegroundColorAttributeName: limitLine.valueTextColor]) + text: label, + point: CGPoint( + x: position.x - xOffset, + y: viewPortHandler.contentBottom - labelLineHeight - yOffset), + align: .right, + attributes: [NSFontAttributeName: limitLine.valueFont, NSForegroundColorAttributeName: limitLine.valueTextColor]) } } } - + } diff --git a/Source/Charts/Renderers/XAxisRendererHorizontalBarChart.swift b/Source/Charts/Renderers/XAxisRendererHorizontalBarChart.swift index 200fd2d9ce..d22c5b7490 100644 --- a/Source/Charts/Renderers/XAxisRendererHorizontalBarChart.swift +++ b/Source/Charts/Renderers/XAxisRendererHorizontalBarChart.swift @@ -65,7 +65,7 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer guard let xAxis = self.axis as? XAxis else { return } - + let longest = xAxis.getLongestLabel() as NSString let labelSize = longest.size(attributes: [NSFontAttributeName: xAxis.labelFont]) @@ -80,7 +80,7 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer xAxis.labelRotatedWidth = round(labelRotatedSize.width + xAxis.xOffset * 3.5) xAxis.labelRotatedHeight = round(labelRotatedSize.height) } - + open override func renderAxisLabels(context: CGContext) { guard @@ -97,7 +97,9 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer if xAxis.labelPosition == .top { - drawLabels(context: context, pos: viewPortHandler.contentRight + xoffset, anchor: CGPoint(x: 0.0, y: 0.5)) + let pos = viewPortHandler.contentRight + xoffset + drawLabels(context: context, pos: pos, anchor: CGPoint(x: 0.0, y: 0.5)) + drawNameXAxis ( context: context, nameRect: xAxis.axisRectLeft) } else if xAxis.labelPosition == .topInside { @@ -105,7 +107,9 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer } else if xAxis.labelPosition == .bottom { - drawLabels(context: context, pos: viewPortHandler.contentLeft - xoffset, anchor: CGPoint(x: 1.0, y: 0.5)) + let pos = viewPortHandler.contentLeft - xoffset + drawLabels(context: context, pos: pos, anchor: CGPoint(x: 1.0, y: 0.5)) + drawNameXAxis ( context: context, nameRect: xAxis.axisRectRight) } else if xAxis.labelPosition == .bottomInside { @@ -113,11 +117,66 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer } else { // BOTH SIDED - drawLabels(context: context, pos: viewPortHandler.contentRight + xoffset, anchor: CGPoint(x: 0.0, y: 0.5)) - drawLabels(context: context, pos: viewPortHandler.contentLeft - xoffset, anchor: CGPoint(x: 1.0, y: 0.5)) + // right + var pos = viewPortHandler.contentRight + xoffset + drawLabels(context: context, pos: pos, anchor: CGPoint(x: 0.0, y: 0.5)) + drawNameXAxis ( context: context, nameRect: xAxis.axisRectRight ) + + // left + pos = viewPortHandler.contentLeft - xoffset + drawLabels(context: context, pos: pos, anchor: CGPoint(x: 1.0, y: 0.5)) + drawNameXAxis ( context: context, nameRect: xAxis.axisRectLeft ) } } - + + /// draws the x-name + open override func drawNameXAxis ( context: CGContext, nameRect: CGRect) + { + guard + let xAxis = self.axis as? XAxis + else { return } + + if xAxis.nameAxisEnabled == false + { + return + } + + let midY = nameRect.midY + let xNamePos = nameRect.maxX + let text = xAxis.nameAxis + + #if os(OSX) + let paraStyle = NSParagraphStyle.default().mutableCopy() as! NSMutableParagraphStyle + #else + let paraStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle + #endif + + paraStyle.alignment = .center + + let labelAttrs = [NSFontAttributeName: xAxis.nameAxisFont, + NSForegroundColorAttributeName: xAxis.labelTextColor, + NSParagraphStyleAttributeName: paraStyle] as [String : NSObject] + + let labelRotationAngleRadians = -90.0 * ChartUtils.Math.FDEG2RAD + + // context.saveGState() + // context.beginPath() + // NSUIColor.black.setStroke() + // let bpath = NSBezierPath(rect: nameRect) + // bpath.stroke() + // context.strokePath() + // context.restoreGState() + + ChartUtils.drawText( + context: context, + text: text, + point: CGPoint(x: xNamePos, y: midY), + attributes: labelAttrs, + anchor: CGPoint(x: 1.0, y: 0.5), + angleRadians: labelRotationAngleRadians) + } + + /// draws the x-labels on the specified y-position open override func drawLabels(context: CGContext, pos: CGFloat, anchor: CGPoint) { @@ -297,7 +356,7 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer clippingRect.origin.y -= l.lineWidth / 2.0 clippingRect.size.height += l.lineWidth context.clip(to: clippingRect) - + position.x = 0.0 position.y = CGFloat(l.limit) position = position.applying(trans) @@ -332,42 +391,42 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer if l.labelPosition == .rightTop { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: viewPortHandler.contentRight - xOffset, - y: position.y - yOffset), - align: .right, - attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) + text: label, + point: CGPoint( + x: viewPortHandler.contentRight - xOffset, + y: position.y - yOffset), + align: .right, + attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) } else if l.labelPosition == .rightBottom { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: viewPortHandler.contentRight - xOffset, - y: position.y + yOffset - labelLineHeight), - align: .right, - attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) + text: label, + point: CGPoint( + x: viewPortHandler.contentRight - xOffset, + y: position.y + yOffset - labelLineHeight), + align: .right, + attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) } else if l.labelPosition == .leftTop { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: viewPortHandler.contentLeft + xOffset, - y: position.y - yOffset), - align: .left, - attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) + text: label, + point: CGPoint( + x: viewPortHandler.contentLeft + xOffset, + y: position.y - yOffset), + align: .left, + attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) } else { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: viewPortHandler.contentLeft + xOffset, - y: position.y + yOffset - labelLineHeight), - align: .left, - attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) + text: label, + point: CGPoint( + x: viewPortHandler.contentLeft + xOffset, + y: position.y + yOffset - labelLineHeight), + align: .left, + attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) } } } diff --git a/Source/Charts/Renderers/YAxisRenderer.swift b/Source/Charts/Renderers/YAxisRenderer.swift index fd9604e868..0001a20b3f 100644 --- a/Source/Charts/Renderers/YAxisRenderer.swift +++ b/Source/Charts/Renderers/YAxisRenderer.swift @@ -44,29 +44,31 @@ open class YAxisRenderer: AxisRendererBase let labelPosition = yAxis.labelPosition var xPos = CGFloat(0.0) - var textAlign: NSTextAlignment - if dependency == .left - { + switch dependency { + case .left, .left1: if labelPosition == .outsideChart { textAlign = .right - xPos = viewPortHandler.offsetLeft - xoffset + xPos = yAxis.axisRectLeft.maxX - xoffset + + drawNameYAxis( context: context, nameRect: yAxis.axisRectLeft) + drawYAxis(context: context, axisRect: yAxis.axisRectLeft, positions: transformedPositions()) } else { textAlign = .left xPos = viewPortHandler.offsetLeft + xoffset } - - } - else - { + case .right, .right1: if labelPosition == .outsideChart { textAlign = .left - xPos = viewPortHandler.contentRight + xoffset + xPos = yAxis.axisRectRight.minX + xoffset + + drawNameYAxis( context: context, nameRect: yAxis.axisRectRight) + drawYAxis(context: context, axisRect: yAxis.axisRectRight, positions: transformedPositions()) } else { @@ -83,47 +85,101 @@ open class YAxisRenderer: AxisRendererBase textAlign: textAlign) } - open override func renderAxisLine(context: CGContext) + + internal func drawYAxis(context: CGContext, axisRect: CGRect, positions: [CGPoint]) { guard - let yAxis = self.axis as? YAxis, - let viewPortHandler = self.viewPortHandler + let yAxis = self.axis as? YAxis else { return } - if !yAxis.isEnabled || !yAxis.drawAxisLineEnabled - { - return - } + let labelTextColor = yAxis.labelTextColor context.saveGState() + context.beginPath() + labelTextColor.setStroke() - context.setStrokeColor(yAxis.axisLineColor.cgColor) - context.setLineWidth(yAxis.axisLineWidth) - if yAxis.axisLineDashLengths != nil + let lengthStick : CGFloat = 5.0 + + if yAxis.axisDependency == .right || yAxis.axisDependency == .right1 { - context.setLineDash(phase: yAxis.axisLineDashPhase, lengths: yAxis.axisLineDashLengths) + context.move(to: CGPoint(x: axisRect.minX, y: axisRect.minY)) + context.addLine(to: CGPoint(x: axisRect.minX, y: axisRect.maxY)) + + let from = yAxis.isDrawBottomYLabelEntryEnabled ? 0 : 1 + let to = yAxis.isDrawTopYLabelEntryEnabled ? yAxis.entryCount : (yAxis.entryCount - 1) + + for i in stride(from: from, to: to, by: 1) + { + context.move(to: CGPoint(x: axisRect.minX, y: positions[i].y)) + context.addLine(to: CGPoint(x: axisRect.minX + lengthStick, y: positions[i].y )) + } } else { - context.setLineDash(phase: 0.0, lengths: []) + context.move(to: CGPoint(x: axisRect.maxX, y: axisRect.minY)) + context.addLine(to: CGPoint(x: axisRect.maxX, y: axisRect.maxY)) + + let from = yAxis.isDrawBottomYLabelEntryEnabled ? 0 : 1 + let to = yAxis.isDrawTopYLabelEntryEnabled ? yAxis.entryCount : (yAxis.entryCount - 1) + + for i in stride(from: from, to: to, by: 1) + { + context.move(to: CGPoint(x: axisRect.maxX, y: positions[i].y)) + context.addLine(to: CGPoint(x: axisRect.maxX - lengthStick, y: positions[i].y )) + } } + context.strokePath() + context.restoreGState() + } + + /// draws the name Yaxis + internal func drawNameYAxis( context: CGContext, nameRect: CGRect) + { + guard + let yAxis = self.axis as? YAxis + else { return } - if yAxis.axisDependency == .left + if yAxis.nameAxisEnabled == false { - context.beginPath() - context.move(to: CGPoint(x: viewPortHandler.contentLeft, y: viewPortHandler.contentTop)) - context.addLine(to: CGPoint(x: viewPortHandler.contentLeft, y: viewPortHandler.contentBottom)) - context.strokePath() + return + } + + let text = yAxis.nameAxis + + #if os(OSX) + let paraStyle = NSParagraphStyle.default().mutableCopy() as! NSMutableParagraphStyle + #else + let paraStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle + #endif + + paraStyle.alignment = .center + + let labelAttrs = [NSFontAttributeName: yAxis.nameAxisFont, + NSForegroundColorAttributeName: yAxis.labelTextColor, + NSParagraphStyleAttributeName: paraStyle] as [String : NSObject] + + let size = text.size(attributes: labelAttrs) + + var xNamePos : CGFloat = 0.0 + if yAxis.axisDependency == .right || yAxis.axisDependency == .right1 + { + xNamePos = nameRect.maxX } else { - context.beginPath() - context.move(to: CGPoint(x: viewPortHandler.contentRight, y: viewPortHandler.contentTop)) - context.addLine(to: CGPoint(x: viewPortHandler.contentRight, y: viewPortHandler.contentBottom)) - context.strokePath() + xNamePos = nameRect.minX + size.height } - context.restoreGState() + let midY = nameRect.midY + let labelRotationAngleRadians = -90.0 * ChartUtils.Math.FDEG2RAD + + ChartUtils.drawText( + context: context, + text: text, + point: CGPoint(x: xNamePos, y: midY), + attributes: labelAttrs, + anchor: CGPoint(x: 1.0, y: 0.5), + angleRadians: labelRotationAngleRadians) } /// draws the y-labels on the specified x-position @@ -157,6 +213,49 @@ open class YAxisRenderer: AxisRendererBase } } + open override func renderAxisLine(context: CGContext) + { + guard + let yAxis = self.axis as? YAxis, + let viewPortHandler = self.viewPortHandler + else { return } + + if !yAxis.isEnabled || !yAxis.drawAxisLineEnabled + { + return + } + + context.saveGState() + + context.setStrokeColor(yAxis.axisLineColor.cgColor) + context.setLineWidth(yAxis.axisLineWidth) + if yAxis.axisLineDashLengths != nil + { + context.setLineDash(phase: yAxis.axisLineDashPhase, lengths: yAxis.axisLineDashLengths) + } + else + { + context.setLineDash(phase: 0.0, lengths: []) + } + + if yAxis.axisDependency == .left || yAxis.axisDependency == .left1 + { + context.beginPath() + context.move(to: CGPoint(x: viewPortHandler.contentLeft, y: viewPortHandler.contentTop)) + context.addLine(to: CGPoint(x: viewPortHandler.contentLeft, y: viewPortHandler.contentBottom)) + context.strokePath() + } + else + { + context.beginPath() + context.move(to: CGPoint(x: viewPortHandler.contentRight, y: viewPortHandler.contentTop)) + context.addLine(to: CGPoint(x: viewPortHandler.contentRight, y: viewPortHandler.contentBottom)) + context.strokePath() + } + + context.restoreGState() + } + open override func renderGridLines(context: CGContext) { guard let @@ -197,7 +296,7 @@ open class YAxisRenderer: AxisRendererBase drawGridLine(context: context, position: positions[i]) } } - + if yAxis.drawZeroLineEnabled { // draw zero line @@ -244,12 +343,12 @@ open class YAxisRenderer: AxisRendererBase { positions.append(CGPoint(x: 0.0, y: entries[i])) } - + transformer.pointValuesToPixel(&positions) return positions } - + /// Draws the zero line at the specified position. open func drawZeroLine(context: CGContext) { @@ -267,12 +366,12 @@ open class YAxisRenderer: AxisRendererBase clippingRect.origin.y -= yAxis.zeroLineWidth / 2.0 clippingRect.size.height += yAxis.zeroLineWidth context.clip(to: clippingRect) - + context.setStrokeColor(zeroLineColor.cgColor) context.setLineWidth(yAxis.zeroLineWidth) let pos = transformer.pixelForValues(x: 0.0, y: 0.0) - + if yAxis.zeroLineDashLengths != nil { context.setLineDash(phase: yAxis.zeroLineDashPhase, lengths: yAxis.zeroLineDashLengths!) @@ -359,42 +458,42 @@ open class YAxisRenderer: AxisRendererBase if l.labelPosition == .rightTop { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: viewPortHandler.contentRight - xOffset, - y: position.y - yOffset), - align: .right, - attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) + text: label, + point: CGPoint( + x: viewPortHandler.contentRight - xOffset, + y: position.y - yOffset), + align: .right, + attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) } else if l.labelPosition == .rightBottom { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: viewPortHandler.contentRight - xOffset, - y: position.y + yOffset - labelLineHeight), - align: .right, - attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) + text: label, + point: CGPoint( + x: viewPortHandler.contentRight - xOffset, + y: position.y + yOffset - labelLineHeight), + align: .right, + attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) } else if l.labelPosition == .leftTop { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: viewPortHandler.contentLeft + xOffset, - y: position.y - yOffset), - align: .left, - attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) + text: label, + point: CGPoint( + x: viewPortHandler.contentLeft + xOffset, + y: position.y - yOffset), + align: .left, + attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) } else { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: viewPortHandler.contentLeft + xOffset, - y: position.y + yOffset - labelLineHeight), - align: .left, - attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) + text: label, + point: CGPoint( + x: viewPortHandler.contentLeft + xOffset, + y: position.y + yOffset - labelLineHeight), + align: .left, + attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) } } } diff --git a/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift b/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift index 621d6dd6ed..039fb41545 100644 --- a/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift +++ b/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift @@ -22,7 +22,7 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer { super.init(viewPortHandler: viewPortHandler, yAxis: yAxis, transformer: transformer) } - + /// Computes the axis values. open override func computeAxis(min: Double, max: Double, inverted: Bool) { @@ -53,7 +53,7 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer computeAxisValues(min: min, max: max) } - + /// draws the y-axis labels to the screen open override func renderAxisLabels(context: CGContext) { @@ -68,33 +68,39 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer } let lineHeight = yAxis.labelFont.lineHeight - let baseYOffset: CGFloat = 2.5 + let baseYOffset: CGFloat = 5 let dependency = yAxis.axisDependency let labelPosition = yAxis.labelPosition var yPos: CGFloat = 0.0 - if dependency == .left - { + switch dependency { + case .left, .left1: + if labelPosition == .outsideChart { - yPos = viewPortHandler.contentTop - baseYOffset + yPos = yAxis.axisRectTop.maxY - baseYOffset + + drawNameYAxis( context: context, nameRect: yAxis.axisRectTop) + drawYAxis(context: context, axisRect: yAxis.axisRectTop, positions: transformedPositions()) } else { yPos = viewPortHandler.contentTop - baseYOffset } - } - else - { + + case .right, .right1: if labelPosition == .outsideChart { - yPos = viewPortHandler.contentBottom + lineHeight + baseYOffset + yPos = yAxis.axisRectBottom.maxY - lineHeight + + drawNameYAxis( context: context, nameRect: yAxis.axisRectBottom) + drawYAxis(context: context, axisRect: yAxis.axisRectBottom, positions: transformedPositions()) } else { - yPos = viewPortHandler.contentBottom + lineHeight + baseYOffset + yPos = viewPortHandler.contentBottom + lineHeight } } @@ -109,6 +115,100 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer offset: yAxis.yOffset) } + internal override func drawYAxis(context: CGContext, axisRect: CGRect, positions: [CGPoint]) + { + guard + let yAxis = self.axis as? YAxis + else { return } + + let labelTextColor = yAxis.labelTextColor + + context.saveGState() + context.beginPath() + labelTextColor.setStroke() + + let lengthStick : CGFloat = 5.0 + + if yAxis.axisDependency == .right || yAxis.axisDependency == .right1 + { + context.move(to: CGPoint(x: axisRect.minX, y: axisRect.minY)) + context.addLine(to: CGPoint(x: axisRect.maxX, y: axisRect.minY)) + + let from = yAxis.isDrawBottomYLabelEntryEnabled ? 0 : 1 + let to = yAxis.isDrawTopYLabelEntryEnabled ? yAxis.entryCount : (yAxis.entryCount - 1) + + for i in stride(from: from, to: to, by: 1) + { + context.move(to: CGPoint(x: positions[i].x, y: axisRect.minY)) + context.addLine(to: CGPoint(x: positions[i].x, y: axisRect.minY + lengthStick)) + } + } + else + { + context.move(to: CGPoint(x: axisRect.minX, y: axisRect.maxY)) + context.addLine(to: CGPoint(x: axisRect.maxX, y: axisRect.maxY)) + + let from = yAxis.isDrawBottomYLabelEntryEnabled ? 0 : 1 + let to = yAxis.isDrawTopYLabelEntryEnabled ? yAxis.entryCount : (yAxis.entryCount - 1) + + for i in stride(from: from, to: to, by: 1) + { + context.move(to: CGPoint(x: positions[i].x, y: axisRect.maxY)) + context.addLine(to: CGPoint(x: positions[i].x, y: axisRect.maxY - lengthStick)) + } + } + + context.strokePath() + context.restoreGState() + } + + /// draws the x-name + open override func drawNameYAxis ( context: CGContext, nameRect: CGRect) + { + guard + let yAxis = self.axis as? YAxis + else { return } + + if yAxis.nameAxisEnabled == false + { + return + } + + let text = yAxis.nameAxis + + #if os(OSX) + let paraStyle = NSParagraphStyle.default().mutableCopy() as! NSMutableParagraphStyle + #else + let paraStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle + #endif + + paraStyle.alignment = .center + let labelAttrs = [NSFontAttributeName: yAxis.nameAxisFont, + NSForegroundColorAttributeName: yAxis.labelTextColor, + NSParagraphStyleAttributeName: paraStyle] as [String : NSObject] + + let size = text.size(attributes: labelAttrs) + + var yNamePos : CGFloat = 0.0 + if yAxis.axisDependency == .right || yAxis.axisDependency == .right1 + { + yNamePos = nameRect.maxY - size.height + } + else + { + yNamePos = nameRect.minY + } + + let midX = nameRect.midX + + ChartUtils.drawText( + context: context, + text: text, + point: CGPoint(x: midX, y: yNamePos), + align: .center, + attributes: labelAttrs) + } + open override func renderAxisLine(context: CGContext) { guard @@ -133,8 +233,8 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer { context.setLineDash(phase: 0.0, lengths: []) } - - if yAxis.axisDependency == .left + + if yAxis.axisDependency == .left || yAxis.axisDependency == .left1 { context.beginPath() context.move(to: CGPoint(x: viewPortHandler.contentLeft, y: viewPortHandler.contentTop)) @@ -146,11 +246,12 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer context.beginPath() context.move(to: CGPoint(x: viewPortHandler.contentLeft, y: viewPortHandler.contentBottom)) context.addLine(to: CGPoint(x: viewPortHandler.contentRight, y: viewPortHandler.contentBottom)) - context.strokePath() } + context.strokePath() + } context.restoreGState() } - + /// draws the y-labels on the specified x-position open func drawYLabels( context: CGContext, @@ -274,7 +375,7 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer else { return } var limitLines = yAxis.limitLines - + if limitLines.count <= 0 { return @@ -297,7 +398,7 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer context.saveGState() defer { context.restoreGState() } - + var clippingRect = viewPortHandler.contentRect clippingRect.origin.x -= l.lineWidth / 2.0 clippingRect.size.width += l.lineWidth @@ -325,7 +426,7 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer context.strokePath() let label = l.label - + // if drawing the limit-value label is enabled if l.drawLabelEnabled && label.characters.count > 0 { @@ -333,46 +434,46 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer let xOffset: CGFloat = l.lineWidth + l.xOffset let yOffset: CGFloat = 2.0 + l.yOffset - + if l.labelPosition == .rightTop { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: position.x + xOffset, - y: viewPortHandler.contentTop + yOffset), - align: .left, - attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) + text: label, + point: CGPoint( + x: position.x + xOffset, + y: viewPortHandler.contentTop + yOffset), + align: .left, + attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) } else if l.labelPosition == .rightBottom { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: position.x + xOffset, - y: viewPortHandler.contentBottom - labelLineHeight - yOffset), - align: .left, - attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) + text: label, + point: CGPoint( + x: position.x + xOffset, + y: viewPortHandler.contentBottom - labelLineHeight - yOffset), + align: .left, + attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) } else if l.labelPosition == .leftTop { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: position.x - xOffset, - y: viewPortHandler.contentTop + yOffset), - align: .right, - attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) + text: label, + point: CGPoint( + x: position.x - xOffset, + y: viewPortHandler.contentTop + yOffset), + align: .right, + attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) } else { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: position.x - xOffset, - y: viewPortHandler.contentBottom - labelLineHeight - yOffset), - align: .right, - attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) + text: label, + point: CGPoint( + x: position.x - xOffset, + y: viewPortHandler.contentBottom - labelLineHeight - yOffset), + align: .right, + attributes: [NSFontAttributeName: l.valueFont, NSForegroundColorAttributeName: l.valueTextColor]) } } } From 1c1022edf3515b83c77797470f9ecad300660155 Mon Sep 17 00:00:00 2001 From: thierryH91200 Date: Fri, 26 May 2017 09:13:19 +0200 Subject: [PATCH 2/8] multi axis and Support for: extraTopOffset, extraBottomOffset, extraLeftOffset, extraRightOffset --- .../Charts/Charts/BarLineChartViewBase.swift | 80 ++++++++++--------- .../Charts/HorizontalBarChartView.swift | 75 +++++++++-------- 2 files changed, 79 insertions(+), 76 deletions(-) diff --git a/Source/Charts/Charts/BarLineChartViewBase.swift b/Source/Charts/Charts/BarLineChartViewBase.swift index cf04e10321..78367cfe59 100644 --- a/Source/Charts/Charts/BarLineChartViewBase.swift +++ b/Source/Charts/Charts/BarLineChartViewBase.swift @@ -483,10 +483,16 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD offsetRight: &offsetRightLegend, offsetBottom: &offsetBottomLegend) + offsetTop += self.extraTopOffset + offsetRight += self.extraRightOffset + offsetBottom += self.extraBottomOffset + offsetLeft += self.extraLeftOffset + let axisRectHeight = viewPortHandler.contentHeight let axisRectTop = viewPortHandler.contentTop let lineWidth : CGFloat = 1.0 let stick : CGFloat = 5.0 + var nameAxisHeight : CGFloat = 0.0 // offsets for y-labels // Space from left to right @@ -497,72 +503,75 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD // 5 pixels : stick // n pixels : label width // n pixels : name height - offsetLeft = offsetLeftLegend + leftAxis.xOffset + offsetLeft += offsetLeftLegend + var offsetLeftTmp = offsetLeft if leftAxis1.needsOffset { offsetLeft += lineWidth + stick + leftAxis1.requiredSize().width if leftAxis1.nameAxisEnabled { let nameAxisHeight = leftAxis1.nameAxis.size(attributes: [NSFontAttributeName: leftAxis1.nameAxisFont]).height - let width = lineWidth + stick + leftAxis1.requiredSize().width + nameAxisHeight - offsetLeft += nameAxisHeight - leftAxis1.axisRectLeft = CGRect(x: offsetLeftLegend, - y: axisRectTop, - width: width, - height: axisRectHeight) } + let width = offsetLeft - offsetLeftTmp + leftAxis1.axisRectLeft = CGRect(x: offsetLeftTmp, + y: axisRectTop, + width: width, + height: axisRectHeight) } + offsetLeftTmp = offsetLeft if leftAxis.needsOffset { offsetLeft += lineWidth + stick + leftAxis.requiredSize().width if leftAxis.nameAxisEnabled { - let nameAxisHeight = leftAxis.nameAxis.size(attributes: [NSFontAttributeName: leftAxis.nameAxisFont]).height - let width = lineWidth + stick + nameAxisHeight + leftAxis.requiredSize().width - + nameAxisHeight = leftAxis.nameAxis.size(attributes: [NSFontAttributeName: leftAxis.nameAxisFont]).height offsetLeft += nameAxisHeight - leftAxis.axisRectLeft = CGRect(x: offsetLeftLegend + leftAxis1.axisRectLeft.width, - y: axisRectTop, - width: width, - height:axisRectHeight) } + let width = offsetLeft - offsetLeftTmp + leftAxis.axisRectLeft = CGRect(x: offsetLeftTmp, + y: axisRectTop, + width: width, + height:axisRectHeight) } + offsetLeft += leftAxis.xOffset // Space from right to left - offsetRight = offsetRightLegend + rightAxis.xOffset + offsetRight += offsetRightLegend + var offsetRightTmp = offsetRight if rightAxis1.needsOffset { offsetRight += lineWidth + stick + rightAxis1.requiredSize().width if rightAxis1.nameAxisEnabled { - let nameAxisHeight = rightAxis1.nameAxis.size(attributes: [NSFontAttributeName: rightAxis1.nameAxisFont]).height - let width = lineWidth + stick + nameAxisHeight + rightAxis1.requiredSize().width - + nameAxisHeight = rightAxis1.nameAxis.size(attributes: [NSFontAttributeName: rightAxis1.nameAxisFont]).height offsetRight += nameAxisHeight - rightAxis1.axisRectRight = CGRect(x: viewPortHandler.chartWidth - offsetRightLegend - width, - y: axisRectTop, - width: width, - height: axisRectHeight) } + let width = offsetRight - offsetRightTmp + rightAxis1.axisRectRight = CGRect(x: viewPortHandler.chartWidth - offsetRight, + y: axisRectTop, + width: width, + height: axisRectHeight) + } + offsetRightTmp = offsetRight if rightAxis.needsOffset { offsetRight += lineWidth + stick + rightAxis.requiredSize().width if rightAxis.nameAxisEnabled { - let nameAxisHeight = rightAxis.nameAxis.size(attributes: [NSFontAttributeName: rightAxis.nameAxisFont]).height - let width = lineWidth + stick + nameAxisHeight + rightAxis.requiredSize().width - + nameAxisHeight = rightAxis.nameAxis.size(attributes: [NSFontAttributeName: rightAxis.nameAxisFont]).height offsetRight += nameAxisHeight - rightAxis.axisRectRight = CGRect(x: viewPortHandler.chartWidth - offsetRightLegend - rightAxis1.axisRectRight.width - width, - y: viewPortHandler.contentTop, - width: width, - height: axisRectHeight) } + let width = offsetRight - offsetRightTmp + rightAxis.axisRectRight = CGRect(x: viewPortHandler.chartWidth - offsetRight, + y: viewPortHandler.contentTop, + width: width, + height: axisRectHeight) } + offsetRight += rightAxis.xOffset if xAxis.isEnabled && xAxis.isDrawLabelsEnabled { @@ -582,7 +591,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD // offsets for x-labels if xAxis.labelPosition == .bottom { - offsetBottom = offsetBottomLegend + xlabelheight + namexAxisHeight + offsetBottom += offsetBottomLegend + xlabelheight + namexAxisHeight xAxis.axisRectBottom = CGRect(x: nameAxisRectLeft, y: viewPortHandler.chartHeight - offsetBottomLegend - namexAxisHeight, width: nameAxisRectWidth, @@ -590,7 +599,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD } else if xAxis.labelPosition == .top { - offsetTop = offsetTopLegend + xlabelheight + namexAxisHeight + offsetTop += offsetTopLegend + xlabelheight + namexAxisHeight xAxis.axisRectTop = CGRect(x: nameAxisRectLeft, y: offsetTop - namexAxisHeight - xlabelheight, width: nameAxisRectWidth, @@ -598,13 +607,13 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD } else if xAxis.labelPosition == .bothSided { - offsetBottom = offsetBottomLegend + xlabelheight + namexAxisHeight + offsetBottom += offsetBottomLegend + xlabelheight + namexAxisHeight xAxis.axisRectBottom = CGRect(x: nameAxisRectLeft, y: viewPortHandler.chartHeight - offsetBottomLegend - namexAxisHeight, width: nameAxisRectWidth, height: namexAxisHeight) - offsetTop = offsetTopLegend + xlabelheight + namexAxisHeight + offsetTop += offsetTopLegend + xlabelheight + namexAxisHeight xAxis.axisRectTop = CGRect(x: nameAxisRectLeft, y: offsetTopLegend, width: nameAxisRectWidth, @@ -612,11 +621,6 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD } } - offsetTop += self.extraTopOffset - offsetRight += self.extraRightOffset - offsetBottom += self.extraBottomOffset - offsetLeft += self.extraLeftOffset - _viewPortHandler.restrainViewPort( offsetLeft: max(self.minOffset, offsetLeft), offsetTop: max(self.minOffset, offsetTop), diff --git a/Source/Charts/Charts/HorizontalBarChartView.swift b/Source/Charts/Charts/HorizontalBarChartView.swift index 7da8b86aaf..fef79a915b 100644 --- a/Source/Charts/Charts/HorizontalBarChartView.swift +++ b/Source/Charts/Charts/HorizontalBarChartView.swift @@ -49,6 +49,11 @@ open class HorizontalBarChartView: BarChartView offsetTop: CGFloat = 0.0, offsetBottom: CGFloat = 0.0 + offsetTop += self.extraTopOffset + offsetRight += self.extraRightOffset + offsetBottom += self.extraBottomOffset + offsetLeft += self.extraLeftOffset + var offsetLeftLegend = CGFloat(0.0) var offsetRightLegend = CGFloat(0.0) var offsetTopLegend = CGFloat(0.0) @@ -74,77 +79,76 @@ open class HorizontalBarChartView: BarChartView // 5 pixels : stick // n pixels : label width // n pixels : name height - offsetTop = offsetTopLegend + leftAxis.yOffset + offsetTop = offsetTopLegend + var offsetTopTmp = offsetTop if leftAxis1.needsOffset { - offsetTop += leftAxis1.getRequiredHeightSpace() + offsetTop += lineWidth + stick + leftAxis1.getRequiredHeightSpace() if leftAxis1.nameAxisEnabled { let nameAxisHeight = leftAxis.nameAxis.size(attributes: [NSFontAttributeName: leftAxis.nameAxisFont]).height - let height = lineWidth + stick + nameAxisHeight + leftAxis1.getRequiredHeightSpace() - - offsetTop += height - leftAxis.axisRectTop = CGRect(x: axisRectLeft, - y: offsetTop - offsetTopLegend, - width: axisRectWidth, - height: height) + offsetTop += nameAxisHeight } + let height = offsetTop - offsetTopTmp + leftAxis1.axisRectTop = CGRect(x: axisRectLeft, + y: offsetTopTmp, + width: axisRectWidth, + height: height) } + offsetTopTmp = offsetTop if leftAxis.needsOffset { - offsetTop += leftAxis.getRequiredHeightSpace() + offsetTop += lineWidth + stick + leftAxis.getRequiredHeightSpace() if leftAxis.nameAxisEnabled { let nameAxisHeight = leftAxis.nameAxis.size(attributes: [NSFontAttributeName: leftAxis.nameAxisFont]).height - let height = lineWidth + stick + nameAxisHeight + leftAxis.getRequiredHeightSpace() - - offsetTop += height - leftAxis.axisRectTop = CGRect(x: axisRectLeft, - y: offsetTop - height, - width: axisRectWidth, - height: height) + offsetTop += nameAxisHeight } + let height = offsetTop - offsetTopTmp + leftAxis.axisRectTop = CGRect(x: axisRectLeft, + y: offsetTopTmp, + width: axisRectWidth, + height: height) } offsetTop += leftAxis.yOffset // Space from bottom to top - offsetBottom = offsetBottomLegend + rightAxis.yOffset + offsetBottom = offsetBottomLegend + var offsetBottomTmp = offsetBottom if rightAxis1.needsOffset { offsetBottom += rightAxis1.getRequiredHeightSpace() if rightAxis1.nameAxisEnabled { let nameAxisHeight = rightAxis1.nameAxis.size(attributes: [NSFontAttributeName: rightAxis1.nameAxisFont]).height - let height = lineWidth + stick + nameAxisHeight + rightAxis1.getRequiredHeightSpace() - - offsetBottom += height - rightAxis1.axisRectBottom = CGRect(x: axisRectLeft, - y: viewPortHandler.chartHeight - offsetBottom + height, - width: axisRectWidth, - height: height) + offsetBottom += nameAxisHeight } + let height = offsetBottom - offsetBottomTmp + rightAxis1.axisRectBottom = CGRect(x: axisRectLeft, + y: viewPortHandler.chartHeight - offsetBottom, + width: axisRectWidth, + height: height) } + offsetBottomTmp = offsetBottom if rightAxis.needsOffset { offsetBottom += rightAxis.getRequiredHeightSpace() if rightAxis.nameAxisEnabled { let nameAxisHeight = rightAxis.nameAxis.size(attributes: [NSFontAttributeName: rightAxis.nameAxisFont]).height - let height = lineWidth + stick + nameAxisHeight + rightAxis.getRequiredHeightSpace() - - offsetBottom += height - rightAxis.axisRectBottom = CGRect(x: axisRectLeft, - y: viewPortHandler.chartHeight - offsetBottom, - width: axisRectWidth, - height: height) + offsetBottom += nameAxisHeight } + let height = offsetBottom - offsetBottomTmp + rightAxis.axisRectBottom = CGRect(x: axisRectLeft, + y: viewPortHandler.chartHeight - offsetBottom, + width: axisRectWidth, + height: height) } offsetBottom += leftAxis.yOffset let xlabelwidth = _xAxis.labelRotatedWidth - if _xAxis.isEnabled { var namexAxisHeight = CGFloat(0.0) @@ -188,11 +192,6 @@ open class HorizontalBarChartView: BarChartView } } - offsetTop += self.extraTopOffset - offsetRight += self.extraRightOffset - offsetBottom += self.extraBottomOffset - offsetLeft += self.extraLeftOffset - _viewPortHandler.restrainViewPort( offsetLeft: max(self.minOffset, offsetLeft), offsetTop: max(self.minOffset, offsetTop), From 1f852b37b2a9a81d48d5a1836d9b27b5ae3f04ca Mon Sep 17 00:00:00 2001 From: thierryH91200 Date: Tue, 30 May 2017 18:19:55 +0200 Subject: [PATCH 3/8] update for axis secondary --- .../Implementations/Standard/ChartData.swift | 237 ++++++++++++------ 1 file changed, 156 insertions(+), 81 deletions(-) diff --git a/Source/Charts/Data/Implementations/Standard/ChartData.swift b/Source/Charts/Data/Implementations/Standard/ChartData.swift index 5d64efeb84..9a2051208c 100644 --- a/Source/Charts/Data/Implementations/Standard/ChartData.swift +++ b/Source/Charts/Data/Implementations/Standard/ChartData.swift @@ -17,10 +17,17 @@ open class ChartData: NSObject internal var _yMin: Double = Double.greatestFiniteMagnitude internal var _xMax: Double = -Double.greatestFiniteMagnitude internal var _xMin: Double = Double.greatestFiniteMagnitude + internal var _leftAxisMax: Double = -Double.greatestFiniteMagnitude internal var _leftAxisMin: Double = Double.greatestFiniteMagnitude + internal var _leftAxisMax1: Double = -Double.greatestFiniteMagnitude + internal var _leftAxisMin1: Double = Double.greatestFiniteMagnitude + internal var _rightAxisMax: Double = -Double.greatestFiniteMagnitude internal var _rightAxisMin: Double = Double.greatestFiniteMagnitude + internal var _rightAxisMax1: Double = -Double.greatestFiniteMagnitude + internal var _rightAxisMin1: Double = Double.greatestFiniteMagnitude + internal var _dataSets = [IChartDataSet]() @@ -83,11 +90,17 @@ open class ChartData: NSObject _leftAxisMax = -Double.greatestFiniteMagnitude _leftAxisMin = Double.greatestFiniteMagnitude + _leftAxisMax1 = -Double.greatestFiniteMagnitude + _leftAxisMin1 = Double.greatestFiniteMagnitude + _rightAxisMax = -Double.greatestFiniteMagnitude _rightAxisMin = Double.greatestFiniteMagnitude + _rightAxisMax1 = -Double.greatestFiniteMagnitude + _rightAxisMin1 = Double.greatestFiniteMagnitude + // left axis - let firstLeft = getFirstLeft(dataSets: dataSets) + let firstLeft = getFirstDataSet(dataSets: dataSets, axisDependency: .left) if firstLeft !== nil { @@ -111,9 +124,32 @@ open class ChartData: NSObject } } - // right axis - let firstRight = getFirstRight(dataSets: dataSets) + // left1 axis + let firstLeft1 = getFirstDataSet(dataSets: dataSets, axisDependency: .left1) + if firstLeft1 !== nil + { + _leftAxisMax1 = firstLeft1!.yMax + _leftAxisMin1 = firstLeft1!.yMin + + for dataSet in _dataSets + { + if dataSet.axisDependency == .left1 + { + if dataSet.yMin < _leftAxisMin1 + { + _leftAxisMin1 = dataSet.yMin + } + + if dataSet.yMax > _leftAxisMax1 + { + _leftAxisMax1 = dataSet.yMax + } + } + } + } + // right axis + let firstRight = getFirstDataSet(dataSets: dataSets, axisDependency: .right) if firstRight !== nil { _rightAxisMax = firstRight!.yMax @@ -135,6 +171,30 @@ open class ChartData: NSObject } } } + + // right1 axis + let firstRight1 = getFirstDataSet(dataSets: dataSets, axisDependency: .right1) + if firstRight1 !== nil + { + _rightAxisMax1 = firstRight1!.yMax + _rightAxisMin1 = firstRight1!.yMin + + for dataSet in _dataSets + { + if dataSet.axisDependency == .right1 + { + if dataSet.yMin < _rightAxisMin1 + { + _rightAxisMin1 = dataSet.yMin + } + + if dataSet.yMax > _rightAxisMax + { + _rightAxisMax1 = dataSet.yMax + } + } + } + } } /// Adjusts the current minimum and maximum values based on the provided Entry object. @@ -160,8 +220,9 @@ open class ChartData: NSObject _xMin = e.x } - if axis == .left + switch axis { + case .left: if _leftAxisMax < e.y { _leftAxisMax = e.y @@ -171,9 +232,18 @@ open class ChartData: NSObject { _leftAxisMin = e.y } - } - else - { + + case .left1: + if _leftAxisMax1 < e.y + { + _leftAxisMax1 = e.y + } + + if _leftAxisMin1 > e.y + { + _leftAxisMin1 = e.y + } + case .right: if _rightAxisMax < e.y { _rightAxisMax = e.y @@ -183,6 +253,16 @@ open class ChartData: NSObject { _rightAxisMin = e.y } + case .right1: + if _rightAxisMax1 < e.y + { + _rightAxisMax1 = e.y + } + + if _rightAxisMin1 > e.y + { + _rightAxisMin1 = e.y + } } } @@ -209,8 +289,8 @@ open class ChartData: NSObject _xMin = d.xMin } - if d.axisDependency == .left - { + switch d.axisDependency { + case .left: if _leftAxisMax < d.yMax { _leftAxisMax = d.yMax @@ -220,9 +300,18 @@ open class ChartData: NSObject { _leftAxisMin = d.yMin } - } - else - { + case .left1: + + if _leftAxisMax1 < d.yMax + { + _leftAxisMax1 = d.yMax + } + + if _leftAxisMin1 > d.yMin + { + _leftAxisMin1 = d.yMin + } + case .right: if _rightAxisMax < d.yMax { _rightAxisMax = d.yMax @@ -232,6 +321,16 @@ open class ChartData: NSObject { _rightAxisMin = d.yMin } + case .right1: + if _rightAxisMax1 < d.yMax + { + _rightAxisMax1 = d.yMax + } + + if _rightAxisMin1 > d.yMin + { + _rightAxisMin1 = d.yMin + } } } @@ -255,28 +354,23 @@ open class ChartData: NSObject open func getYMin(axis: YAxis.AxisDependency) -> Double { - if axis == .left - { - if _leftAxisMin == Double.greatestFiniteMagnitude - { - return _rightAxisMin - } - else - { - return _leftAxisMin - } - } - else + let arrayYMin = [_leftAxisMin, _leftAxisMin1, _rightAxisMin, _rightAxisMin1] + let filteredArray = arrayYMin.filter() { $0 != Double.greatestFiniteMagnitude} + let axisMin = filteredArray.min()! + var axisYMin = 0.0 + + switch axis { - if _rightAxisMin == Double.greatestFiniteMagnitude - { - return _leftAxisMin - } - else - { - return _rightAxisMin - } + case .left: + axisYMin = _leftAxisMin == Double.greatestFiniteMagnitude ? axisMin : _leftAxisMin + case .left1: + axisYMin = _leftAxisMin1 == Double.greatestFiniteMagnitude ? axisMin : _leftAxisMin1 + case .right: + axisYMin = _rightAxisMin == Double.greatestFiniteMagnitude ? axisMin : _rightAxisMin + case .right1: + axisYMin = _rightAxisMin1 == Double.greatestFiniteMagnitude ? axisMin : _rightAxisMin1 } + return axisYMin } /// - returns: The greatest y-value the data object contains. @@ -293,28 +387,23 @@ open class ChartData: NSObject open func getYMax(axis: YAxis.AxisDependency) -> Double { - if axis == .left - { - if _leftAxisMax == -Double.greatestFiniteMagnitude - { - return _rightAxisMax - } - else - { - return _leftAxisMax - } - } - else + let arrayYMax = [_leftAxisMax, _leftAxisMax1, _rightAxisMax, _rightAxisMax1] + let filteredArray = arrayYMax.filter() { $0 != -Double.greatestFiniteMagnitude} + let axisMax = filteredArray.max()! + var axisYMax = 0.0 + + switch axis { - if _rightAxisMax == -Double.greatestFiniteMagnitude - { - return _leftAxisMax - } - else - { - return _rightAxisMax - } + case .left: + axisYMax = _leftAxisMax == -Double.greatestFiniteMagnitude ? axisMax : _leftAxisMax + case .left1: + axisYMax = _leftAxisMax1 == -Double.greatestFiniteMagnitude ? axisMax : _leftAxisMax1 + case .right: + axisYMax = _rightAxisMax == -Double.greatestFiniteMagnitude ? axisMax : _rightAxisMin + case .right1: + axisYMax = _rightAxisMax1 == -Double.greatestFiniteMagnitude ? axisMax : _rightAxisMax1 } + return axisYMax } /// - returns: The minimum x-value the data object contains. @@ -330,7 +419,7 @@ open class ChartData: NSObject /// - returns: All DataSet objects this ChartData object holds. open var dataSets: [IChartDataSet] - { + { get { return _dataSets @@ -343,7 +432,7 @@ open class ChartData: NSObject } /// Retrieve the index of a ChartDataSet with a specific label from the ChartData. Search can be case sensitive or not. - /// + /// /// **IMPORTANT: This method does calculations at runtime, do not over-use in performance critical situations.** /// /// - parameter dataSets: the DataSet array to search @@ -454,7 +543,7 @@ open class ChartData: NSObject /// Also recalculates all minimum and maximum values. /// /// - returns: `true` if a DataSet was removed, `false` ifno DataSet could be removed. - @discardableResult open func removeDataSet(_ dataSet: IChartDataSet!) -> Bool + open func removeDataSet(_ dataSet: IChartDataSet!) -> Bool { if dataSet === nil { @@ -472,11 +561,11 @@ open class ChartData: NSObject return false } - /// Removes the DataSet at the given index in the DataSet array from the data object. - /// Also recalculates all minimum and maximum values. + /// Removes the DataSet at the given index in the DataSet array from the data object. + /// Also recalculates all minimum and maximum values. /// /// - returns: `true` if a DataSet was removed, `false` ifno DataSet could be removed. - @discardableResult open func removeDataSetByIndex(_ index: Int) -> Bool + open func removeDataSetByIndex(_ index: Int) -> Bool { if index >= _dataSets.count || index < 0 { @@ -508,7 +597,7 @@ open class ChartData: NSObject } /// Removes the given Entry object from the DataSet at the specified index. - @discardableResult open func removeEntry(_ entry: ChartDataEntry, dataSetIndex: Int) -> Bool + open func removeEntry(_ entry: ChartDataEntry, dataSetIndex: Int) -> Bool { // entry outofbounds if dataSetIndex >= _dataSets.count @@ -528,9 +617,9 @@ open class ChartData: NSObject } /// Removes the Entry object closest to the given xIndex from the ChartDataSet at the - /// specified index. + /// specified index. /// - returns: `true` if an entry was removed, `false` ifno Entry was found that meets the specified requirements. - @discardableResult open func removeEntry(xValue: Double, dataSetIndex: Int) -> Bool + open func removeEntry(xValue: Double, dataSetIndex: Int) -> Bool { if dataSetIndex >= _dataSets.count { @@ -565,7 +654,7 @@ open class ChartData: NSObject return nil } - + /// - returns: The index of the provided DataSet in the DataSet array of this data object, or -1 if it does not exist. open func indexOfDataSet(_ dataSet: IChartDataSet) -> Int { @@ -580,26 +669,12 @@ open class ChartData: NSObject return -1 } - /// - returns: The first DataSet from the datasets-array that has it's dependency on the left axis. Returns null if no DataSet with left dependency could be found. - open func getFirstLeft(dataSets: [IChartDataSet]) -> IChartDataSet? - { - for dataSet in dataSets - { - if dataSet.axisDependency == .left - { - return dataSet - } - } - - return nil - } - /// - returns: The first DataSet from the datasets-array that has it's dependency on the right axis. Returns null if no DataSet with right dependency could be found. - open func getFirstRight(dataSets: [IChartDataSet]) -> IChartDataSet? + open func getFirstDataSet(dataSets: [IChartDataSet], axisDependency : YAxis.AxisDependency) -> IChartDataSet? { for dataSet in _dataSets { - if dataSet.axisDependency == .right + if dataSet.axisDependency == axisDependency { return dataSet } @@ -675,7 +750,7 @@ open class ChartData: NSObject /// Enables / disables highlighting values for all DataSets this data object contains. /// If set to true, this means that values can be highlighted programmatically or by touch gesture. open var highlightEnabled: Bool - { + { get { for set in dataSets @@ -708,7 +783,7 @@ open class ChartData: NSObject notifyDataChanged() } - /// Checks if this data object contains the specified DataSet. + /// Checks if this data object contains the specified DataSet. /// - returns: `true` if so, `false` ifnot. open func contains(dataSet: IChartDataSet) -> Bool { @@ -735,7 +810,7 @@ open class ChartData: NSObject return count } - + /// - returns: The DataSet object with the maximum number of entries or null if there are no DataSets. open var maxEntryCountSet: IChartDataSet? { From 228667220b429adc89c266489db44ca39ab1b3eb Mon Sep 17 00:00:00 2001 From: thierryH91200 Date: Thu, 1 Jun 2017 11:15:07 +0200 Subject: [PATCH 4/8] update legend without axis --- .../Charts/Charts/BarLineChartViewBase.swift | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/Source/Charts/Charts/BarLineChartViewBase.swift b/Source/Charts/Charts/BarLineChartViewBase.swift index 78367cfe59..8ac282e34d 100644 --- a/Source/Charts/Charts/BarLineChartViewBase.swift +++ b/Source/Charts/Charts/BarLineChartViewBase.swift @@ -483,11 +483,11 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD offsetRight: &offsetRightLegend, offsetBottom: &offsetBottomLegend) - offsetTop += self.extraTopOffset - offsetRight += self.extraRightOffset - offsetBottom += self.extraBottomOffset - offsetLeft += self.extraLeftOffset - + offsetTop += self.extraTopOffset + offsetTopLegend + offsetRight += self.extraRightOffset + offsetRightLegend + offsetBottom += self.extraBottomOffset + offsetBottomLegend + offsetLeft += self.extraLeftOffset + offsetLeftLegend + let axisRectHeight = viewPortHandler.contentHeight let axisRectTop = viewPortHandler.contentTop let lineWidth : CGFloat = 1.0 @@ -503,7 +503,6 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD // 5 pixels : stick // n pixels : label width // n pixels : name height - offsetLeft += offsetLeftLegend var offsetLeftTmp = offsetLeft if leftAxis1.needsOffset { @@ -538,7 +537,6 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD offsetLeft += leftAxis.xOffset // Space from right to left - offsetRight += offsetRightLegend var offsetRightTmp = offsetRight if rightAxis1.needsOffset { @@ -553,7 +551,6 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD y: axisRectTop, width: width, height: axisRectHeight) - } offsetRightTmp = offsetRight @@ -591,7 +588,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD // offsets for x-labels if xAxis.labelPosition == .bottom { - offsetBottom += offsetBottomLegend + xlabelheight + namexAxisHeight + offsetBottom += xlabelheight + namexAxisHeight xAxis.axisRectBottom = CGRect(x: nameAxisRectLeft, y: viewPortHandler.chartHeight - offsetBottomLegend - namexAxisHeight, width: nameAxisRectWidth, @@ -599,7 +596,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD } else if xAxis.labelPosition == .top { - offsetTop += offsetTopLegend + xlabelheight + namexAxisHeight + offsetTop += xlabelheight + namexAxisHeight xAxis.axisRectTop = CGRect(x: nameAxisRectLeft, y: offsetTop - namexAxisHeight - xlabelheight, width: nameAxisRectWidth, @@ -607,13 +604,13 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD } else if xAxis.labelPosition == .bothSided { - offsetBottom += offsetBottomLegend + xlabelheight + namexAxisHeight + offsetBottom += xlabelheight + namexAxisHeight xAxis.axisRectBottom = CGRect(x: nameAxisRectLeft, y: viewPortHandler.chartHeight - offsetBottomLegend - namexAxisHeight, width: nameAxisRectWidth, height: namexAxisHeight) - offsetTop += offsetTopLegend + xlabelheight + namexAxisHeight + offsetTop += xlabelheight + namexAxisHeight xAxis.axisRectTop = CGRect(x: nameAxisRectLeft, y: offsetTopLegend, width: nameAxisRectWidth, From fdc1dca4bbf47f80c66b9d2f30eb766732211ceb Mon Sep 17 00:00:00 2001 From: thierryH91200 Date: Sun, 4 Jun 2017 16:48:35 +0200 Subject: [PATCH 5/8] add axisSecondaryEnabled = false and not enabled --- .../Charts/Charts/BarLineChartViewBase.swift | 49 ++++++++++++------- .../Charts/HorizontalBarChartView.swift | 12 ++--- Source/Charts/Components/YAxis.swift | 31 ++++++++++-- .../YAxisRendererHorizontalBarChart.swift | 19 ++++--- 4 files changed, 75 insertions(+), 36 deletions(-) diff --git a/Source/Charts/Charts/BarLineChartViewBase.swift b/Source/Charts/Charts/BarLineChartViewBase.swift index 8ac282e34d..590e2622ba 100644 --- a/Source/Charts/Charts/BarLineChartViewBase.swift +++ b/Source/Charts/Charts/BarLineChartViewBase.swift @@ -199,7 +199,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { _leftYAxisRenderer?.computeAxis(min: _leftAxis._axisMinimum, max: _leftAxis._axisMaximum, inverted: _leftAxis.isInverted) } - if _leftAxis1.isEnabled + if _leftAxis1.isAxisSecondaryEnabled { _leftYAxisRenderer1?.computeAxis(min: _leftAxis1._axisMinimum, max: _leftAxis1._axisMaximum, inverted: _leftAxis1.isInverted) } @@ -208,7 +208,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { _rightYAxisRenderer?.computeAxis(min: _rightAxis._axisMinimum, max: _rightAxis._axisMaximum, inverted: _rightAxis.isInverted) } - if _rightAxis1.isEnabled + if _rightAxis1.isAxisSecondaryEnabled { _rightYAxisRenderer1?.computeAxis(min: _rightAxis1._axisMinimum, max: _rightAxis1._axisMaximum, inverted: _rightAxis1.isInverted) } @@ -240,7 +240,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { _leftYAxisRenderer?.renderLimitLines(context: context) } - if _leftAxis1.isEnabled && _leftAxis1.isDrawLimitLinesBehindDataEnabled + if _leftAxis1.isAxisSecondaryEnabled && _leftAxis1.isDrawLimitLinesBehindDataEnabled { _leftYAxisRenderer1?.renderLimitLines(context: context) } @@ -250,7 +250,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { _rightYAxisRenderer?.renderLimitLines(context: context) } - if _rightAxis1.isEnabled && _rightAxis1.isDrawLimitLinesBehindDataEnabled + if _rightAxis1.isAxisSecondaryEnabled && _rightAxis1.isDrawLimitLinesBehindDataEnabled { _rightYAxisRenderer1?.renderLimitLines(context: context) } @@ -280,7 +280,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { _leftYAxisRenderer?.renderLimitLines(context: context) } - if _leftAxis1.isEnabled && !_leftAxis1.isDrawLimitLinesBehindDataEnabled + if _leftAxis1.isAxisSecondaryEnabled && !_leftAxis1.isDrawLimitLinesBehindDataEnabled { _leftYAxisRenderer1?.renderLimitLines(context: context) } @@ -289,18 +289,29 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { _rightYAxisRenderer?.renderLimitLines(context: context) } - if _rightAxis1.isEnabled && !_rightAxis1.isDrawLimitLinesBehindDataEnabled + if _rightAxis1.isAxisSecondaryEnabled && !_rightAxis1.isDrawLimitLinesBehindDataEnabled { _rightYAxisRenderer1?.renderLimitLines(context: context) } _xAxisRenderer.renderAxisLabels(context: context) - _leftYAxisRenderer.renderAxisLabels(context: context) - _leftYAxisRenderer1.renderAxisLabels(context: context) - - _rightYAxisRenderer.renderAxisLabels(context: context) - _rightYAxisRenderer1.renderAxisLabels(context: context) + if _leftAxis.isEnabled + { + _leftYAxisRenderer.renderAxisLabels(context: context) + } + if _leftAxis1.isAxisSecondaryEnabled + { + _leftYAxisRenderer1.renderAxisLabels(context: context) + } + if _rightAxis.isEnabled + { + _rightYAxisRenderer.renderAxisLabels(context: context) + } + if _rightAxis1.isAxisSecondaryEnabled + { + _rightYAxisRenderer1.renderAxisLabels(context: context) + } if clipValuesToContentEnabled { @@ -342,7 +353,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { _leftAxis.calculate(min: data.getYMin(axis: .left), max: data.getYMax(axis: .left)) } - if _leftAxis1.isEnabled + if _leftAxis1.isAxisSecondaryEnabled { _leftAxis1.calculate(min: data.getYMin(axis: .left1), max: data.getYMax(axis: .left1)) } @@ -351,7 +362,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD { _rightAxis.calculate(min: data.getYMin(axis: .right), max: data.getYMax(axis: .right)) } - if _rightAxis1.isEnabled + if _rightAxis1.isAxisSecondaryEnabled { _rightAxis1.calculate(min: data.getYMin(axis: .right1), max: data.getYMax(axis: .right1)) } @@ -450,7 +461,6 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD } case .horizontal: - switch _legend.verticalAlignment { case .top: @@ -487,7 +497,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD offsetRight += self.extraRightOffset + offsetRightLegend offsetBottom += self.extraBottomOffset + offsetBottomLegend offsetLeft += self.extraLeftOffset + offsetLeftLegend - + let axisRectHeight = viewPortHandler.contentHeight let axisRectTop = viewPortHandler.contentTop let lineWidth : CGFloat = 1.0 @@ -504,7 +514,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD // n pixels : label width // n pixels : name height var offsetLeftTmp = offsetLeft - if leftAxis1.needsOffset + if leftAxis1.needsOffsetSecondary { offsetLeft += lineWidth + stick + leftAxis1.requiredSize().width if leftAxis1.nameAxisEnabled @@ -538,7 +548,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD // Space from right to left var offsetRightTmp = offsetRight - if rightAxis1.needsOffset + if rightAxis1.needsOffsetSecondary { offsetRight += lineWidth + stick + rightAxis1.requiredSize().width if rightAxis1.nameAxisEnabled @@ -551,6 +561,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD y: axisRectTop, width: width, height: axisRectHeight) + } offsetRightTmp = offsetRight @@ -588,7 +599,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD // offsets for x-labels if xAxis.labelPosition == .bottom { - offsetBottom += xlabelheight + namexAxisHeight + offsetBottom += xlabelheight + namexAxisHeight xAxis.axisRectBottom = CGRect(x: nameAxisRectLeft, y: viewPortHandler.chartHeight - offsetBottomLegend - namexAxisHeight, width: nameAxisRectWidth, @@ -1900,7 +1911,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD /// - returns: The y-axis object to the corresponding AxisDependency. In the /// horizontal bar-chart, LEFT == top, RIGHT == BOTTOM - open func getAxis(_ axis: YAxis.AxisDependency) -> YAxis + @objc open func getAxis(_ axis: YAxis.AxisDependency) -> YAxis { switch axis { diff --git a/Source/Charts/Charts/HorizontalBarChartView.swift b/Source/Charts/Charts/HorizontalBarChartView.swift index fef79a915b..fb4ff50959 100644 --- a/Source/Charts/Charts/HorizontalBarChartView.swift +++ b/Source/Charts/Charts/HorizontalBarChartView.swift @@ -75,15 +75,15 @@ open class HorizontalBarChartView: BarChartView // offsetTop = offsetTopLegend + leftAxis1.axisRectTop.height + leftAxis.axisRectTop.height + leftAxis.yOffset // rect axis - // 1 pixel : line width + // 1 pixel : line height // 5 pixels : stick - // n pixels : label width + // n pixels : label height // n pixels : name height offsetTop = offsetTopLegend var offsetTopTmp = offsetTop - if leftAxis1.needsOffset + if leftAxis1.needsOffsetSecondary { - offsetTop += lineWidth + stick + leftAxis1.getRequiredHeightSpace() + offsetTop += lineWidth + stick + leftAxis1.getRequiredHeightSpaceSecondary() if leftAxis1.nameAxisEnabled { let nameAxisHeight = leftAxis.nameAxis.size(attributes: [NSFontAttributeName: leftAxis.nameAxisFont]).height @@ -116,9 +116,9 @@ open class HorizontalBarChartView: BarChartView // Space from bottom to top offsetBottom = offsetBottomLegend var offsetBottomTmp = offsetBottom - if rightAxis1.needsOffset + if rightAxis1.needsOffsetSecondary { - offsetBottom += rightAxis1.getRequiredHeightSpace() + offsetBottom += rightAxis1.getRequiredHeightSpaceSecondary() if rightAxis1.nameAxisEnabled { let nameAxisHeight = rightAxis1.nameAxis.size(attributes: [NSFontAttributeName: rightAxis1.nameAxisFont]).height diff --git a/Source/Charts/Components/YAxis.swift b/Source/Charts/Components/YAxis.swift index e5cad75bba..826f2eff59 100644 --- a/Source/Charts/Components/YAxis.swift +++ b/Source/Charts/Components/YAxis.swift @@ -89,11 +89,14 @@ open class YAxis: AxisBase /// **default**: CGFloat.infinity open var maxWidth = CGFloat(CGFloat.infinity) + open var axisSecondaryEnabled = false + open var isAxisSecondaryEnabled: Bool { return axisSecondaryEnabled } + public override init() { super.init() - // self.yOffset = 0.0 why ??? + // self.yOffset = 0.0 } public init(position: AxisDependency) @@ -102,7 +105,7 @@ open class YAxis: AxisBase _axisDependency = position - // self.yOffset = 0.0 why ?? + // self.yOffset = 0.0 } open var axisDependency: AxisDependency @@ -129,10 +132,32 @@ open class YAxis: AxisBase return 0 } + open func getRequiredHeightSpaceSecondary() -> CGFloat + { + if isAxisSecondaryEnabled + { + return requiredSize().height + } + return 0 + } + /// - returns: `true` if this axis needs horizontal offset, `false` ifno offset is needed. open var needsOffset: Bool { - if isEnabled && isDrawLabelsEnabled && labelPosition == .outsideChart + if isEnabled && isDrawLabelsEnabled && labelPosition == .outsideChart + { + return true + } + else + { + return false + } + } + + /// - returns: `true` if this axis needs horizontal offset, `false` ifno offset is needed. + open var needsOffsetSecondary: Bool + { + if isAxisSecondaryEnabled && isDrawLabelsEnabled && labelPosition == .outsideChart { return true } diff --git a/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift b/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift index 039fb41545..476cfc215e 100644 --- a/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift +++ b/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift @@ -68,7 +68,7 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer } let lineHeight = yAxis.labelFont.lineHeight - let baseYOffset: CGFloat = 5 + let baseYOffset: CGFloat = 6 let dependency = yAxis.axisDependency let labelPosition = yAxis.labelPosition @@ -93,7 +93,7 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer case .right, .right1: if labelPosition == .outsideChart { - yPos = yAxis.axisRectBottom.maxY - lineHeight + yPos = yAxis.axisRectBottom.minY + baseYOffset + lineHeight drawNameYAxis( context: context, nameRect: yAxis.axisRectBottom) drawYAxis(context: context, axisRect: yAxis.axisRectBottom, positions: transformedPositions()) @@ -102,6 +102,7 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer { yPos = viewPortHandler.contentBottom + lineHeight } + drawRect(context: context, rect: yAxis.axisRectBottom) } // For compatibility with Android code, we keep above calculation the same, @@ -121,6 +122,14 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer let yAxis = self.axis as? YAxis else { return } + if yAxis.entryCount == 0 + { + return + } + + let from = yAxis.isDrawBottomYLabelEntryEnabled ? 0 : 1 + let to = yAxis.isDrawTopYLabelEntryEnabled ? yAxis.entryCount : (yAxis.entryCount - 1) + let labelTextColor = yAxis.labelTextColor context.saveGState() @@ -134,9 +143,6 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer context.move(to: CGPoint(x: axisRect.minX, y: axisRect.minY)) context.addLine(to: CGPoint(x: axisRect.maxX, y: axisRect.minY)) - let from = yAxis.isDrawBottomYLabelEntryEnabled ? 0 : 1 - let to = yAxis.isDrawTopYLabelEntryEnabled ? yAxis.entryCount : (yAxis.entryCount - 1) - for i in stride(from: from, to: to, by: 1) { context.move(to: CGPoint(x: positions[i].x, y: axisRect.minY)) @@ -148,9 +154,6 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer context.move(to: CGPoint(x: axisRect.minX, y: axisRect.maxY)) context.addLine(to: CGPoint(x: axisRect.maxX, y: axisRect.maxY)) - let from = yAxis.isDrawBottomYLabelEntryEnabled ? 0 : 1 - let to = yAxis.isDrawTopYLabelEntryEnabled ? yAxis.entryCount : (yAxis.entryCount - 1) - for i in stride(from: from, to: to, by: 1) { context.move(to: CGPoint(x: positions[i].x, y: axisRect.maxY)) From 87deabb627689578deb706dcb4197d9840d5e24b Mon Sep 17 00:00:00 2001 From: thierryH91200 Date: Sun, 4 Jun 2017 16:50:37 +0200 Subject: [PATCH 6/8] add axisSecondaryEnabled = false for compatibility --- Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift b/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift index 476cfc215e..27939548e5 100644 --- a/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift +++ b/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift @@ -102,7 +102,6 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer { yPos = viewPortHandler.contentBottom + lineHeight } - drawRect(context: context, rect: yAxis.axisRectBottom) } // For compatibility with Android code, we keep above calculation the same, From 5a39e2f0f6a8cf07dd0b102447ee3599825e9a42 Mon Sep 17 00:00:00 2001 From: thierryH91200 Date: Sun, 4 Jun 2017 18:52:42 +0200 Subject: [PATCH 7/8] multiaxis minor bug --- Source/Charts/Renderers/YAxisRenderer.swift | 55 ++++++++++++++----- .../YAxisRendererHorizontalBarChart.swift | 18 +++++- 2 files changed, 57 insertions(+), 16 deletions(-) diff --git a/Source/Charts/Renderers/YAxisRenderer.swift b/Source/Charts/Renderers/YAxisRenderer.swift index 0001a20b3f..783295f7c0 100644 --- a/Source/Charts/Renderers/YAxisRenderer.swift +++ b/Source/Charts/Renderers/YAxisRenderer.swift @@ -32,15 +32,22 @@ open class YAxisRenderer: AxisRendererBase let viewPortHandler = self.viewPortHandler else { return } - if !yAxis.isEnabled || !yAxis.isDrawLabelsEnabled + let dependency = yAxis.axisDependency + if (dependency == .right || dependency == .left) && !yAxis.isEnabled || !yAxis.isDrawLabelsEnabled + { + return + } + + if (dependency == .right1 || dependency == .left1) && !yAxis.isAxisSecondaryEnabled || !yAxis.isDrawLabelsEnabled { return } + let xoffset = yAxis.xOffset let yoffset = yAxis.labelFont.lineHeight / 2.5 + yAxis.yOffset - let dependency = yAxis.axisDependency + let labelPosition = yAxis.labelPosition var xPos = CGFloat(0.0) @@ -85,13 +92,31 @@ open class YAxisRenderer: AxisRendererBase textAlign: textAlign) } - + internal func drawRect(context: CGContext, rect: CGRect) + { + context.saveGState() + context.beginPath() + NSUIColor.black.setStroke() + let bpath = NSBezierPath(rect: rect) + bpath.stroke() + context.strokePath() + context.restoreGState() + } + internal func drawYAxis(context: CGContext, axisRect: CGRect, positions: [CGPoint]) { guard let yAxis = self.axis as? YAxis else { return } + if yAxis.entryCount == 0 + { + return + } + + let from = yAxis.isDrawBottomYLabelEntryEnabled ? 0 : 1 + let to = yAxis.isDrawTopYLabelEntryEnabled ? yAxis.entryCount : (yAxis.entryCount - 1) + let labelTextColor = yAxis.labelTextColor context.saveGState() @@ -105,9 +130,6 @@ open class YAxisRenderer: AxisRendererBase context.move(to: CGPoint(x: axisRect.minX, y: axisRect.minY)) context.addLine(to: CGPoint(x: axisRect.minX, y: axisRect.maxY)) - let from = yAxis.isDrawBottomYLabelEntryEnabled ? 0 : 1 - let to = yAxis.isDrawTopYLabelEntryEnabled ? yAxis.entryCount : (yAxis.entryCount - 1) - for i in stride(from: from, to: to, by: 1) { context.move(to: CGPoint(x: axisRect.minX, y: positions[i].y)) @@ -119,9 +141,6 @@ open class YAxisRenderer: AxisRendererBase context.move(to: CGPoint(x: axisRect.maxX, y: axisRect.minY)) context.addLine(to: CGPoint(x: axisRect.maxX, y: axisRect.maxY)) - let from = yAxis.isDrawBottomYLabelEntryEnabled ? 0 : 1 - let to = yAxis.isDrawTopYLabelEntryEnabled ? yAxis.entryCount : (yAxis.entryCount - 1) - for i in stride(from: from, to: to, by: 1) { context.move(to: CGPoint(x: axisRect.maxX, y: positions[i].y)) @@ -220,7 +239,13 @@ open class YAxisRenderer: AxisRendererBase let viewPortHandler = self.viewPortHandler else { return } - if !yAxis.isEnabled || !yAxis.drawAxisLineEnabled + let dependency = yAxis.axisDependency + if (dependency == .right || dependency == .left) && !yAxis.isEnabled || !yAxis.drawAxisLineEnabled + { + return + } + + if (dependency == .right1 || dependency == .left1) && !yAxis.isAxisSecondaryEnabled || !yAxis.drawAxisLineEnabled { return } @@ -262,7 +287,13 @@ open class YAxisRenderer: AxisRendererBase yAxis = self.axis as? YAxis else { return } - if !yAxis.isEnabled + let dependency = yAxis.axisDependency + if (dependency == .right || dependency == .left) && !yAxis.isEnabled + { + return + } + + if (dependency == .right1 || dependency == .left1) && !yAxis.isAxisSecondaryEnabled { return } @@ -283,7 +314,6 @@ open class YAxisRenderer: AxisRendererBase if yAxis.gridLineDashLengths != nil { context.setLineDash(phase: yAxis.gridLineDashPhase, lengths: yAxis.gridLineDashLengths) - } else { @@ -345,7 +375,6 @@ open class YAxisRenderer: AxisRendererBase } transformer.pointValuesToPixel(&positions) - return positions } diff --git a/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift b/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift index 27939548e5..b0afdc227c 100644 --- a/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift +++ b/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift @@ -62,7 +62,13 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer let viewPortHandler = self.viewPortHandler else { return } - if !yAxis.isEnabled || !yAxis.isDrawLabelsEnabled + let dependency = yAxis.axisDependency + if (dependency == .right || dependency == .left) && !yAxis.isEnabled || !yAxis.isDrawLabelsEnabled + { + return + } + + if (dependency == .right1 || dependency == .left1) && !yAxis.isAxisSecondaryEnabled || !yAxis.isDrawLabelsEnabled { return } @@ -70,7 +76,6 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer let lineHeight = yAxis.labelFont.lineHeight let baseYOffset: CGFloat = 6 - let dependency = yAxis.axisDependency let labelPosition = yAxis.labelPosition var yPos: CGFloat = 0.0 @@ -102,6 +107,7 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer { yPos = viewPortHandler.contentBottom + lineHeight } + drawRect(context: context, rect: yAxis.axisRectBottom) } // For compatibility with Android code, we keep above calculation the same, @@ -218,7 +224,13 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer let viewPortHandler = self.viewPortHandler else { return } - if !yAxis.isEnabled || !yAxis.drawAxisLineEnabled + let dependency = yAxis.axisDependency + if (dependency == .right || dependency == .left) && !yAxis.isEnabled || !yAxis.drawAxisLineEnabled + { + return + } + + if (dependency == .right1 || dependency == .left1) && !yAxis.isAxisSecondaryEnabled || !yAxis.drawAxisLineEnabled { return } From 358d477567d1056b2c56d4b07921ac593999aeed Mon Sep 17 00:00:00 2001 From: thierryH91200 Date: Tue, 6 Jun 2017 12:46:46 +0200 Subject: [PATCH 8/8] multi axis : bug on func getYMax and getYMin --- .../Implementations/Standard/ChartData.swift | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/Source/Charts/Data/Implementations/Standard/ChartData.swift b/Source/Charts/Data/Implementations/Standard/ChartData.swift index 9a2051208c..71cdf244e6 100644 --- a/Source/Charts/Data/Implementations/Standard/ChartData.swift +++ b/Source/Charts/Data/Implementations/Standard/ChartData.swift @@ -354,21 +354,18 @@ open class ChartData: NSObject open func getYMin(axis: YAxis.AxisDependency) -> Double { - let arrayYMin = [_leftAxisMin, _leftAxisMin1, _rightAxisMin, _rightAxisMin1] - let filteredArray = arrayYMin.filter() { $0 != Double.greatestFiniteMagnitude} - let axisMin = filteredArray.min()! var axisYMin = 0.0 switch axis { case .left: - axisYMin = _leftAxisMin == Double.greatestFiniteMagnitude ? axisMin : _leftAxisMin + axisYMin = _leftAxisMin == Double.greatestFiniteMagnitude ? min(_rightAxisMin, _rightAxisMin1) : _leftAxisMin case .left1: - axisYMin = _leftAxisMin1 == Double.greatestFiniteMagnitude ? axisMin : _leftAxisMin1 + axisYMin = _leftAxisMin1 == Double.greatestFiniteMagnitude ? min(_rightAxisMin, _rightAxisMin1) : _leftAxisMin1 case .right: - axisYMin = _rightAxisMin == Double.greatestFiniteMagnitude ? axisMin : _rightAxisMin + axisYMin = _rightAxisMin == Double.greatestFiniteMagnitude ? min(_leftAxisMin, _leftAxisMin1) : _rightAxisMin case .right1: - axisYMin = _rightAxisMin1 == Double.greatestFiniteMagnitude ? axisMin : _rightAxisMin1 + axisYMin = _rightAxisMin1 == Double.greatestFiniteMagnitude ? min(_leftAxisMin, _leftAxisMin1) : _rightAxisMin1 } return axisYMin } @@ -387,21 +384,18 @@ open class ChartData: NSObject open func getYMax(axis: YAxis.AxisDependency) -> Double { - let arrayYMax = [_leftAxisMax, _leftAxisMax1, _rightAxisMax, _rightAxisMax1] - let filteredArray = arrayYMax.filter() { $0 != -Double.greatestFiniteMagnitude} - let axisMax = filteredArray.max()! var axisYMax = 0.0 switch axis { case .left: - axisYMax = _leftAxisMax == -Double.greatestFiniteMagnitude ? axisMax : _leftAxisMax + axisYMax = _leftAxisMax == -Double.greatestFiniteMagnitude ? max(_rightAxisMax, _rightAxisMax1) : _leftAxisMax case .left1: - axisYMax = _leftAxisMax1 == -Double.greatestFiniteMagnitude ? axisMax : _leftAxisMax1 + axisYMax = _leftAxisMax1 == -Double.greatestFiniteMagnitude ? max(_rightAxisMax, _rightAxisMax1) : _leftAxisMax1 case .right: - axisYMax = _rightAxisMax == -Double.greatestFiniteMagnitude ? axisMax : _rightAxisMin + axisYMax = _rightAxisMax == -Double.greatestFiniteMagnitude ? max(_leftAxisMax, _leftAxisMax1) : _rightAxisMax case .right1: - axisYMax = _rightAxisMax1 == -Double.greatestFiniteMagnitude ? axisMax : _rightAxisMax1 + axisYMax = _rightAxisMax1 == -Double.greatestFiniteMagnitude ? max(_leftAxisMax, _leftAxisMax1) : _rightAxisMax1 } return axisYMax }