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

Custom Y Value Formatter #943

Closed
schech-a opened this issue Apr 12, 2016 · 11 comments
Closed

Custom Y Value Formatter #943

schech-a opened this issue Apr 12, 2016 · 11 comments
Labels

Comments

@schech-a
Copy link

First of all, this IOS Library is awesome! Thanks.

I have to display Y values in a BarChart in time format (mn:ss)

I have seen on the IOS documentation that a class called "ChartDefaultXAxisValueFormatter", but I can not find a way to use it.

Have anyone achieved such a thing?

Alexis

@dxclancy
Copy link

Have you looked at the example for stacked bar chart view controller? I imagine it is similar where you pass a formatter?

        NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
        formatter.maximumFractionDigits = 1;
        formatter.negativeSuffix = @" $";
        formatter.positiveSuffix = @" $";

        BarChartData *data = [[BarChartData alloc] initWithXVals:xVals dataSets:dataSets];
        [data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:7.f]];
        [data setValueFormatter:formatter];

        _chartView.data = data;

@liuxuan30
Copy link
Member

@dxclancy pointed it out. Be aware it's a number formatter right now, so you may need write some code to bridge the number and date formatter.

@schech-a
Copy link
Author

Hi there,

Thanks your answer. Unfortunately, leftAxis.valueformatter only accepts NSNumberFormatter.

I am trying to use the ChartDefaultXAxisValueFormatter as in the swift files, but I cannot manage to implement it.

What is need is to display the left(Y) axis as time ex = 1:02:58

Alexis

@dxclancy
Copy link

dxclancy commented Apr 14, 2016

Hi, I assume what you want is to pass an NSDateFormatter?

I see this in the definition:
public var valueFormatter: ChartXAxisValueFormatter?

So you need to have one of your classes implement that protocol

@interface MyChartViewController: < ChartXAxisValueFormatter>

or

@interface MyCustomFormatter: NSObject < ChartXAxisValueFormatter>

or the swift equivalent.

But it sounds like you want to format the yVals, which means you only have access to a NSNumberFormatter. Right?

We are actually having a discussion about a similar issue to this in #742. However, @danielgindi 's position currently seems to be that this is incorrect.

So I think you have 3 options.

  • If ChartXAxisValueFormatter is sufficient, implement the protocol. I can help you with that.
  • If not, the simplest thing to do is to write a subclass of NSNumberFormatter that overrides stringFromNumber and pass that value to an NSDateFormatter, or perform you own custom formatting.
  • If you feel comfortable modifying the library, you can merge the pull request in IChartDataSet valueFormatter is now of NSFormatter type #742 to your own fork and pass an NSDateFormatter, which I think will be able to format time as you wish. Or you can add a ChartYAxisValueFormatter modeled on the ChartXAxisValueFormatter.

Note that I'm fairly new to this wonderful library which has a lot of great options I'm unfamiliar with, so I may be missing something obvious.

@liuxuan30
Copy link
Member

your suggestions are appreciated. We need to think carefully if we want to move the axis formatter to formatters. Thinking that all the data is naturally numbers, we think number formatter is the formatter to use. In case you want to display different strings from the value, you can customize your own. But the formatter's source is number for sure.

@schech-a
Copy link
Author

I used the override method. It worked like a charm!
Thank you guys, you are the best :)

@danielgindi
Copy link
Collaborator

NSNumberFormatter is more correct than NSFormatter simply due to the fact that the value being passed in is always a number. You don't gain anything by using NSFormatter specifically. The fact that you want an output that's not a number, does not change the fact that the input is a number, and you want to format that number in a very special manner.

We will, however, move forward with having our own interface which passes more information along with the value (the ChartYAxisValueFormatter approach).

@danielgindi
Copy link
Collaborator

Having said that - this issue should stay open until we implement the protocol for a Y axis value formatter.

@danielgindi
Copy link
Collaborator

Implemented in Charts 3.0 (v3 branch)

@manishpathak99
Copy link

I achieved it by inheriting IAxisValueFormatter .

import Foundation
import Charts
class YAxisValueFormatter: NSObject, IAxisValueFormatter {

    let numFormatter: NumberFormatter

    override init() {
        numFormatter = NumberFormatter()
        numFormatter.minimumFractionDigits = 1
        numFormatter.maximumFractionDigits = 1

        // if number is less than 1 add 0 before decimal
        numFormatter.minimumIntegerDigits = 1 // how many digits do want before decimal
        numFormatter.paddingPosition = .beforePrefix
        numFormatter.paddingCharacter = "0"
    }

    /// Called when a value from an axis is formatted before being drawn.
    ///
    /// For performance reasons, avoid excessive calculations and memory allocations inside this method.
    ///
    /// - returns: The customized label that is drawn on the axis.
    /// - parameter value:           the value that is currently being drawn
    /// - parameter axis:            the axis that the value belongs to
    ///

    public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
        return numFormatter.string(from: NSNumber(floatLiteral: value))!
    }
}

create YAxisValueFormatterclass, and assign object to graph leftAxis


    // Number formatting of YAxis
    chartView.leftAxis.valueFormatter = YAxisValueFormatter()

@John1843
Copy link

When I inherit IAxisValueFormatter as stated above, I get an error: "No type or protocol named 'IChartAxisValueFormatter'" in my ProjectName-Swift.h file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants