Charts: Named axis support?

Created on 18 Apr 2015  ·  36Comments  ·  Source: danielgindi/Charts

2015-04-19 00-48-45 lifts rimmer sk last -1

Looked at android wiki, but did not find the possibility to name x or y axis.

Is that possible?

feature help wanted ★★★

Most helpful comment

I just ran into this as well. It's too bad this feature request has been open for about 4 years now. To implement it I wrote my own custom y-axis renderer. To accomplish such a title on the left axis you can do something like this:

In your chart configuration:

leftAxis.xOffset = 45
leftYAxisRenderer = MyYAxisRenderer(viewPortHandler: viewPortHandler, yAxis: leftAxis, transformer: getTransformer(forAxis: .left))

And create your custom renderer:

class MyYAxisRenderer: YAxisRenderer {
    private static let titleLabelPadding: CGFloat = 20

    /**
     Unfortunately iOS Charts has marked many of its methods with internal visibily
     so they cannot be customized. Instead you often need to re-implement logic from
     the charting framework.
    */
    override func renderAxisLabels(context: CGContext) {
        // Render the y-labels.
        super.renderAxisLabels(context: context)

        // Render the y-axis title using our custom renderer.
        renderTitle(title: "Lorem ipsum dolor sit amet", inContext: context, x: MyYAxisRenderer.titleLabelPadding)
    }
}

// MARK: Y-Axis titles.
private extension MyYAxisRenderer {
    func renderTitle(title: String, inContext context: CGContext, x: CGFloat) {
        guard let yAxis = self.axis as? YAxis else { return }

        let attributes: [NSAttributedString.Key: Any] = [
            .font: yAxis.labelFont,
            .foregroundColor: yAxis.labelTextColor
        ]

        // Determine the chart title's y-position.
        let titleSize = title.size(withAttributes: attributes)
        let verticalTitleSize = CGSize(width: titleSize.height, height: titleSize.width)
        let point = CGPoint(x: x, y: (viewPortHandler.chartHeight - verticalTitleSize.height) / 2)

        // Render the chart title.
        ChartUtils.drawText(context: context,
                            text: title,
                            point: point,
                            attributes: attributes,
                            anchor: .zero,
                            angleRadians: .pi / -2)
    }
}

This example will render the y-axis title with a left offset / padding of 20px, and the y-axis labels with a left offset of 45px.

I hope this helps some people...

All 36 comments

Everything that is supported in the Android version is supported here with the exact same API !

@danielgindi I understand this and already read the docs but maybe I've missed something, do you know the answer to my question?

Well currently it is not implemented - I currently am not planning on implementing, so you can do it :-)
Or you can ask for it on the MPAndroidChart repo and when it's done I'll pull it here too

+1, This would be awesome and an important feature - we're all taught since grade school to title our axes! :)

it is possible. I have done this before. just similar to rotating the x axis labels. The whole point is calculating the correct anchor point for rotation.

I could do a PR, but the question is, what I did is simply 90 rotation and centered in the middle of y axis with a simple text and text color, font. Once we officially support it, people would ask more, like different angle, position, multiple lines, etc... That's painful

I don't quite follow your explanation, because there's no axis label property to apply rotation and centering to. Do you just mean you manually added a label to the chart view and manually applied some transforms to it?

Respectfully, I suggest that even basic axis labels would be a huge benefit, and you wouldn't be forced to support any more features than you want to (after all, you're currently not planning to support this one). Hope you'll reconsider!

@UberJason I mean I subclassed the axis class and apply an axisName property and made toe rotation. Most customized work could use subclass + override to achieve.

I am on vacation.. so I may check my old code and file a PR for v3.

+1 Would love to see this feature

+1 Would love to see this feature

+1 Would love to see this feature

+1 Would love to see this feature

is this implemented?

+1 Would love to see this feature

+1

Is there a way to get a frame position that one could use to insert any custom UIView?

+1 would love to see that feature

is this implemented? i need this.

There is a PR #2387 , but not reviewed yet.

+1 would love to see that feature

+1 would love to see that feature

+1 would love to see this feature. .....

+1 would love to see that feature

+1 this feature would be great!!

+1

look at #2452 and #2387

+1 would love to see that feature

+1 me too

Could really use this feature....

I do want this feature too.

Waiting for it....

Me too............

I do want this feature too..

I do want this feature too.. I'm tired for every update of the rewrite

I've seen a lot of talk on adding axis titles on multiple threads, but still haven't found a code example of how to add them. I'm using Swift 4.2. My chart is working great other than I can't get axis titles to show up. Does anyone have a code example?

I just ran into this as well. It's too bad this feature request has been open for about 4 years now. To implement it I wrote my own custom y-axis renderer. To accomplish such a title on the left axis you can do something like this:

In your chart configuration:

leftAxis.xOffset = 45
leftYAxisRenderer = MyYAxisRenderer(viewPortHandler: viewPortHandler, yAxis: leftAxis, transformer: getTransformer(forAxis: .left))

And create your custom renderer:

class MyYAxisRenderer: YAxisRenderer {
    private static let titleLabelPadding: CGFloat = 20

    /**
     Unfortunately iOS Charts has marked many of its methods with internal visibily
     so they cannot be customized. Instead you often need to re-implement logic from
     the charting framework.
    */
    override func renderAxisLabels(context: CGContext) {
        // Render the y-labels.
        super.renderAxisLabels(context: context)

        // Render the y-axis title using our custom renderer.
        renderTitle(title: "Lorem ipsum dolor sit amet", inContext: context, x: MyYAxisRenderer.titleLabelPadding)
    }
}

// MARK: Y-Axis titles.
private extension MyYAxisRenderer {
    func renderTitle(title: String, inContext context: CGContext, x: CGFloat) {
        guard let yAxis = self.axis as? YAxis else { return }

        let attributes: [NSAttributedString.Key: Any] = [
            .font: yAxis.labelFont,
            .foregroundColor: yAxis.labelTextColor
        ]

        // Determine the chart title's y-position.
        let titleSize = title.size(withAttributes: attributes)
        let verticalTitleSize = CGSize(width: titleSize.height, height: titleSize.width)
        let point = CGPoint(x: x, y: (viewPortHandler.chartHeight - verticalTitleSize.height) / 2)

        // Render the chart title.
        ChartUtils.drawText(context: context,
                            text: title,
                            point: point,
                            attributes: attributes,
                            anchor: .zero,
                            angleRadians: .pi / -2)
    }
}

This example will render the y-axis title with a left offset / padding of 20px, and the y-axis labels with a left offset of 45px.

I hope this helps some people...

Trying a simpler workaround using SwiftUI:
https://github.com/danielgindi/Charts/issues/4405

Was this page helpful?
0 / 5 - 0 ratings