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

Is there a way to use Line Chart with custom xAxis? #3579

Closed
katisari opened this issue Jul 25, 2018 · 14 comments
Closed

Is there a way to use Line Chart with custom xAxis? #3579

katisari opened this issue Jul 25, 2018 · 14 comments

Comments

@katisari
Copy link

I'm trying to create a Line Chart with custom xAxis labels.
I want to put different categories in the axis for such as ["january", "Feb", "March"]. Is there any way to do that for line charts?

@MaxDesiatov
Copy link

Strong +1 for this, my use case is displaying time series data, where x values are of NSTimeInterval type, but should be formatted as dates on the x axis.

@katisari
Copy link
Author

katisari commented Jul 25, 2018 via email

@thierryH91200
Copy link
Contributor

look at #3069

@MaxDesiatov
Copy link

MaxDesiatov commented Jul 25, 2018

It only appears as a formatted Double, because ChartDataEntry type is not generic and supports only Double for both x and y, while it doesn't provide any customisation points for formatting at all.

@katisari
Copy link
Author

Does this mean that I won't be able to insert strings on the x-axis? Would it be only possible for barographs? I want to use a line graph but with categories in strings on the x-axis.

@MaxDesiatov
Copy link

MaxDesiatov commented Jul 25, 2018

After a quick investigation, looks like IAxisValueFormatter could solve this:

import Charts
import UIKit

final class DateValueFormatter: IAxisValueFormatter {
  func stringForValue(_ value: Double, axis: AxisBase?) -> String {
    return formatter.string(from: Date(timeIntervalSinceReferenceDate: value))
  }

  let formatter: DateFormatter

  init(formatter: DateFormatter) {
    self.formatter = formatter
  }
}

let dataSetSize: CGFloat = 14

final class ViewController: UIViewController {
  @IBOutlet weak var chartView: LineChartView!

  func refresh() {
    // Do any additional setup after loading the view.
    let ys1 = Array(1..<10).map { sin(Double($0) / 2.0 / 3.141 * 1.5) }
    let ys2 = Array(1..<10).map { cos(Double($0) / 2.0 / 3.141) }

    let yse1 = ys1.enumerated().map { ChartDataEntry(x: Double($0), y: $1) }
    let yse2 = ys2.enumerated().map { ChartDataEntry(x: Double($0), y: $1) }

    let data = LineChartData()
    let ds1 = LineChartDataSet(values: yse1, label: "Hello")
    ds1.valueFont = .systemFont(ofSize: dataSetSize)
    ds1.colors = [.red]
    data.addDataSet(ds1)

    let ds2 = LineChartDataSet(values: yse2, label: "World")
    ds2.valueFont = .systemFont(ofSize: dataSetSize)
    ds2.colors = [.blue]
    data.addDataSet(ds2)

    let f = DateFormatter()
    f.dateStyle = .short
    chartView.xAxis.valueFormatter = DateValueFormatter(formatter: f)
    chartView.data = data

    chartView.gridBackgroundColor = .lightGray
    chartView.backgroundColor = .white

    chartView.chartDescription?.text = "Linechart Demo"
  }

  override func viewDidLoad() {
    super.viewDidLoad()

    refresh()
  }
}

@thierryH91200
Copy link
Contributor

it's false

final class DateValueFormatter: IAxisValueFormatter {
  func stringForValue(_ value: Double, axis: AxisBase?) -> String {
    return formatter.string(from: Date(timeIntervalSinceReferenceDate: value))
  }

  let formatter: DateFormatter

  init(formatter: DateFormatter) {
    self.formatter = formatter
  }
}

IAxisValueFormatter is obsolete

@MaxDesiatov
Copy link

@thierryH91200 would you kindly provide any documentation or references that confirm that this protocol is obsolete? In the latest Charts 3.1.1 it's not marked as either obsolete or deprecated and the example code I provided works perfectly well and is able to change X axis labels without a problem.

Please have a look at the attached screenshot, which is made from the example code from my comment above.

screen shot 2018-07-25 at 17 11 32

@thierryH91200
Copy link
Contributor

thierryH91200 commented Jul 25, 2018

it's a mistake
mea culpa
I work with 4.0.0

I was too fast

@objc(ChartAxisBase)
open class AxisBase: ComponentBase
{
    public override init()
    {
        super.init()
    }
    
    /// Custom formatter that is used instead of the auto-formatter if set
    private lazy var _axisValueFormatter: AxisValueFormatter = DefaultAxisValueFormatter(decimals: decimals)
    
    @objc open var labelFont = NSUIFont.systemFont(ofSize: 10.0)
    @objc open var labelTextColor = NSUIColor.black
  

@katisari
Copy link
Author

katisari commented Jul 25, 2018


screen shot 2018-07-25 at 9 29 08 am

This is what I'm getting. But I want the x-axis labels to be a string and not in the format of a date. Specifically, I want to put ["height", age"] in the x-axis. Is there a way to do this?

@MaxDesiatov
Copy link

MaxDesiatov commented Jul 25, 2018

@katisari change func stringForValue(_ value: Double, axis: AxisBase?) -> String in your IAxisValueFormatter implementation to convert X values to strings as needed. I don't know what are your sample X values to provide more info.

@katisari
Copy link
Author

katisari commented Jul 25, 2018

Okay that works! But do I have to use date formatter in the class that's inheriting from the IAxisValueFormatter? Am I allowed to change formatter variable to type String? It throws me an error when I try to do that.

@MaxDesiatov
Copy link

MaxDesiatov commented Jul 25, 2018

@katisari you don't have to use a date formatter, you can produce whatever string is needed as long as your formatter conforms to IAxisValueFormatter protocol, which is super-simple: https://github.com/danielgindi/Charts/blob/v3.1.1/Source/Charts/Formatters/IAxisValueFormatter.swift

@liuxuan30
Copy link
Member

Seems it's answered by great people, closing.

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

4 participants