آموزش Expandable RecyclerView در اندروید
آموزش Expandable RecyclerView در اندروید با کاتلین
۱۳۹۷-۱۰-۱۴
نمایش گیف در اندروید
نمایش فایل گیف gif در اندروید
۱۳۹۷-۱۰-۲۲

رسم نمودار دایره ای pie chart در اندروید با کاتلین

نمودار دایره ای در اندروید

نمودار دایره ای در اندروید

رسم نمودار دایره ای pie chart در اندروید با کاتلین ، رسم نمودار در تمام پلتفرم ها یک امر بسیار کاربردی ست که در اندروید نیز کتابخانه هایی برای این کار ایجاد شده که در این آموزش یکی از بهترین های آن را بررسی و یک نمودار دایره ای یا کلوچه ای pie chart رسم خواهیم کرد.

رسم نمودار دایره ای pie chart در اندروید با کاتلین

نتیجه این آموزش به شکل زیر خواهد بود (برای مشاهده عکس در سایز اصلی روی آن کلیک کنید! )

رسم نمودار دایره ای pie chart در اندروید با کاتلین

رسم نمودار دایره ای pie chart در اندروید با کاتلین

ما از کتابخانه MPAndroidChart استفاده میکنیم.

من یک پروژه با اسم PieChart ایجاد کردم و برای شروع باید ابتدای کار دیپندنسی مربوط به کتابخانه را اضافه کنیم

فایل build.gradle(Module:app)

implementation 'com.android.support:design:27.1.1'
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0-alpha'

فایل build.gradle(Project:PieChart)

</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 نیز ایجاد میکنیم.

محتوی فایل layout_pie_chart.xml بصورت زیر است

<?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 رو مطابق چیزی که کد زدیم ببینید.

امیدوارم این پست براتون مفید بوده باشه و ازش استفاده کنید. از طریق راه های ارتباطی زیر میتونید با ما برای درخواست آموزش های اختصاصی و انواع پروژه ها در ارتباط باشید.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *