رسم نمودار دایره ای pie chart در اندروید با کاتلین ، رسم نمودار در تمام پلتفرم ها یک امر بسیار کاربردی ست که در اندروید نیز کتابخانه هایی برای این کار ایجاد شده که در این آموزش یکی از بهترین های آن را بررسی و یک نمودار دایره ای یا کلوچه ای pie chart رسم خواهیم کرد.
نتیجه این آموزش به شکل زیر خواهد بود (برای مشاهده عکس در سایز اصلی روی آن کلیک کنید! )
ما از کتابخانه MPAndroidChart استفاده میکنیم.
من یک پروژه با اسم PieChart ایجاد کردم و برای شروع باید ابتدای کار دیپندنسی مربوط به کتابخانه را اضافه کنیم
implementation 'com.android.support:design:27.1.1' implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0-alpha'
</pre> <pre><span class="pl-en">repositories</span> { maven { url <span class="pl-s"><span class="pl-pds">'</span>https://jitpack.io<span class="pl-pds">'</span></span> } }</pre> <pre>
سپس یک اکتیویتی از نوع EmptyActivity ایجاد میکنیم با نام PieChartActivity ایجاد میکنیم و به همراه آن لایه xml ی با نام layout_pie_chart نیز ایجاد میکنیم.
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <com.github.mikephil.charting.charts.PieChart android:id="@+id/chart1" android:layout_width="match_parent" android:layout_height="0dp" android:layout_above="@+id/seekBar1" app:layout_constraintBottom_toTopOf="@+id/seekBar1" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <SeekBar android:id="@+id/seekBar2" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:max="200" android:padding="8dp" app:layout_constraintBottom_toBottomOf="@+id/tvYMax" app:layout_constraintEnd_toStartOf="@+id/tvYMax" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_chainStyle="spread_inside" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/tvYMax" /> <SeekBar android:id="@+id/seekBar1" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_above="@+id/seekBar2" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:max="25" android:padding="8dp" app:layout_constraintBottom_toBottomOf="@+id/tvXMax" app:layout_constraintEnd_toStartOf="@+id/tvXMax" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_chainStyle="spread_inside" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/tvXMax" /> <TextView android:id="@+id/tvXMax" android:layout_width="50dp" android:layout_height="wrap_content" android:layout_alignBottom="@+id/seekBar1" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:layout_marginBottom="16dp" android:gravity="right" android:text="-" android:textAppearance="?android:attr/textAppearanceMedium" app:layout_constraintBottom_toTopOf="@+id/tvYMax" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/seekBar1" /> <TextView android:id="@+id/tvYMax" android:layout_width="50dp" android:layout_height="wrap_content" android:layout_alignBottom="@+id/seekBar2" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:layout_marginBottom="32dp" android:gravity="right" android:text="-" android:textAppearance="?android:attr/textAppearanceMedium" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/seekBar2" /> </android.support.constraint.ConstraintLayout>
package dn.marjan.piechart import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.widget.SeekBar import com.github.mikephil.charting.listener.OnChartValueSelectedListener import com.github.mikephil.charting.utils.ColorTemplate import android.text.style.ForegroundColorSpan import android.graphics.Typeface import android.text.style.StyleSpan import android.text.style.RelativeSizeSpan import android.text.SpannableString import com.github.mikephil.charting.animation.Easing import android.graphics.Color import android.graphics.Paint import com.github.mikephil.charting.data.PieData import com.github.mikephil.charting.utils.MPPointF import com.github.mikephil.charting.data.PieDataSet import com.github.mikephil.charting.data.PieEntry import com.github.mikephil.charting.components.Legend import android.util.Log import android.view.WindowManager import android.widget.TextView import com.github.mikephil.charting.charts.PieChart import com.github.mikephil.charting.components.Description import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight class PieChartActivity : AppCompatActivity(), SeekBar.OnSeekBarChangeListener, OnChartValueSelectedListener { private var chart: PieChart? = null private var seekBarX: SeekBar? = null private var seekBarY:SeekBar? = null private var tvX: TextView? = null private var tvY:TextView? = null private val parties = arrayOf( "Party A", "Party B", "Party C", "Party D", "Party E", "Party F", "Party G", "Party H", "Party I", "Party J", "Party K", "Party L", "Party M", "Party N", "Party O", "Party P", "Party Q", "Party R", "Party S", "Party T", "Party U", "Party V", "Party W", "Party X", "Party Y", "Party Z" ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) //set page full screen(hide status bar) window.setFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN ) setContentView(R.layout.layout_pie_chart) //declare views tvX = findViewById(R.id.tvXMax) tvY = findViewById(R.id.tvYMax) seekBarX = findViewById(R.id.seekBar1) seekBarY = findViewById(R.id.seekBar2) //set onclick listener seekBarX!!.setOnSeekBarChangeListener(this) seekBarY!!.setOnSeekBarChangeListener(this) chart = findViewById(R.id.chart1) chart!!.setUsePercentValues(false) //set description for chart chart!!.description.isEnabled = true chart!!.description = generateDescription() //set offset of chart block descriptions chart!!.setExtraOffsets(5f, 10f, 5f, 5f) chart!!.dragDecelerationFrictionCoef = 0.95f //manage center text chart!!.centerText = generateCenterSpannableText() chart!!.isDrawHoleEnabled = true chart!!.setHoleColor(Color.WHITE) chart!!.setTransparentCircleColor(Color.WHITE) chart!!.setTransparentCircleAlpha(110) chart!!.holeRadius = 58f chart!!.transparentCircleRadius = 61f chart!!.setDrawCenterText(true) chart!!.rotationAngle = 0f // enable rotation of the chart by touch chart!!.isRotationEnabled = true chart!!.isHighlightPerTapEnabled = true // add a selection listener chart!!.setOnChartValueSelectedListener(this) seekBarX!!.progress = 4 seekBarY!!.progress = 10 chart!!.animateY(1400, Easing.EaseInOutQuad) val l = chart!!.legend l.verticalAlignment = Legend.LegendVerticalAlignment.TOP l.horizontalAlignment = Legend.LegendHorizontalAlignment.RIGHT l.orientation = Legend.LegendOrientation.VERTICAL l.setDrawInside(false) l.xEntrySpace = 7f l.yEntrySpace = 0f l.yOffset = 0f // entry label styling chart!!.setEntryLabelColor(Color.WHITE) chart!!.setEntryLabelTextSize(12f) } //manage chart description private fun generateDescription(): Description{ val s = Description() s.text = "TejariApp.com" s.textColor = ColorTemplate.getHoloBlue() s.textAlign = Paint.Align.RIGHT s.textSize = 14F return s } //set data to chart private fun setData(count: Int, range: Float) { val entries = ArrayList<PieEntry>() // NOTE: The order of the entries when being added to the // entries array determines their position around the center of the chart. for (i in 0 until count) { entries.add( PieEntry( (Math.random() * range + range / 5).toFloat(), parties[i % parties.size], resources.getDrawable(R.mipmap.ic_launcher_round) ) ) } val dataSet = PieDataSet(entries, "Election Results") dataSet.setDrawIcons(false) dataSet.sliceSpace = 3f dataSet.iconsOffset = MPPointF(0f, 40f) dataSet.selectionShift = 5f // add a lot of colors val colors = ArrayList<Int>() for (c in ColorTemplate.VORDIPLOM_COLORS) colors.add(c) for (c in ColorTemplate.JOYFUL_COLORS) colors.add(c) for (c in ColorTemplate.COLORFUL_COLORS) colors.add(c) for (c in ColorTemplate.LIBERTY_COLORS) colors.add(c) for (c in ColorTemplate.PASTEL_COLORS) colors.add(c) colors.add(ColorTemplate.getHoloBlue()) dataSet.colors = colors val data = PieData(dataSet) data.setValueTextSize(11f) data.setValueTextColor(Color.WHITE) chart!!.data = data // undo all highlights chart!!.highlightValues(null) chart!!.invalidate() } //call when progress value change override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { tvX!!.text = (seekBarX!!.progress).toString() tvY!!.text = seekBarY!!.progress.toString() setData(seekBarX!!.progress, seekBarY!!.progress.toFloat()) } //manage chart center text style with span class private fun generateCenterSpannableText(): SpannableString { val s = SpannableString("TejariApp.com\ndeveloped by Progrun Team") s.setSpan(RelativeSizeSpan(1.7f), 0, 14, 0) s.setSpan(StyleSpan(Typeface.NORMAL), 14, s.length - 15, 0) s.setSpan(ForegroundColorSpan(Color.GRAY), 14, s.length - 12, 0) s.setSpan(RelativeSizeSpan(.8f), 14, s.length - 12, 0) s.setSpan(StyleSpan(Typeface.ITALIC), s.length - 12, s.length, 0) s.setSpan(ForegroundColorSpan(ColorTemplate.getHoloBlue()), s.length - 12, s.length, 0) return s } //call when each chart block clicked override fun onValueSelected(e: Entry, h: Highlight) { Log.i( "VAL SELECTED", "Value: " + e.y + ", index: " + h.x + ", DataSet index: " + h.dataSetIndex ) } //call when user clicked on nothing override fun onNothingSelected() { Log.i("PieChart", "nothing selected") } override fun onStartTrackingTouch(seekBar: SeekBar) {} override fun onStopTrackingTouch(seekBar: SeekBar) {} }
حالا کافیه برنامه رو ران کنید و نمودار دایره ای pie chart رو مطابق چیزی که کد زدیم ببینید.