Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Named axis support #2452

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 54 additions & 7 deletions Source/Charts/Charts/BarLineChartViewBase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -426,38 +426,84 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD
if leftAxis.needsOffset
{
offsetLeft += leftAxis.requiredSize().width
if leftAxis.nameAxisEnabled
{
let nameLeftAxisHeight = leftAxis.nameAxis.size(attributes: [NSFontAttributeName: leftAxis.nameAxisFont]).height
offsetLeft += nameLeftAxisHeight
leftAxis.nameRectLeft = CGRect(x: offsetLeft - leftAxis.requiredSize().width - nameLeftAxisHeight,
y:viewPortHandler.contentTop,
width: nameLeftAxisHeight,
height:viewPortHandler.contentHeight)
}
}

if rightAxis.needsOffset
{
offsetRight += rightAxis.requiredSize().width
if rightAxis.nameAxisEnabled
{
let nameRightAxisHeight = rightAxis.nameAxis.size(attributes: [NSFontAttributeName: rightAxis.nameAxisFont]).height
offsetRight += nameRightAxisHeight
rightAxis.nameRectRight = CGRect(x: viewPortHandler.contentRight + rightAxis.requiredSize().width,
y: viewPortHandler.contentTop,
width: nameRightAxisHeight,
height: viewPortHandler.contentHeight)
}
}

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 += xlabelheight + namexAxisHeight
xAxis.nameRectBottom = CGRect(x: nameAxisRectLeft,
y: viewPortHandler.chartHeight - offsetBottom + xlabelheight,
width: nameAxisRectWidth,
height: namexAxisHeight)
}
else if xAxis.labelPosition == .top
{
offsetTop += xlabelheight
offsetTop += xlabelheight + namexAxisHeight
xAxis.nameRectTop = CGRect(x: nameAxisRectLeft,
y: offsetTop - namexAxisHeight - xlabelheight,
width: nameAxisRectWidth,
height: namexAxisHeight)
}
else if xAxis.labelPosition == .bothSided
{
offsetBottom += xlabelheight
offsetTop += xlabelheight
offsetBottom += xlabelheight + namexAxisHeight
xAxis.nameRectBottom = CGRect(x: nameAxisRectLeft,
y: viewPortHandler.chartHeight - offsetBottom + xlabelheight,
width: nameAxisRectWidth,
height: namexAxisHeight)
offsetTop += xlabelheight + namexAxisHeight
xAxis.nameRectTop = CGRect(x: nameAxisRectLeft,
y: offsetTop - namexAxisHeight - xlabelheight,
width: nameAxisRectWidth,
height: namexAxisHeight)
}
}

offsetTop += self.extraTopOffset
offsetRight += self.extraRightOffset
offsetBottom += self.extraBottomOffset
offsetLeft += self.extraLeftOffset

_viewPortHandler.restrainViewPort(
offsetLeft: max(self.minOffset, offsetLeft),
offsetTop: max(self.minOffset, offsetTop),
Expand All @@ -469,6 +515,7 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD
prepareValuePxMatrix()
}


/// draws the grid background
internal func drawGridBackground(context: CGContext)
{
Expand Down
57 changes: 53 additions & 4 deletions Source/Charts/Charts/HorizontalBarChartView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,34 +46,83 @@ open class HorizontalBarChartView: BarChartView
offsetRight: &offsetRight,
offsetBottom: &offsetBottom)

var nameAxisRectWidth = CGFloat(0.0)
var nameAxisRectLeft = CGFloat(0.0)
if _leftAxis.nameAxisEnabled || _rightAxis.nameAxisEnabled
{
nameAxisRectWidth = viewPortHandler.contentWidth
nameAxisRectLeft = viewPortHandler.contentLeft
}

// offsets for y-labels
if _leftAxis.needsOffset
{
offsetTop += _leftAxis.getRequiredHeightSpace()
if leftAxis.nameAxisEnabled
{
let nameLeftAxisSize = leftAxis.nameAxis.size(attributes: [NSFontAttributeName: leftAxis.nameAxisFont])
offsetTop += nameLeftAxisSize.height
leftAxis.nameRectTop = CGRect(x: nameAxisRectLeft,
y: offsetTop - nameLeftAxisSize.height - _leftAxis.getRequiredHeightSpace(),
width: nameAxisRectWidth,
height: nameLeftAxisSize.height)
}
}

