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 ChartXAxisValueFormatter not Being Called with Data containing NSObjects #429

Closed
someoneAnyone opened this issue Sep 28, 2015 · 4 comments

Comments

@someoneAnyone
Copy link

Hi! I'm experimenting with this framework and its really cool, but I've having some trouble figuring out some things... My goal is to re-create a D3 chart as seen below.
d3chart

I'm using the CombinedChartView and in my test code, I'm generating an array of dates.

        var dateArray: [NSObject] = []
        for _ in 0..<20 {
            let aRandomInt = Double(Int.randomRange(100000...200000))  // returns a random number within the given range.
            // dateArray.append("\(aRandomInt)") // Works. My formatter code is called.
             dateArray.append(NSDate(timeIntervalSinceNow: -aRandomInt)) // Does not work. Formatter code isn't called.
            // dateArray.append(NSDate(timeIntervalSinceNow: -aRandomInt).description) // Works. My formatter code is called.
        }
        let data = CombinedChartData(xVals: dateArray)
        data.lineData = generateLineData(dateArray.count)

later I configure my custom formatter..

    func configureBottomAxis(bottomAxis: ChartXAxis) {
        bottomAxis.labelPosition = .Bottom
        bottomAxis.labelTextColor = UIColor.whiteColor()
        bottomAxis.drawGridLinesEnabled = false
        bottomAxis.valueFormatter = MyFormatter()
    }
class MyFormatter: NSObject, ChartXAxisValueFormatter {

    override init() {
        super.init()
    }

    @objc func stringForXValue(index: Int, original: String, viewPortHandler: ChartViewPortHandler) -> String {
        print("stringForXValue:\(index) original: \(original), viewPortHandler:\(viewPortHandler)" )

        return "modified: \(original)"
    }

}

But as you can see from code comments above, if I pass in an object MyFormatter() is never called. It only happens if I pass in a string. Is this intentional? Am I approaching this the wrong way? Is there another method I can use to get the object?

Thanks!

@liuxuan30
Copy link
Member

I think I figure it out:
Swift does not support multiple inheritance, following Objective C in this.
class MyFormatter: ChartXAxisValueFormatter should be enough
class MyFormatter: NSObject, ChartXAxisValueFormatter this will inherits from NSObject, not a formatter

@someoneAnyone
Copy link
Author

Even with the change (removing NSObject), It doesn't get called when I place an object like NSdatecomponents into the xAxis array.

@danielgindi
Copy link
Collaborator

@someoneAnyone you cannot pass NSDateComponents to the xAxis array.

You can only pass Strings or nils. In ObjC you can pass NSString or NSNull, which is why you can pass an NSObject - for translating between objc's "nullable" type to a real nullable type of Swift.

I really hope that in the next Swift version we will be able to specify that a specific function is not available in Swift, but only in ObjC. This way we'll hide the ObjC bridges from Swift consumers.

@someoneAnyone
Copy link
Author

Ok, one way I got around this was by passing a time interval as a string then using the custom formatter to turn into a date string. But I'm having a hard time keeping the x-axis sync to line data.... Any tips on how to do that in the combined chart view? As you can seen the image above I'm trying to get a time series type visual going. here is where I'm at with it now... My values aren't matching up... with the time on x-axis.

simulator-screen-shot-sep-30_-2015_-1 56 00-pm

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

No branches or pull requests

3 participants