android app.です。
こちらはkotlinで開発しました。
物理モデルはこちら
アプリ紹介
該当アプリはこちらになります。
紹介動画
苦労した点
ここでは主にMPandroidchartで苦労したことをまとめる。
combined viewにてline chart, scatter plot を作成
当該アクティビティに記載
//combinedchart用の設定
private fun setupCombinedChart() {
combinedChart.apply {
description.isEnabled = false
setTouchEnabled(true)
isDragEnabled = true
isScaleXEnabled = true
setPinchZoom(false)
setDrawGridBackground(false)
//y軸右側の表示
axisRight.isEnabled = false
//X軸表示
xAxis.apply {
typeface = mTypeface
setDrawGridLines(true)
textColor = Color.BLACK
axisMinimum = 0f
axisMaximum = 3f
labelCount = 3
}
//y軸左側の表示
axisLeft.apply {
typeface = mTypeface
textColor = Color.BLACK
setDrawGridLines(true)
axisMinimum = -50f
axisMaximum = 150f
labelCount = 4
}
}
}
// LineChartデータ作成
private fun setupLineChart(Te_time_:List<Entry>): LineData {
var values2=Te_time_
val yVals2 = LineDataSet(values2, "Te [Nm]").apply {
axisDependency = YAxis.AxisDependency.LEFT
color = Color.BLACK
highLightColor = Color.BLUE
setDrawCircles(true)
setDrawCircleHole(false)
setDrawValues(false)
lineWidth = 2f
}
val data=LineData(yVals2)
data.setValueTextColor(Color.BLACK)
data.setValueTextSize(9f)
return data
}
// scatterChartデータ作成
private fun setupscatterChart(Temp00_:List<Entry>): ScatterData {
var values1=Temp00_
val yVals1 = ScatterDataSet(values1, "").apply {
axisDependency = YAxis.AxisDependency.LEFT
//透明色
color = Color.TRANSPARENT
highLightColor = Color.TRANSPARENT
setDrawValues(false)
}
val data=ScatterData(yVals1)
data.setValueTextColor(Color.BLACK)
data.setValueTextSize(9f)
return data
}
レイアウトファイルには以下を記載
<com.github.mikephil.charting.charts.CombinedChart
android:id="@+id/combinedChart"
android:layout_width="match_parent"
android:layout_height="350dp" />
事前にscatter plotでグラフ全体に透明色でプロット
透明色は前の工程で設定済
for (k in 1..30){
for (l in 1..2000){
Temp00.add(Entry(k/10f,l/10f-50f))
}
}
setupCombinedChart()
val combinedData=CombinedData()
combinedData.setData(setupscatterChart(Temp00))
combinedData.setData(setupLineChart(Te_time))
combinedChart.data=combinedData
タッチしたときにscatter plotの値を拾い、line chartに代入
これでタッチしたときの値を拾う
class CustomMarkerView(context: Context?, layoutResource: Int) :MarkerView(context, layoutResource) {
private val tvContent: TextView
override fun refreshContent(
e: Entry,
highlight: Highlight?
) {
super.refreshContent(e, highlight);
}
fun getXOffset(xpos: Float): Int {
return -(width / 2)
}
fun getYOffset(ypos: Float): Int {
return height
}
init {
tvContent = findViewById<View>(R.id.highlight_V) as TextView
}
}
highlight_Vの定義は以下のとおり。別途xmlを作成する。
<TextView
android:id="@+id/highlight_V"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="7"
android:textSize="12dp"
android:textColor="@android:color/holo_red_light"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceSmall" />
タッチ後の値を拾ってグラフにプロットする
val customMarkerView =CustomMarkerView(this,R.layout.high_light_value)
combinedChart.setMarkerView(customMarkerView)
combinedChart.setOnChartValueSelectedListener(object : OnChartValueSelectedListener {
override fun onValueSelected(
e: Entry,
h: Highlight
){
if(e.x>temp01){
time_of_torque1.add(e.x)
torque_of_time1.add(e.y)
Te_time.add(Entry(e.x, e.y))
combinedData.setData(setupLineChart(Te_time))
combinedChart.data=combinedData
combinedChart.setMarkerView(customMarkerView)
temp01=e.x
}
}
override fun onNothingSelected() {}
})
2軸の設定
linechartの引数を2つ取れるようにする。
setupLineChart()
chart_StaticLineGraph1.data = lineDataWithCount1(Te_time,ratio_time)
グラフの設定。y軸右側が活きるようにする。
private fun setupLineChart() {
chart_StaticLineGraph1.apply {
description.isEnabled = false
setTouchEnabled(true)
isDragEnabled = false
isScaleXEnabled = true
setPinchZoom(true)
setDrawGridBackground(false)
//y軸右側の表示 ここ!
axisRight.isEnabled = true
//X軸表示
xAxis.apply {
typeface = mTypeface
setDrawGridLines(true)
textColor = Color.BLACK
axisMinimum = 0f
axisMaximum = 3f
labelCount = 3
}
//y軸左側の表示
axisLeft.apply {
typeface = mTypeface
textColor = Color.BLACK
setDrawGridLines(true)
axisMinimum = -50f
axisMaximum = 150f
labelCount = 4
}
//y軸右側の表示
axisRight.apply {
typeface = mTypeface
textColor = Color.BLACK
setDrawGridLines(true)
axisMinimum = 0f
axisMaximum = 4f
labelCount = 4
}
}
受け取る2つのデータの処理内容をまとめる。
/ LineChart用のデータ作成
private fun lineDataWithCount1(Te_time_:List<Entry>,ratio_:List<Entry>): LineData {
var values1=Te_time_
var values2=ratio_
val yVals1 = LineDataSet(values1, "Torque [Nm]").apply {
axisDependency = YAxis.AxisDependency.LEFT
color = Color.BLACK
highLightColor = Color.YELLOW
setDrawCircles(false)
setDrawCircleHole(false)
setDrawValues(false)
lineWidth = 2f
}
val yVals2 = LineDataSet(values2, "ratio [-]").apply {
axisDependency = YAxis.AxisDependency.RIGHT
color = Color.BLUE
highLightColor = Color.YELLOW
setDrawCircles(false)
setDrawCircleHole(false)
setDrawValues(false)
lineWidth = 2f
}
val dataSets: ArrayList<ILineDataSet> = ArrayList()
dataSets.add(yVals1)
dataSets.add(yVals2)
val data=LineData(dataSets)
data.setValueTextColor(Color.BLACK)
data.setValueTextSize(9f)
return data
}
まとめ
ここでは主にMPandroidchartの使い方を紹介。英語のマニュアルがweb上にあるので、そちらを参考にされると解決につながることがある。


