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

Added value text rotation #2200

Merged
merged 6 commits into from
Jul 14, 2018
Merged
Show file tree
Hide file tree
Changes from 3 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
3 changes: 3 additions & 0 deletions Source/Charts/Data/Implementations/ChartBaseDataSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,9 @@ open class ChartBaseDataSet: NSObject, ChartDataSetProtocol
/// the font for the value-text labels
open var valueFont: NSUIFont = NSUIFont.systemFont(ofSize: 7.0)

/// the rotation angle for value-text labels
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change to "The rotation angle (in degrees) for value-text labels

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you change it in the protocol, you can delete the documentation comment here and Xcode will use the one from the protocol.

open var valueRotationAngle: CGFloat = CGFloat(0.0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

valueLabelAngle


/// The form to draw for this dataset in the legend.
open var form = Legend.Form.default

Expand Down
3 changes: 3 additions & 0 deletions Source/Charts/Data/Interfaces/ChartDataSetProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,9 @@ public protocol ChartDataSetProtocol
/// the font for the value-text labels
var valueFont: NSUIFont { get set }

/// the rotation angle for value-text labels
var valueRotationAngle: CGFloat { get set }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

valueLabelAngle


/// The form to draw for this dataset in the legend.
///
/// Return `.Default` to use the default legend form.
Expand Down
29 changes: 24 additions & 5 deletions Source/Charts/Renderers/BarChartRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,8 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer
shouldDrawValues(forDataSet: dataSet)
else { continue }

let angleRadians = dataSet.valueRotationAngle.DEG2RAD

let isInverted = dataProvider.isInverted(axis: dataSet.axisDependency)

// calculate the correct offset depending on the draw position of the value
Expand Down Expand Up @@ -376,7 +378,9 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer
: (rect.origin.y + rect.size.height + negOffset),
font: valueFont,
align: .center,
color: dataSet.valueTextColorAt(j))
color: dataSet.valueTextColorAt(j),
anchor: CGPoint(x: 0.5, y: 0.5),
angleRadians: angleRadians)
}

if let icon = e.icon, dataSet.isDrawIconsEnabled
Expand All @@ -393,6 +397,7 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer
atCenter: CGPoint(x: px, y: py),
size: icon.size)
}

}
}
else
Expand Down Expand Up @@ -469,7 +474,9 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer
yPos: y,
font: valueFont,
align: .center,
color: dataSet.valueTextColorAt(index))
color: dataSet.valueTextColorAt(index),
anchor: CGPoint(x: 0.5, y: 0.5),
angleRadians: angleRadians)
}

if let icon = e.icon, dataSet.isDrawIconsEnabled
Expand Down Expand Up @@ -501,7 +508,9 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer
(e.y >= 0 ? posOffset : negOffset),
font: valueFont,
align: .center,
color: dataSet.valueTextColorAt(index))
color: dataSet.valueTextColorAt(index),
anchor: CGPoint(x: 0.5, y: 0.5),
angleRadians: angleRadians)
}

if let icon = e.icon, dataSet.isDrawIconsEnabled
Expand All @@ -527,10 +536,20 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer
}

/// Draws a value at the specified x and y position.
@objc open func drawValue(context: CGContext, value: String, xPos: CGFloat, yPos: CGFloat, font: NSUIFont, align: NSTextAlignment, color: NSUIColor)
@objc open func drawValue(context: CGContext, value: String, xPos: CGFloat, yPos: CGFloat, font: NSUIFont, align: NSTextAlignment, color: NSUIColor, anchor: CGPoint, angleRadians: CGFloat)
{
context.drawText(value, at: CGPoint(x: xPos, y: yPos), align: align, attributes: [.font: font, .foregroundColor: color])
if (angleRadians == 0.0)
{
context.drawText(value, at: CGPoint(x: xPos, y: yPos), align: align, attributes: [.font: font, .foregroundColor: color])
}
else
{
// align left to center text with rotation
context.drawText(value, at: CGPoint(x: xPos, y: yPos), align: align, anchor: anchor,
angleRadians: angleRadians, attributes: [.font: font, .foregroundColor: color])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no line break please

}
}


