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

Add rounded corners on the bar chart #1066 #1917

Closed
wants to merge 2 commits into from
Closed
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
22 changes: 22 additions & 0 deletions ChartsDemo/Classes/DemoBaseViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,28 @@ - (void)handleOption:(NSString *)key forChartView:(ChartViewBase *)chartView

[chartView setNeedsDisplay];
}

if ([key isEqualToString:@"toggleRoundedBarsAllCorners"])
{
((BarChartView *)chartView).drawRoundedBarEnabled = YES;

[chartView setNeedsDisplay];
}

if ([key isEqualToString:@"toggleRoundedBarsTopCorners"])
{
((BarChartView *)chartView).drawRoundedBarEnabled = YES;

for (id<IBarChartDataSet, NSObject> set in chartView.data.dataSets)
{
if ([set conformsToProtocol:@protocol(IBarChartDataSet)])
{
set.barRoundingCorners = UIRectCornerTopLeft | UIRectCornerTopRight;
}
}

[chartView setNeedsDisplay];
}
}

#pragma mark - Actions
Expand Down
2 changes: 2 additions & 0 deletions ChartsDemo/Classes/Demos/BarChartViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ - (void)viewDidLoad
@{@"key": @"toggleAutoScaleMinMax", @"label": @"Toggle auto scale min/max"},
@{@"key": @"toggleData", @"label": @"Toggle Data"},
@{@"key": @"toggleBarBorders", @"label": @"Show Bar Borders"},
@{@"key": @"toggleRoundedBarsAllCorners", @"label": @"All Corners Rounded"},
@{@"key": @"toggleRoundedBarsTopCorners", @"label": @"Top Corners Rounded"},
];

[self setupBarLineChartView:_chartView];
Expand Down
17 changes: 17 additions & 0 deletions Source/Charts/Charts/BarChartView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ open class BarChartView: BarLineChartViewBase, BarChartDataProvider
/// if set to true, a grey area is drawn behind each bar that indicates the maximum value
fileprivate var _drawBarShadowEnabled = false

/// if set to true, a rounded rectangle with the corners is drawn on each bar
fileprivate var _drawRoundedBarEnabled = false

internal override func initialize()
{
super.initialize()
Expand Down Expand Up @@ -159,6 +162,17 @@ open class BarChartView: BarLineChartViewBase, BarChartDataProvider
setNeedsDisplay()
}
}

/// if set to true, a rounded rectangle with the corners is drawn on each bar
open var drawRoundedBarEnabled: Bool
{
get { return _drawRoundedBarEnabled }
set
{
_drawRoundedBarEnabled = newValue
setNeedsDisplay()
}
}

/// Adds half of the bar width to each side of the x-axis range in order to allow the bars of the barchart to be fully displayed.
/// **default**: false
Expand All @@ -180,4 +194,7 @@ open class BarChartView: BarLineChartViewBase, BarChartDataProvider

/// - returns: `true` if drawing shadows (maxvalue) for each bar is enabled, `false` ifnot
open var isDrawBarShadowEnabled: Bool { return drawBarShadowEnabled }

/// - returns: `true` if drawing rounded bars is enabled, `false` ifnot

Choose a reason for hiding this comment

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

ifnot typo

open var isDrawRoundedBarEnabled: Bool { return drawRoundedBarEnabled }
}
10 changes: 10 additions & 0 deletions Source/Charts/Charts/CombinedChartView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ open class CombinedChartView: BarLineChartViewBase, CombinedChartDataProvider
get { return (renderer as! CombinedChartRenderer!).drawBarShadowEnabled }
set { (renderer as! CombinedChartRenderer!).drawBarShadowEnabled = newValue }
}

/// if set to true, a rounded rectangle with the corners is drawn on each bar
open var drawRoundedBarEnabled: Bool
{
get { return (renderer as! CombinedChartRenderer!).drawRoundedBarEnabled }
set { (renderer as! CombinedChartRenderer!).drawRoundedBarEnabled = newValue }
}

/// - returns: `true` if drawing values above bars is enabled, `false` ifnot
open var isDrawValueAboveBarEnabled: Bool { return (renderer as! CombinedChartRenderer!).drawValueAboveBarEnabled }
Expand Down Expand Up @@ -222,4 +229,7 @@ open class CombinedChartView: BarLineChartViewBase, CombinedChartDataProvider

/// - returns: `true` the highlight is be full-bar oriented, `false` ifsingle-value
open var isHighlightFullBarEnabled: Bool { return highlightFullBarEnabled }

/// - returns: `true` if drawing rounded bars is enabled, `false` ifnot
punano marked this conversation as resolved.
Show resolved Hide resolved
open var isDrawRoundedBarEnabled: Bool { return drawRoundedBarEnabled }
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ open class BarChartDataSet: BarLineScatterCandleBubbleChartDataSet, IBarChartDat
/// the color drawing borders around the bars.
open var barBorderColor = NSUIColor.black

#if !os(OSX)
/// the option rounding bar corners
open var barRoundingCorners: UIRectCorner = .allCorners
#endif

/// the alpha value (transparency) that is used for drawing the highlight indicator bar. min = 0.0 (fully transparent), max = 1.0 (fully opaque)
open var highlightAlpha = CGFloat(120.0 / 255.0)

Expand Down
5 changes: 5 additions & 0 deletions Source/Charts/Data/Interfaces/IBarChartDataSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ public protocol IBarChartDataSet: IBarLineScatterCandleBubbleChartDataSet
/// the color drawing borders around the bars.
var barBorderColor: NSUIColor { get set }

#if !os(OSX)
/// the option rounding bar corners
var barRoundingCorners: UIRectCorner { get set }
#endif