if _rightAxis.needsOffset
{
offsetBottom += _rightAxis.getRequiredHeightSpace()
if rightAxis.nameAxisEnabled
{
let nameRightAxisSize = rightAxis.nameAxis.size(attributes: [NSFontAttributeName: rightAxis.nameAxisFont])
offsetBottom += nameRightAxisSize.height
rightAxis.nameRectBottom = CGRect(x: nameAxisRectLeft,
y: viewPortHandler.chartHeight - offsetBottom + _rightAxis.getRequiredHeightSpace() ,
width: nameAxisRectWidth,
height: nameRightAxisSize.height)
}
}

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
if _xAxis.labelPosition == .bottom
{
offsetLeft += xlabelwidth
offsetLeft += xlabelwidth + namexAxisHeight
xAxis.nameRectLeft = CGRect(x: offsetLeft - xlabelwidth - namexAxisHeight,
y:viewPortHandler.contentTop,
width: namexAxisHeight,
height:viewPortHandler.contentHeight)
}
else if _xAxis.labelPosition == .top
{
offsetRight += xlabelwidth
offsetRight += xlabelwidth + namexAxisHeight
xAxis.nameRectRight = 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.nameRectLeft = CGRect(x: offsetLeft - xlabelwidth - namexAxisHeight,
y:viewPortHandler.contentTop,
width: namexAxisHeight,
height:viewPortHandler.contentHeight)

offsetRight += xlabelwidth + namexAxisHeight
xAxis.nameRectRight = CGRect(x: viewPortHandler.contentRight + xlabelwidth,
y: viewPortHandler.contentTop,
width: namexAxisHeight,
height: viewPortHandler.contentHeight)
}
}

Expand Down
11 changes: 11 additions & 0 deletions Source/Charts/Components/AxisBase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ open class AxisBase: ComponentBase
open var drawGridLinesEnabled = true
open var drawAxisLineEnabled = true

open var nameAxis : String = ""
open var nameAxisFont = NSUIFont.boldSystemFont(ofSize: 12.0)
open var nameAxisTextColor = NSUIColor.black
open var nameAxisEnabled = false

/// flag that indicates of the labels of this axis should be drawn or not
open var drawLabelsEnabled = true

Expand Down Expand Up @@ -213,6 +218,12 @@ open class AxisBase: ComponentBase
/// the total range of values this axis covers
open var axisRange = Double(0)

open var nameRectBottom = CGRect()
open var nameRectTop = CGRect()
open var nameRectLeft = CGRect()
open var nameRectRight = CGRect()


/// the number of label entries the axis should have
/// max = 25,
/// min = 2,
Expand Down
87 changes: 83 additions & 4 deletions Source/Charts/Renderers/XAxisRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,27 +101,65 @@ 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.nameRectTop)
}
else if xAxis.labelPosition == .topInside
{
drawLabels(context: context, pos: viewPortHandler.contentTop + yOffset + xAxis.labelRotatedHeight, anchor: CGPoint(x: 0.5, y: 1.0))
}
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.nameRectBottom)
}
else if xAxis.labelPosition == .bottomInside
{
drawLabels(context: context, pos: viewPortHandler.contentBottom - yOffset - xAxis.labelRotatedHeight, anchor: CGPoint(x: 0.5, y: 0.0))
}
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.nameRectTop)

// bottom
pos = viewPortHandler.contentBottom + yOffset
drawLabels(context: context, pos: pos, anchor: CGPoint(x: 0.5, y: 0.0))
drawNameXAxis ( context: context, nameRect: xAxis.nameRectBottom)
}
}

/// 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.nameAxisTextColor,
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)
Expand Down Expand Up @@ -262,6 +300,47 @@ open class XAxisRenderer: AxisRendererBase
}
}

/// draws the x-name
open func drawNameXAxis (
context: CGContext,
fixedPosition: CGFloat,
positions: CGPoint,
offset: CGFloat)
{
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.nameAxisTextColor,
NSParagraphStyleAttributeName: paraStyle] as [String : NSObject]
let labelRotationAngleRadians = 0 * ChartUtils.Math.FDEG2RAD

let text = xAxis.nameAxis
let labelMaxSize = CGSize()

ChartUtils.drawMultilineText(
context: context,
text: text,
point: CGPoint(x: positions.x, y: fixedPosition),
attributes: labelAttrs,
constrainedToSize: labelMaxSize,
anchor: CGPoint(x: 0.5, y: 1.0),
angleRadians: labelRotationAngleRadians)
}

open func drawLabel(
context: CGContext,
formattedLabel: String,
Expand Down
Loading