open override func drawExtras(context: CGContext)
{
Expand Down
3 changes: 3 additions & 0 deletions Source/Charts/Renderers/BubbleChartRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ open class BubbleChartRenderer: BarLineScatterCandleBubbleRenderer
let valueToPixelMatrix = trans.valueToPixelMatrix

let iconsOffset = dataSet.iconsOffset

let angleRadians = dataSet.valueRotationAngle.DEG2RAD

for j in _xBounds.min..._xBounds.range + _xBounds.min
{
Expand Down Expand Up @@ -182,6 +184,7 @@ open class BubbleChartRenderer: BarLineScatterCandleBubbleRenderer
at: CGPoint(x: pt.x,
y: pt.y - (0.5 * lineHeight)),
align: .center,
angleRadians: angleRadians,
attributes: [.font: valueFont,
.foregroundColor: valueTextColor])
}
Expand Down
3 changes: 3 additions & 0 deletions Source/Charts/Renderers/CandleStickChartRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ open class CandleStickChartRenderer: LineScatterCandleRadarRenderer

let iconsOffset = dataSet.iconsOffset

let angleRadians = dataSet.valueRotationAngle.DEG2RAD

_xBounds.set(chart: dataProvider, dataSet: dataSet, animator: animator)

let lineHeight = valueFont.lineHeight
Expand Down Expand Up @@ -299,6 +301,7 @@ open class CandleStickChartRenderer: LineScatterCandleRadarRenderer
at: CGPoint(x: pt.x,
y: pt.y - yOffset),
align: .center,
angleRadians: angleRadians,
attributes: [.font: valueFont,
.foregroundColor: dataSet.valueTextColorAt(j)])
}
Expand Down
14 changes: 11 additions & 3 deletions Source/Charts/Renderers/HorizontalBarChartRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@ open class HorizontalBarChartRenderer: BarChartRenderer
{
guard let dataSet = dataSets[dataSetIndex] as? BarChartDataSetProtocol else { continue }

let angleRadians = dataSet.valueRotationAngle.DEG2RAD

if !shouldDrawValues(forDataSet: dataSet) || !(dataSet.isDrawIconsEnabled && dataSet.isVisible)
{
continue
Expand Down Expand Up @@ -392,7 +394,9 @@ open class HorizontalBarChartRenderer: BarChartRenderer
yPos: y + yOffset,
font: valueFont,
align: textAlign,
color: dataSet.valueTextColorAt(j))
color: dataSet.valueTextColorAt(j),
anchor: CGPoint.zero,
angleRadians: angleRadians)
}

if let icon = e.icon, dataSet.isDrawIconsEnabled
Expand Down Expand Up @@ -470,7 +474,9 @@ open class HorizontalBarChartRenderer: BarChartRenderer
yPos: rect.origin.y + yOffset,
font: valueFont,
align: textAlign,
color: dataSet.valueTextColorAt(index))
color: dataSet.valueTextColorAt(index),
anchor: CGPoint.zero,
angleRadians: angleRadians)
}

if let icon = e.icon, dataSet.isDrawIconsEnabled
Expand Down Expand Up @@ -569,7 +575,9 @@ open class HorizontalBarChartRenderer: BarChartRenderer
yPos: y + yOffset,
font: valueFont,
align: textAlign,
color: dataSet.valueTextColorAt(index))
color: dataSet.valueTextColorAt(index),
anchor: CGPoint.zero,
angleRadians: angleRadians)
}

if let icon = e.icon, dataSet.isDrawIconsEnabled
Expand Down
4 changes: 3 additions & 1 deletion Source/Charts/Renderers/LineChartRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,8 @@ open class LineChartRenderer: LineRadarRenderer

let formatter = dataSet.valueFormatter