/// the alpha value (transparency) that is used for drawing the highlight indicator bar. min = 0.0 (fully transparent), max = 1.0 (fully opaque)
var highlightAlpha: CGFloat { get set }

Expand Down
3 changes: 2 additions & 1 deletion Source/Charts/Interfaces/BarChartDataProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public protocol BarChartDataProvider: BarLineScatterCandleBubbleChartDataProvide
var barData: BarChartData? { get }

var isDrawBarShadowEnabled: Bool { get }
var isDrawRoundedBarEnabled: Bool { get }
var isDrawValueAboveBarEnabled: Bool { get }
var isHighlightFullBarEnabled: Bool { get }
}
}
55 changes: 46 additions & 9 deletions Source/Charts/Renderers/BarChartRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -310,14 +310,36 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer
// Set the color for the currently drawn value. If the index is out of bounds, reuse colors.
context.setFillColor(dataSet.color(atIndex: j).cgColor)
}

context.fill(barRect)

if drawBorder

if dataProvider.isDrawRoundedBarEnabled
{
context.setStrokeColor(borderColor.cgColor)
context.setLineWidth(borderWidth)
context.stroke(barRect)
let cornerRadius = CGSize(width: barRect.width / 2.0, height: barRect.width / 2.0)

Choose a reason for hiding this comment

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

It would be nice if this was a property instead, so that we can specify a custom corner radius.

#if os(OSX)
let bezierPath = NSBezierPath(roundedRect: barRect, xRadius: cornerRadius.width, yRadius: cornerRadius.height)
Copy link
Member

Choose a reason for hiding this comment

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

Just FYI, I came across API like CGPathCreateWithRoundedRect() and CGPathAddRoundedRect(), looks like we can replace the UIBezierPath APIs?

context.addPath(bezierPath.cgPath)
#else
let bezierPath = UIBezierPath(roundedRect: barRect, byRoundingCorners: dataSet.barRoundingCorners, cornerRadii: cornerRadius)
context.addPath(bezierPath.cgPath)
#endif
context.fillPath()

if drawBorder
{
bezierPath.lineWidth = borderWidth
borderColor.setStroke()
bezierPath.stroke()
}
}
else
{
context.fill(barRect)

if drawBorder
{
context.setStrokeColor(borderColor.cgColor)
context.setLineWidth(borderWidth)
context.stroke(barRect)
}
}
}

Expand Down Expand Up @@ -574,7 +596,7 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer
let set = barData.getDataSetByIndex(high.dataSetIndex) as? IBarChartDataSet,
set.isHighlightEnabled
else { continue }

if let e = set.entryForXValue(high.x, closestToY: high.y) as? BarChartDataEntry
{
if !isInBoundsX(entry: e, dataSet: set)
Expand Down Expand Up @@ -617,7 +639,22 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer

setHighlightDrawPos(highlight: high, barRect: barRect)

context.fill(barRect)
if dataProvider.isDrawRoundedBarEnabled
{
let cornerRadius = CGSize(width: barRect.width / 2.0, height: barRect.width / 2.0)
#if os(OSX)
let bezierPath = NSBezierPath(roundedRect: barRect, xRadius: cornerRadius.width, yRadius: cornerRadius.height)
context.addPath(bezierPath.cgPath)
#else
let bezierPath = UIBezierPath(roundedRect: barRect, byRoundingCorners: set.barRoundingCorners, cornerRadii: cornerRadius)
context.addPath(bezierPath.cgPath)
#endif
context.fillPath()
}
else
{
context.fill(barRect)
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions Source/Charts/Renderers/CombinedChartRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ open class CombinedChartRenderer: DataRenderer
/// if set to true, a grey area is drawn behind each bar that indicates the maximum value
open var drawBarShadowEnabled = false

/// if set to true, a rounded rectangle with the corners is drawn on each bar
open var drawRoundedBarEnabled = false

internal var _renderers = [DataRenderer]()

internal var _drawOrder: [CombinedChartView.DrawOrder] = [.bar, .bubble, .line, .candle, .scatter]
Expand Down
48 changes: 48 additions & 0 deletions Source/Charts/Utils/Platform.swift
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,54 @@ types are aliased to either their UI* implementation (on iOS) or their NS* imple
}
}
}

extension NSBezierPath
{
var cgPath: CGPath
{
let mutablePath = CGMutablePath()
var points = [CGPoint](repeating: .zero, count: 3)
for i in 0 ..< elementCount
{
let type = element(at: i, associatedPoints: &points)
switch type
{
case .moveToBezierPathElement:
mutablePath.move(
to: CGPoint(
x: points[0].x,
y: points[0].y
)
)
case .lineToBezierPathElement:
mutablePath.addLine(
to: CGPoint(
x: points[0].x,
y: points[0].y
)
)
case .curveToBezierPathElement:
mutablePath.addCurve(
to: CGPoint(
x: points[2].x,
y: points[2].y
),
control1: CGPoint(
x: points[0].x,
y: points[0].y
),
control2: CGPoint(
x: points[1].x,
y: points[1].y
)
)
case .closePathBezierPathElement:
mutablePath.closeSubpath()
}
}
return mutablePath
}
}

extension NSString
{
Expand Down
5 changes: 5 additions & 0 deletions Source/ChartsRealm/Data/RealmBarDataSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ open class RealmBarDataSet: RealmBarLineScatterCandleBubbleDataSet, IBarChartDat
/// the color drawing borders around the bars.
open var barBorderColor = NSUIColor(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha: 1.0)

#if !os(OSX)
/// the option rounding bar corners
open var barRoundingCorners: UIRectCorner = .allCorners
#endif

/// the alpha value (transparency) that is used for drawing the highlight indicator bar. min = 0.0 (fully transparent), max = 1.0 (fully opaque)
open var highlightAlpha = CGFloat(120.0 / 255.0)

Expand Down