表示させるプロット
iOS-Charts を利用して、霧箱で認識された各トラックについての、「時間変化」、「長さの分布」、「方向の分布」等のプロットを表示させる (図1)。
iOS-Charts については、以下のサイトを参照しました。
How to Use iOS Charts API to Create Beautiful Charts in Swift:
https://www.appcoda.com/ios-charts-api-tutorial/
図1. 画面を右にスクロールさせることで、カメラ画面の上にグラフを重ねる形で表示させる。
BarChartView
霧箱で認識されたトラックの長さの分布をプロットするのに、ヒストグラムを表示させるのに適していそうな BarChartView を利用することにします。まず、Main.StoryBoard 上に View を配置し、配置した View の class を BarChartView に変更します。下の例では、plotLength としてコードに紐付けをしています。この後に、下の例のように必要なコードを加えていきます。実際の表示を図2に示します。
class ViewController: UIViewController{
var dataLength = [[Double]]()
@IBOutlet weak var plotLength: BarChartView!
override func viewDidLoad(){
super.viewDidLoad()
// 2次元配列 dataLength に、xとyの値をセットする処理を行う。
// 具体的な中身は、ここでは省略。
setData( val: dataLength )
// setData で値の入れられた2次元配列 dataLength を、バーグラフで表示するための処理。
setChart( val: dataLength )
}
func setChart( val: [[Double]] ){
var entry: [ BarChartDataEntry ] = []
let start = val[0].first
let end = val[0].last
let num = val[0].count
// 表示させるデータの値を BarChartDataEntry にセットする。
for i in 0..<num {
entry.append( BarChartDataEntry( x: Double( i ), y: val[1][i] ) )
}
let dataSet = BarChartDataSet( entries: entry, label: "Length ( x: cm, y: events )" )
// バーの境界線の色を設定する。
dataSet.barBorderColor = UIColor( red:1.0, green:0.0, blue:0.0, alpha:1.0 )
// バーの色を設定する。
dataSet.setColor( NSUIColor.red )
// バーの上に表示される数値の少数点を表示させないようにする。
dataSet.valueFormatter = BarChartValueFormatter()
// BarChartData をセットする。
plotLength.data = BarChartData( dataSet: dataSet )
// x軸のラベルをデータに沿ったものにする。
plotLength.xAxis.valueFormatter = BarChartFormatter( start!, end:end!, num:num )
// x軸のラベルを下に表示させる。
plotLength.xAxis.labelPosition = .bottom
// y軸の数値表示の最小値を 0 にする。
plotLength.rightAxis.axisMinimum = 0.0
plotLength.leftAxis.axisMinimum = 0.0
// y軸の数値表示の少数点を消去する。
plotLength.rightAxis.granularityEnabled = true
plotLength.rightAxis.granularity = 1.0
plotLength.leftAxis.granularityEnabled = true
plotLength.leftAxis.granularity = 1.0
// 枠をはっきりと表示させる。
plotLength.drawBorderEnabled = true
// オフセットの設定。
plotLength.setExtraOffsets( left: 0, top:0, right:0, bottom:0 )
}
}
// バーの上に表示される数値の少数点を表示させないようにする。
public class BarChartValueFormatter: NSObject, IValueFormatter {
public func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler? ) -> String {
return String( Int( entry.y ) )
}
}
// x軸に対応する数値をセットする。
public class BarChartFormatter: NSObject, IAxisValueFormatter {
var xLabel = [ String ]()
var start_val = 0.0
var end_val = 0.0
var bin_num = 0
var bin_width = 0.0
init(_ start: Double, end: Double, num: Int ){
start_val = start
end_val = end
bin_num = num
if bin_num > 0 {
bin_width = ( end_val - start_val ) / Double( bin_num )
}
for i in 0..<bin_num {
xLabel[i] = String( format: "%.1lf", start_val + Double( i ) * bin_width )
}
}
public func stringForValue( value: Double, axis: AxisBase? ) -> String {
return xLabel[ Int( value ) ]
}
図2. plotLength の表示。ただし、上についている “Length Distribution” の文字は、別に UILabel を配置することで実現している。