let angleRadians = dataSet.valueRotationAngle.DEG2RAD

let trans = dataProvider.getTransformer(forAxis: dataSet.axisDependency)
let valueToPixelMatrix = trans.valueToPixelMatrix

Expand Down Expand Up @@ -564,7 +566,7 @@ open class LineChartRenderer: LineRadarRenderer
viewPortHandler: viewPortHandler),
at: CGPoint(x: pt.x,
y: pt.y - CGFloat(valOffset) - valueFont.lineHeight),
align: .center,
angleRadians: angleRadians,
attributes: [.font: valueFont,
.foregroundColor: dataSet.valueTextColorAt(j)])
}
Expand Down
10 changes: 10 additions & 0 deletions Source/Charts/Renderers/PieChartRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ open class PieChartRenderer: NSObject, DataRenderer

let iconsOffset = dataSet.iconsOffset

let angleRadians = dataSet.valueRotationAngle.DEG2RAD

let xValuePosition = dataSet.xValuePosition
let yValuePosition = dataSet.yValuePosition

Expand Down Expand Up @@ -429,6 +431,7 @@ open class PieChartRenderer: NSObject, DataRenderer
context.drawText(valueText,
at: labelPoint,
align: align,
angleRadians: angleRadians,
attributes: [.font: valueFont,
.foregroundColor: valueTextColor])

Expand All @@ -438,6 +441,7 @@ open class PieChartRenderer: NSObject, DataRenderer
at: CGPoint(x: labelPoint.x,
y: labelPoint.y + lineHeight),
align: align,
angleRadians: angleRadians,
attributes: [.font: entryLabelFont ?? valueFont,
.foregroundColor: entryLabelColor ?? valueTextColor])
}
Expand All @@ -450,6 +454,7 @@ open class PieChartRenderer: NSObject, DataRenderer
at: CGPoint(x: labelPoint.x,
y: labelPoint.y + lineHeight / 2.0),
align: align,
angleRadians: angleRadians,
attributes: [.font: entryLabelFont ?? valueFont,
.foregroundColor: entryLabelColor ?? valueTextColor])
}
Expand All @@ -460,6 +465,7 @@ open class PieChartRenderer: NSObject, DataRenderer
at: CGPoint(x: labelPoint.x,
y: labelPoint.y + lineHeight / 2.0),
align: align,
angleRadians: angleRadians,
attributes: [.font: valueFont,
.foregroundColor: valueTextColor])
}
Expand All @@ -476,13 +482,15 @@ open class PieChartRenderer: NSObject, DataRenderer
context.drawText(valueText,
at: CGPoint(x: x, y: y),
align: .center,
angleRadians: angleRadians,
attributes: [.font: valueFont, .foregroundColor: valueTextColor])

if j < data.entryCount && pe?.label != nil
{
context.drawText(pe!.label!,
at: CGPoint(x: x, y: y + lineHeight),
align: .center,
angleRadians: angleRadians,
attributes: [.font: entryLabelFont ?? valueFont,
.foregroundColor: entryLabelColor ?? valueTextColor])
}
Expand All @@ -494,6 +502,7 @@ open class PieChartRenderer: NSObject, DataRenderer
context.drawText(pe!.label!,
at: CGPoint(x: x, y: y + lineHeight / 2.0),
align: .center,
angleRadians: angleRadians,
attributes: [.font: entryLabelFont ?? valueFont,
.foregroundColor: entryLabelColor ?? valueTextColor])
}
Expand All @@ -503,6 +512,7 @@ open class PieChartRenderer: NSObject, DataRenderer
context.drawText(valueText,
at: CGPoint(x: x, y: y + lineHeight / 2.0),
align: .center,
angleRadians: angleRadians,
attributes: [.font: valueFont, .foregroundColor: valueTextColor])
}
}
Expand Down
3 changes: 3 additions & 0 deletions Source/Charts/Renderers/RadarChartRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ open class RadarChartRenderer: LineRadarRenderer
continue
}

