이끼의 생각

[iOS Swift]Charts x, y 축 값 커스텀 본문

Mobile App/iOS와 Swift

[iOS Swift]Charts x, y 축 값 커스텀

IKKIson 2019. 5. 7. 05:02

안드로이드와 iOS를 개발하면서 그래프가 필요한 경우 가장 유명한 오픈소스인 Charts 를 사용하게 될 것이다.

 

안드로이드 버전 Charts

https://github.com/PhilJay/MPAndroidChart

 

PhilJay/MPAndroidChart

A powerful 🚀 Android chart view / graph view library, supporting line- bar- pie- radar- bubble- and candlestick charts as well as scaling, dragging and animations. - PhilJay/MPAndroidChart

github.com

 

iOS 버전 Charts

https://github.com/danielgindi/Charts

 

danielgindi/Charts

Beautiful charts for iOS/tvOS/OSX! The Apple side of the crossplatform MPAndroidChart. - danielgindi/Charts

github.com

 

Charts 가 한사람에 의핸 개발된 것이 아니며 iOS버전을 사용할 경우 먼저 개발된 안드로이드에서 구현한 모든기능들이 구현되어 있지않다. 뿐만아니라 없는 기능도 상당하여 개발자 본인이 직접 커스텀을 해야하는 경우가 발생한다.

 

그래프를 그리면 X, Y축의 값의 자료형을 다양하게 정하여 사용하는데 iOS에서는 Formatter를 직접 커스텀해야된다.

이유는 다음과 값다.

let values = (0..<count).map { (i) -> ChartDataEntry in
            let val = Double(arc4random_uniform(range) + 3)
            return ChartDataEntry(x: Double(i), y: val, icon: #imageLiteral(resourceName: "icon"))
        }
        
        let set1 = LineChartDataSet(entries: values, label: "DataSet 1")

(위의 소스코드는 iOS버전의 Charts의 demo 소스를 인용하였다.)

출처 : http://ChartsDemo-iOS/Swift/Demos/LineChart1ViewController.swift

 

위 소스에서 보면 데이터셋을 만드는 과정인데,  그래프에 그려줄 정의역과 치역의 값들(x, y)을 values 변수에 ChartDataEntry 타입으로 선언하면서 ChartDatEnrtry()를 볼 수 있다. ChartDataEntry 데이터를 생성할 때 iOS에서는 x와 y값의 파라미터들은 Double형 만 가능하게 된다. 이렇게 되면 실제 그래프를 View에 생성하면 데이터를 표현하는데 한계가 발생하는 것이다.

 

결국 이를 해결하기 위해 View에서 그래프가 그려질 때 X축이나 Y축을 자신이 원하는 자료형으로 표현하기 위한 Formatter 커스텀이 요구가 되는것이다.

일반적으로 데이터 표현범위가 많은 소숫점, 10의 제곱(Exponential)을 직접 커스텀 해보겠다.

8Byte의 표현범위를 가진 Double형의 데이터를 "E+2", "6E+8" 등으로 표현하기 위해 아래의 소스를 구현한다.

extension Double {
    struct Number {
        static var formatter = NumberFormatter()
    }
    var scientificStyle: String {
        Number.formatter.numberStyle = .scientific
        Number.formatter.positiveFormat = "0.###E+0"
        Number.formatter.exponentSymbol = "e"
        let number = NSNumber(value: self)
        return Number.formatter.string(from :number) ?? description
    }
}

1. Formatter

- Foundation에 정의된 추상클래스로 값의 텍스트 표현을 생성, 해석, 검증하는 오브젝트의 인터페이스를 선언하는 추상 클래스이다.

 

2. NumberFormatter

- 숫자 값과 텍스트 값을 표현하기 위해 이들 사이를 변환하는 포맷터이다. Formatter 클래스의 파생클래스이다.

 

3. Number.formatter.numberStyle

- NumberFormatter.Style은 다양하게 표현할 수 있는 수치방식들을 미리 결정된 값 집합이다(enum), 예를들어 10 진수 값, 백분율 값 및 통화에 사용되는 스타일들이 있다.

- Number.formatter.numberStyle = .scientific 에서는 표현할 스타일을 NumberFormatter.Style에 미리 선언된 scientific을 사용할 것이고 이것은 10의 제곱을 E(Exponential)를 사용한다는 뜻이다.

(NumberFormatter의 스타일 : https://developer.apple.com/documentation/foundation/numberformatter/style)


4. Number.formatter.positiveFormat

- 양수값을 표현할 때 어떠게 표현할 지 정한다. C언어의 printf함수의 서식 지정자와 유사하다. 

 

 

5. Number.formatter.exponentSymbol

- 지수 기호를 사용할 때 사용한다.

- 여기서 Exponential 라틴 대문자 e (E)로 설정된다.

- 지수 기호는 표기법에서 "1.0E + 42"와 같이 "E"또는 "e"이 된다.

 

 

커스텀이 끝났으니 실제로 적용해보자.

...
let data = LineChartData(dataSet: set1)
        
chartView.data = data

그래프 생성을 해주는 함수의 마지막 부분에 미리 커스텀한 함수를 호출해주면 그래프 내의 실제 값들은 유지되며 x/y 축의 UI에 보여주는 값들만 변하게 된다.

 

 

 

<주의!>

이글에서는 많은 양의 수치값을 다룰 때를 고려하여 설명을 하였다. 만약 본인이 생성하는 그래프가 몇가지의 항목들의 이름을 축의 값으로 표현하는 경우처럼 미리 제한된 값이라면 ChartDataEntry를 무시하고 Formatter를 사용하는 방법을 찾아보면 된다.

 

 

출처 : https://stackoverflow.com/questions/31934088/convert-double-to-scientific-notation-in-swift

Comments