let angleRadians = dataSet.valueRotationAngle.DEG2RAD

let entryCount = dataSet.entryCount

let iconsOffset = dataSet.iconsOffset
Expand All @@ -183,6 +185,7 @@ open class RadarChartRenderer: LineRadarRenderer
viewPortHandler: viewPortHandler),
at: CGPoint(x: p.x, y: p.y - yoffset - valueFont.lineHeight),
align: .center,
angleRadians: angleRadians,
attributes: [.font: valueFont,
.foregroundColor: dataSet.valueTextColorAt(j)])
}
Expand Down
3 changes: 3 additions & 0 deletions Source/Charts/Renderers/ScatterChartRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ open class ScatterChartRenderer: LineScatterCandleRadarRenderer

let iconsOffset = dataSet.iconsOffset

let angleRadians = dataSet.valueRotationAngle.DEG2RAD

let shapeSize = dataSet.scatterShapeSize
let lineHeight = valueFont.lineHeight

Expand Down Expand Up @@ -169,6 +171,7 @@ open class ScatterChartRenderer: LineScatterCandleRadarRenderer
at: CGPoint(x: pt.x,
y: pt.y - shapeSize - lineHeight),
align: .center,
angleRadians: angleRadians,
attributes: [.font: valueFont,
.foregroundColor: dataSet.valueTextColorAt(j)]
)
Expand Down
43 changes: 28 additions & 15 deletions Source/Charts/Utils/ChartUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,27 +137,25 @@ extension CGContext {
NSUIGraphicsPopContext()
}

open func drawText(_ text: String, at point: CGPoint, align: NSTextAlignment, attributes: [NSAttributedStringKey : Any]?)
open func drawText(_ text: String, at point: CGPoint, align: NSTextAlignment, anchor: CGPoint = CGPoint(x: 0.5, y: 0.5), angleRadians: CGFloat = 0.0, attributes: [NSAttributedStringKey : Any]?)
{
var point = point

if align == .center
let drawPoint = getDrawPoint(text: text, point: point, align: align, attributes: attributes)
if (angleRadians == 0.0)
{
point.x -= text.size(withAttributes: attributes).width / 2.0
NSUIGraphicsPushContext(self)

(text as NSString).draw(at: drawPoint, withAttributes: attributes)

NSUIGraphicsPopContext()
}
else if align == .right
else
{
point.x -= text.size(withAttributes: attributes).width
drawText(text, at: drawPoint, anchor: anchor, angleRadians: angleRadians, attributes: attributes)
}

NSUIGraphicsPushContext(self)

(text as NSString).draw(at: point, withAttributes: attributes)

NSUIGraphicsPopContext()
}

open func drawText(_ text: String, at point: CGPoint, anchor: CGPoint, angleRadians: CGFloat, attributes: [NSAttributedStringKey : Any]?)
open func drawText(_ text: String, at point: CGPoint, anchor: CGPoint = CGPoint(x: 0.5, y: 0.5), angleRadians: CGFloat, attributes: [NSAttributedStringKey : Any]?)
{
var drawOffset = CGPoint()

Expand Down Expand Up @@ -209,6 +207,21 @@ extension CGContext {
NSUIGraphicsPopContext()
}

func getDrawPoint(text: String, point: CGPoint, align: NSTextAlignment, attributes: [NSAttributedStringKey : Any]?) -> CGPoint
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private func

{
var point = point

if align == .center
{
point.x -= text.size(withAttributes: attributes).width / 2.0
}
else if align == .right
{
point.x -= text.size(withAttributes: attributes).width
}
return point
}

func drawMultilineText(_ text: String, at point: CGPoint, constrainedTo size: CGSize, anchor: CGPoint, knownTextSize: CGSize, angleRadians: CGFloat, attributes: [NSAttributedStringKey : Any]?)
{
var rect = CGRect(origin: .zero, size: knownTextSize)
Expand Down