From 180ba9f0570f228f293c1a013042272eba552695 Mon Sep 17 00:00:00 2001 From: Stefan Gsottbauer Date: Thu, 12 Nov 2020 10:51:26 +0100 Subject: [PATCH 01/11] =?UTF-8?q?=E2=9C=A8=20added=20possibility=20to=20cr?= =?UTF-8?q?eate=20a=20barchart?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 33 +- .../main/java/com/faskn/lib/BarChartDsl.kt | 92 +++++ .../java/com/faskn/lib/ClickableBarChart.kt | 337 ++++++++++++++++++ lib/src/main/res/values/attrs.xml | 1 + 4 files changed, 461 insertions(+), 2 deletions(-) create mode 100644 lib/src/main/java/com/faskn/lib/BarChartDsl.kt create mode 100644 lib/src/main/java/com/faskn/lib/ClickableBarChart.kt diff --git a/README.md b/README.md index 7104750..450e02b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ [![](https://jitpack.io/v/furkanaskin/ClickablePieChart.svg)](https://jitpack.io/#furkanaskin/ClickablePieChart) # ClickablePieChart -Android Pie Chart library, supported with **Kotlin DSL**. +Android Chart library, supported with **Kotlin DSL**. -PieChart +PieChart ## Installation Step 1. Add the JitPack repository to your build file @@ -31,6 +31,16 @@ dependencies { chart.setPieChart(pieChart) ``` + +Or create a BarChart + +```kotlin + val barChart = BarChart( + slices = provideSlices(), clickListener = null).build() + + chart.setBarChart(barChart) +``` + Also you can use **Kotlin DSL** for building your chart. ```kotlin val pieChartDSL = buildChart { @@ -43,6 +53,20 @@ Also you can use **Kotlin DSL** for building your chart. } chart.setPieChart(pieChartDSL) ``` + +Or create a BarChart + +```kotlin + val barChartDSL = buildBarChart { + slices { provideSlices() } + clickListener { percentage, index -> + // ... + } + } + chart.setBarChart(barChartDSL) +``` + + To setup with legend you need an root layout for legend. ```kotlin chart.showLegend(legendLayout) @@ -87,5 +111,10 @@ chart.showLegend(legendLayout, CustomLegendAdapter()) integer Animation duration with milliseconds. + + app:orientation + string + Orientation of BarChart (horizontal/vertical) + diff --git a/lib/src/main/java/com/faskn/lib/BarChartDsl.kt b/lib/src/main/java/com/faskn/lib/BarChartDsl.kt new file mode 100644 index 0000000..a7a8f04 --- /dev/null +++ b/lib/src/main/java/com/faskn/lib/BarChartDsl.kt @@ -0,0 +1,92 @@ +package com.faskn.lib + +/** + * Created by turkergoksu on 30-Aug-20 + */ + +@DslMarker +annotation class BarChartDsl +data class BarChart( + var slices: ArrayList, + var clickListener: ((String, Float) -> Unit)? +) { + fun build(): BarChart { + initScaledValues() + initPercentages() + return BarChart(slices, clickListener) + } + + private fun initScaledValues() { + slices.forEachIndexed { _, slice -> + slice.scaledValue = (slice.dataPoint / getSumOfDataPoints()) + } + } + + private fun initPercentages() { + var remainder = 100 + slices.forEach { slice -> + val percentage = (100 * slice.scaledValue!!.toInt()) + slice.percentage = percentage + remainder -= percentage + } + var i = 0 + while (remainder != 0) { + slices[i].percentage = slices[i].percentage!! + 1 + remainder -= 1 + i = (i + 1) % 4 + } + } + + private fun getSumOfDataPoints(): Float { + return slices.sumByDouble { slice -> slice.dataPoint.toDouble() }.toFloat() + } +} + +fun buildBarChart(block: BarChartBuilder.() -> Unit) = BarChartBuilder().apply(block).build() + +@PieChartDsl +class BarChartBuilder { + private lateinit var slices: ArrayList + private var clickListener: ((String, Float) -> Unit)? = null + + fun slices(block: () -> ArrayList) { + slices = block() + } + + fun clickListener(block: ((String, Float) -> Unit)?) { + clickListener = block + } + + + fun build(): BarChart { + initScaledValues() + initPercentages() + return BarChart(slices, clickListener) + } + + private fun initScaledValues() { + slices.forEachIndexed { i, slice -> + val scaledValue = slice.dataPoint / getSumOfDataPoints() + slice.scaledValue = scaledValue + } + } + + private fun initPercentages() { + var remainder = 100 + slices.forEach { slice -> + val percentage = (slice.scaledValue!! * 100).toInt() + slice.percentage = percentage + remainder -= percentage + } + var i = 0 + while (remainder != 0) { + slices[i].percentage = slices[i].percentage!! + 1 + remainder -= 1 + i = (i + 1) % 4 + } + } + + private fun getSumOfDataPoints(): Float { + return slices.sumByDouble { slice -> slice.dataPoint.toDouble() }.toFloat() + } +} \ No newline at end of file diff --git a/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt b/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt new file mode 100644 index 0000000..353e03a --- /dev/null +++ b/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt @@ -0,0 +1,337 @@ +package com.faskn.lib + +/** + * Created by Furkan on 6.08.2020 + */ + +import android.animation.ValueAnimator +import android.content.Context +import android.content.res.ColorStateList +import android.graphics.Canvas +import android.graphics.Paint +import android.graphics.drawable.ColorDrawable +import android.util.AttributeSet +import android.view.* +import android.view.animation.LinearInterpolator +import android.widget.LinearLayout +import android.widget.PopupWindow +import android.widget.TextView +import androidx.core.content.ContextCompat +import androidx.core.view.doOnPreDraw +import androidx.core.widget.ImageViewCompat +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.faskn.lib.legend.LegendAdapter +import kotlin.math.abs + +class ClickableBarChart @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : View(context, attrs, defStyleAttr) { + + private var slicePaint: Paint = Paint().apply { + isAntiAlias = true + isDither = true + style = Paint.Style.FILL + } + + private var touchX = 0f + private var touchY = 0f + + // PieChart variables + private var barChart: BarChart? = null + private var slices: ArrayList? = null + + // Animation variables + private var animator: ValueAnimator? = null + private var showPopup = true + private var animationDuration: Int = 1000 + + // Attributes + private var popupText: String? = null + private var showPercentage = false + private var currentAnimationPercentage = 0 + + private var orientation: Orientation = Orientation.HORIZONTAL + + + init { + initAttributes(attrs) + } + + private fun init() { + initSlices() + startAnimation() + } + + private fun initAttributes(attrs: AttributeSet?) { + val typedArray = + context.theme.obtainStyledAttributes(attrs, R.styleable.ClickablePieChart, 0, 0) + + try { + popupText = typedArray.getString(R.styleable.ClickablePieChart_popupText) ?: "" + + showPercentage = + typedArray.getBoolean(R.styleable.ClickablePieChart_showPercentage, false) + + animationDuration = + abs(typedArray.getInt(R.styleable.ClickablePieChart_animationDuration, 0)) + + showPopup = typedArray.getBoolean(R.styleable.ClickablePieChart_showPopup, true) + + orientation = Orientation.valueOf( + typedArray.getString(R.styleable.ClickablePieChart_orientation)?.toUpperCase() + ?: Orientation.VERTICAL.name + ) + + } finally { + typedArray.recycle() + } + } + + private fun startAnimation() { + animator?.cancel() + animator = ValueAnimator.ofInt(0, 100).apply { + duration = animationDuration.toLong() + interpolator = LinearInterpolator() + addUpdateListener { valueAnimator -> + currentAnimationPercentage = valueAnimator.animatedValue as Int + invalidate() + } + } + animator?.start() + } + + private fun initSlices() { + slices = barChart?.slices + } + + + /*override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { + super.onSizeChanged(w, h, oldw, oldh) + + rectF = RectF( + 0f, + 0f, + width.coerceAtMost(height).toFloat(), + width.coerceAtMost(height).toFloat() + ) + }*/ + + override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + + var startPercentage = 0F + + if (slices.isNullOrEmpty().not()) { + slices?.forEach { slice -> + + var endPercentage = (startPercentage + slice.percentage!!.toFloat()) + slicePaint.color = ContextCompat.getColor(context, slice.color) + + if (orientation == Orientation.HORIZONTAL) { + + if (startPercentage < currentAnimationPercentage && endPercentage <= currentAnimationPercentage) { + canvas.drawRect( + (measuredWidth * startPercentage) / 100, + 0F, + ((measuredWidth * (startPercentage + slice.percentage!!.toFloat())) / 100), + measuredHeight.toFloat(), + slicePaint + ) + } else if (startPercentage < currentAnimationPercentage && endPercentage > currentAnimationPercentage) { + canvas.drawRect( + (measuredWidth * startPercentage) / 100, + 0F, + ((measuredWidth * currentAnimationPercentage) / 100).toFloat(), + measuredHeight.toFloat(), + slicePaint + ) + } + + } else { + + if (startPercentage < currentAnimationPercentage && endPercentage <= currentAnimationPercentage) { + canvas.drawRect( + 0F, + measuredHeight - (((measuredHeight * (startPercentage + slice.percentage!!.toFloat())) / 100)), + measuredWidth.toFloat(), + measuredHeight - ((measuredHeight * startPercentage) / 100), + slicePaint + ) + } else if (startPercentage < currentAnimationPercentage && endPercentage > currentAnimationPercentage) { + canvas.drawRect( + 0F, + measuredHeight - (((measuredHeight * currentAnimationPercentage) / 100).toFloat()), + measuredWidth.toFloat(), + measuredHeight - ((measuredHeight * startPercentage) / 100), + slicePaint + ) + } + } + + + + startPercentage = endPercentage + } + } else { + slicePaint.color = ContextCompat.getColor(context, R.color.semiGray) + canvas.drawRect( + 0F, + measuredHeight.toFloat(), + measuredWidth.toFloat(), + 0F, + slicePaint + ) + } + } + + override fun onTouchEvent(event: MotionEvent): Boolean { + return when (event.action) { + MotionEvent.ACTION_DOWN -> { + touchX = event.x + touchY = event.y + true + } + MotionEvent.ACTION_UP -> { + + touchX = event.x + touchY = event.y + + + var currentPercentage = if (orientation == Orientation.VERTICAL) { + 100 - ((touchY * 100) / measuredHeight) + } else { + (touchX * 100) / measuredWidth + } + var calculatedPercentage = 0F + + run { + slices?.forEachIndexed { index, slice -> + + val start = calculatedPercentage + val end = calculatedPercentage + slice.percentage!!.toFloat() + + if (start <= currentPercentage && end > currentPercentage && showPopup) { + barChart?.clickListener?.invoke( + calculatedPercentage.toString(), + index.toFloat() + ) + + showInfoPopup(index, event, ((start + end) / 2).toInt()) + return@run + } + + calculatedPercentage = end + } + } + true + } + else -> false + } + } + + private fun showInfoPopup(index: Int, event: MotionEvent, center: Int) { + val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater + val popupView = inflater.inflate(R.layout.popup_slice, null) + val width = LinearLayout.LayoutParams.WRAP_CONTENT + val height = LinearLayout.LayoutParams.WRAP_CONTENT + val popupWindow = PopupWindow(popupView, width, height, true) + var parent = this + + var popupText = "${slices?.get(index)!!.dataPoint.toInt()} $popupText" + if (showPercentage) { + popupText = "$popupText (%${slices?.get(index)!!.percentage})" + } + popupView.findViewById(R.id.textViewPopupText).text = popupText + + ImageViewCompat.setImageTintList( + popupView.findViewById(R.id.imageViewPopupCircleIndicator), + ColorStateList.valueOf( + ContextCompat.getColor( + context, + slices?.get(index)?.color ?: R.color.semiGray + ) + ) + ) + + popupWindow.setBackgroundDrawable(ColorDrawable()) + popupWindow.showAtLocation( + this, + Gravity.NO_GRAVITY, + event.x.toInt(), + event.y.toInt() + ) + + val currentViewLocation = IntArray(2) + this.getLocationOnScreen(currentViewLocation) + + + if (orientation == Orientation.VERTICAL) { + popupView.doOnPreDraw { + popupWindow.update( + currentViewLocation[0] + (parent.measuredWidth / 2) - (it.width / 2), + (currentViewLocation[1] + parent.measuredHeight - (parent.measuredHeight * center) / 100), + popupWindow.width, + popupWindow.height + ) + } + } else { + popupView.doOnPreDraw { + popupWindow.update( + currentViewLocation[0] + ((parent.measuredWidth * center) / 100) - (it.width / 2), + currentViewLocation[1] + (parent.measuredHeight / 2), + popupWindow.width, + popupWindow.height + ) + } + } + + + } + + fun setBarChart(barChart: BarChart) { + this.barChart = barChart + init() + invalidateAndRequestLayout() + } + + + fun showPopup(show: Boolean) { + showPopup = show + } + + fun showLegend( + rootLayout: ViewGroup, + adapter: LegendAdapter = LegendAdapter(), + orientation: Int = LinearLayoutManager.VERTICAL + ) { + val recyclerView = RecyclerView(context) + val linearLayoutManager = + LinearLayoutManager( + context, if (orientation == LinearLayoutManager.VERTICAL) { + LinearLayoutManager.VERTICAL + } else { + LinearLayoutManager.HORIZONTAL + }, false + ) + recyclerView.layoutManager = linearLayoutManager + recyclerView.adapter = adapter + slices?.toMutableList()?.let { adapter.setup(it) } + recyclerView.overScrollMode = OVER_SCROLL_NEVER + rootLayout.addView(recyclerView) + invalidateAndRequestLayout() + } + + private fun invalidateAndRequestLayout() { + invalidate() + requestLayout() + } + + + enum class Orientation { + VERTICAL, + HORIZONTAL; + } +} \ No newline at end of file diff --git a/lib/src/main/res/values/attrs.xml b/lib/src/main/res/values/attrs.xml index d845644..1d87fd6 100644 --- a/lib/src/main/res/values/attrs.xml +++ b/lib/src/main/res/values/attrs.xml @@ -6,5 +6,6 @@ + \ No newline at end of file From a4b24bb157c500bca0627ce40cac5fa6e898a098 Mon Sep 17 00:00:00 2001 From: Stefan Gsottbauer Date: Thu, 12 Nov 2020 10:52:03 +0100 Subject: [PATCH 02/11] updated MainActivity to create barchart as well, added new screenshot --- .../faskn/clickablepiechart/MainActivity.kt | 40 +++-- app/src/main/res/layout/activity_main.xml | 146 ++++++++++++------ assets/device-2020-11-12-104411.png | Bin 0 -> 67496 bytes 3 files changed, 132 insertions(+), 54 deletions(-) create mode 100644 assets/device-2020-11-12-104411.png diff --git a/app/src/main/java/com/faskn/clickablepiechart/MainActivity.kt b/app/src/main/java/com/faskn/clickablepiechart/MainActivity.kt index d2cfc75..a0dfa33 100644 --- a/app/src/main/java/com/faskn/clickablepiechart/MainActivity.kt +++ b/app/src/main/java/com/faskn/clickablepiechart/MainActivity.kt @@ -2,11 +2,10 @@ package com.faskn.clickablepiechart import android.os.Bundle import androidx.appcompat.app.AppCompatActivity -import com.faskn.lib.PieChart -import com.faskn.lib.Slice -import com.faskn.lib.buildChart +import androidx.recyclerview.widget.LinearLayoutManager +import com.faskn.lib.* import kotlinx.android.synthetic.main.activity_main.* -import kotlin.random.Random + class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { @@ -17,7 +16,7 @@ class MainActivity : AppCompatActivity() { val pieChartDSL = buildChart { slices { provideSlices() } sliceWidth { 80f } - sliceStartPoint { 0f } + sliceStartPoint { -90f } clickListener { angle, index -> // ... } @@ -34,29 +33,48 @@ class MainActivity : AppCompatActivity() { chart.showLegend(legendLayout) //OR SET WITH CUSTOMER LEGEND ADAPTER - chart2.setPieChart(pieChart) - chart2.showLegend(legendLayout2,CustomLegendAdapter()) + //chart2.setPieChart(pieChart) + //chart2.showLegend(legendLayout2,CustomLegendAdapter()) + + + val barChart = BarChart( + slices = provideSlices(), clickListener = null + ).build() + + val barChartDSL = buildBarChart { + slices { provideSlices() } + clickListener { percentage, index -> + // ... + } + } + + chart3.setBarChart(barChart) + chart3.showLegend(legendLayout3) + + + chart4.setBarChart(barChartDSL) + chart4.showLegend(rootLayout = legendLayout4,orientation = LinearLayoutManager.HORIZONTAL) } private fun provideSlices(): ArrayList { return arrayListOf( Slice( - Random.nextInt(1000, 3000).toFloat(), + 2F, R.color.colorPrimary, "Google" ), Slice( - Random.nextInt(1000, 2000).toFloat(), + 2F, R.color.colorPrimaryDark, "Facebook" ), Slice( - Random.nextInt(1000, 5000).toFloat(), + 1F, R.color.materialIndigo600, "Twitter" ), Slice( - Random.nextInt(1000, 10000).toFloat(), + 4F, R.color.colorAccent, "Other" ) diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index af84670..7978849 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,63 +1,123 @@ - + android:layout_height="match_parent"> + android:orientation="vertical" + tools:context=".MainActivity"> - - - - + android:layout_margin="24dp" + android:weightSum="2" + android:orientation="horizontal"> + - + + + + + + - android:layout_weight="1" - android:orientation="horizontal"> + + - - - + + + + + + + + + + android:layout_margin="24dp" + android:weightSum="2" + android:orientation="horizontal"> + + + + + + + + + - \ No newline at end of file + \ No newline at end of file diff --git a/assets/device-2020-11-12-104411.png b/assets/device-2020-11-12-104411.png new file mode 100644 index 0000000000000000000000000000000000000000..08b348641dd2a8567144a04f47bde76eabc96534 GIT binary patch literal 67496 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

k4SxIoHc>qUtS)2iaAmDZU-n|3TPUgfo7}2S- zeL+f!BQ`&Ue}H+}{(^a9{3W`z&g_;}4NWEUqkejPU@43j-^=UTUC8^c&ZQ@?&G0yj zWDywlh-T?kr4;@+?3d}N+xiD`oT3V6y)Bm*c^;{Xm+S|V?p;~gYcGrG9LtuF;DNlk z*$tddt{I|awad1vwHvlOEHM&YFyn_y99+qWS!Fm%T}{^jV%CB=<;s-%z1iObWSX z5xxaHo7vD|o-16F71a-Xcnk;*$|Z{EC#cPkrTp6f+h zOk~r7>IsEDK;uF_LG^;_Bi+cqu!X=Ml7fI3Q}6*24L*_Q{Qi`muKf9wpRWAp=19+7 zwwwcciQo0~dVj%z)BolG^79`$@{dEXe#+Y5{X7Kg1Nn#X-F)hQv(KMD#lHQ-OTENXCP^U$ zyR8qhd8&G{U!*v9j*Cj(@5cEgvmvs#H;BuII_{IV6`x5;=13aW>U^zZipd=dkCt?) ztQMV&Hhc#2e%sn2@myO6-AMQS;fMWe>*c32)_+(#@6_5QKmG8_+IfHYVg0;+ZjE&C zPd)jE4%xPkXDgg?WKB@*T$5s3N!NaG1c&PHuKj0N{^^k4O^82CrvH!6ko_WsJ7Ea# zt`%+jX~y3z?Rkg{?H}If4?q0v7erCKafq2dRZ+V%KA5q~B7e`JyQ`w(*(1wEYJ7X6 zvuB8=dix(9hMGzWPw(v-CaZzWxOFnkd?wEedS!+ntlKr7ZCylvmwgOM*h z_n__YY9Lgg)o`!Bdf56y*G{B4^Yfc+JmBBG89eRazwZKg+4U|!-Wu+Ne5`lDS%r-| zBCSVy=BE=kx(Det=vC+|_<)Old+9&x?cd$ucaPe*9nyp!9}W8Fm5^ThPv-gmxlzInAhP?fSNtD$jh+^*-)}a5 zCjS0)z9JIrcf!k(clU1(-q=B4J3;nI?%^moMe)wnW{-;Uzw5lq(6K?)ofqexc^Gm z{=?wHPPF#mA2NwF_IKOWpWAq(zu$IY+qprBh^&7n#@FTqGGqU@*|@*?@t{rr@0!p5 z2X6h%*PtrIpfN$It^)|ubPhgeo*b-89k~jr#2K0^0cu)S=ldtX{aeG#U^Jw*W;^Gf*2HIXyjXP*haZdfhNO zSQ{#gAwm66v##Qf5*!_{N9LQR7R^+0X=Hvf`QV-D)SK9PY0tBY+tW#(;{7!vE-j@N z*bwbpc^Lf+Dwm>pis$s~AxA9RV0mG>V6+5CjcFF2vc|Yt=Pc1lPlnfBTPa6aT(eI< zisNc?xRt~0a#GxIH zGe9plKfYtzzHj3LqHPml^#w}$X$qWe0fX=Ku_#lh^w}E5r_auG%B0ny%Pj-rM`H-= zjQOyW^4{Yrv@~GkXDJ*?d87wK|4ChokjyFAjul8RV4T}S&nv;1Z+D)Nzq89le-@jnOgktH77I`n*^X36U?2H7bhNc!(ddEM3*i8O}1D>7k2!6ktr`CuSI+zJ41T z8k)T=3fYvV4X@-{GmRS4D}q=JV`Tz{XC3{=T7sCpO5b0|vTtezbamC{g=-q#y8@?~ zhnHGU&~$zgFump%;}g@-xD|_okY43DDv(}Ksk6h?W<`Ata-F`+o$LA~Wc#*#kF46i ziCccW+beU_J=^~iMIas+ci$E&2QW!X6+k|+Lms6;TeewilbUWclJXmDK*Ony$P52> zxmF|MA!H)vlz2n&0D7bDxo%SFFw$n#<;AX5Y7j$glI9B0PBrVd?)XFz^PYBe5`W;a zUZhXe-;V=rU=g|?!8 zXmYKJ9gq3ae4U4R?$VRv^6XXP8Ff;v06zlpcc0>AbRb=pjP+A05fp%0R=Ky5?%ljN zU@(Mn4xPCRBpgidj|1)B1k5SL!h@J=A0a@Ul)^XX3h(p}DoRd&sjRDpm@SB!Lq~1Q zZE1yfM^{%MKBKLqAB}1Q6nkY}_=}1n``WgBGEun)FLE68&1P?I8tYI2)R>Ob*>K*Q zXR2(BUr9RvZM3kqdw*r{Ja0LyI^jq@eHkH0{~7^~SYW~Sl0^X0O7U7fL(lI>*!&oD&uIoPE z-#REYn^(EgpWSAjD88+r+N?;m+YumilNB+&^JV$md3{etJV_Zp#Sku!2#ag0ad`Gh zug)v2I8!a^l8W2Px9^Gz-gRD+ioi}7V;|jyBBK+!mK~|Pgr^}34Y0#l1IjFwz!IFpnSJ$N9;ovZUQf|1KyvRMTh+YAsh95kd9 zL>6_EJOFCE=<=G;z<;#jAU$f3!qM5%YtEb1oCd+uezeE9OIM;R&%RGz$>@pYPC%0R z#jUotJix@MZ*L}t`K*R&J6oBU*GbDV_dze|rJFM|IVDA7GgNJpkmcTLtBsakakTFX zlx^0oYf00e)Z}Y!!v&`$CoJY51h%aZL|1dr<|EoDD2jwF)|_l^y4amN)gaGNg>cul zLghu_HePLt92YJQb4tDFvs5BFFc?b>J?b-14OXdRStTk{Zuabnu}lb@kzDypWuX_z>Cz{S{4(8REDU6csk+no?D?ct8go)%y%gd&iMu5Q2= zZh(*hI5=@zIo*uCzuJ>aZce?%1YOyiCT%XnN@+_;KEQKA(h|mE;y|#i^u$O;UGqM1 zixKihvl$+bdHI@ty(yVAg=$=LrQvhPT0Krqb5t^rGA(`1T|r&?vq4p7SN!5j4XZ`C zFgxIg<*7v2$1Xc}d)sACYBkIYhrJB`@@EttQ zb=SppX8r^}KD}BuP;0ql)?MI$Vsuy#DMOS6S$g!8V zqikRHh8=v}d7N{IEi0_xWxcm2Qee=|L)Ursb&G?ozNQk1Y`fGf5GK5Fd2=BujWZ;` zq(`<=DpvC^Cw7H$O1OQ$NIv)QZ!*fOGC?4{@X`d0al|DnrT<>`>Ou9i*ESgg~# zMgUYx8!hH*KPf6Zt-4h9a6S+vUVwp4il89Y$Bs%OBBQ}FRPJKuwX;8KdS?|U`MWb_*9_2v&<(N3}f zjp0&^>|RnPAb;<_!78bK!bW@O)^$G0wAOsRL-qxp%x;}m;}winjuHZdyY!qKRBkHe zpNmuB+nX2NWrvU}G*dXNTwq!R$^dmI&Vg>D?36ny*L;&#(h@cY(VTk#$s)y-DZdf9NjdkzW}Ys}tKv}%>BCLE-AuFlQkuM{dT ztAZeUJ|44tnpbjZ_Iv@sEbnypjn8{SNT}qJu7$BWmLyM>4 z;@?^*tGlW4448Nq#Fb@>SacS;I$F<_u}Ue=Yg-jGIfq6=*=}7Ug2f3NO{NRo-Wkc5 zbiUok-Ar@G?kAG7ACrokWWcQEB%chk$I8ik^rhlpm(Fk`;@u~QC?|JO1wEp+8N8-j z+knHV<=x_x^bvgO8C$)ajCk9Q(<Fmi&c5H~w zgqecgn5>2y#^t?2Q5!0lN(6uZ0nP=iQUQz94-wU(?#@? z>}mQ+=>7vD$A&3A#kdKtXC25A+$^V0pXVb#)dL%RcJj&B_Bm~3@ke9B5?GH}5SK;1 z@ib>arGzDyG;Nxrv4^avSWAydVP|`5f6a2oUfzZ}Ih%uc1fSk%E02z={YXLZT@#Eh zkJY*k-#8MQ^U5>UF=MZAyX9GVLP7VvJ;t3W+0}M&xJSBH7%FWt`k{_rb_@r~GNwge z&aa`<<+5W0iI`;bdaJDKestSbYJ$)GWf4tbV8L-+M1@gEEe|Q-$mnreHkbO-U|D7- z4=N92OFb^7Xpno^NEq=VNaZd(Ken91QLF<+O-6%HXBaG^t_=2g+hN4K#4I0x)@&9k zk2!XXI_MBh6(;$X-}LH;p>$OVjf07?z2E4Io%9A{7Knbw)>>ne9ZW5vr#&i#2E{8U z{XUv}(O?^DD!*o!#MfEx&aLE1oq_y@7Xg5g8#V5}kh+L|F>dAZRTUFX)3&qY-S-c{ zaogc_3hHA0O9N{kGvS`BPN#a9iIK`qOa0nW!m0kbv+ORcYm!~`L%-Hr#b6OSL6T zp(N$2N*0224ra96Kjx7(@8b6W25f-3ENk6Sh9*mZT!tQ4tJ$qqEDdHvNV8h?90Q_6 zrX+Dl-J$71yOcWcTb5n_gimv9oaqw(h^aUj>Oe27#}F;yrAQ*{%rFo73Y}tg8=GZW zYb8DnsWYBj5?5{JcEppph^h~;e)Z#NJ^AD*Qm?&5C4Ds|%DJ2yXOF!IeQ#U&P}mN+ zm3BDmtD4e4#Ur#18om`Wgc?~2PvK&ZZcozN;tpfgNV)F#gL}x&ceB}eaDe;yG)8p+=dkxqwk@)RXFg%iH! z+nJQ`Kg(jNVdtE0|19*h^!gW>$l8!=`8V$}E{C>9dhwfk%WxTH5SuW{9l% zHBywvQZG|5mPIkD#ll0mO37oP(N&W?P5Oijvdk~^P7Q(z>y9SFtt}m^$QJyQSdlPx z#sW~#%u@G880xk>y%g7gT6cnGS7iyRO#f41Cq8Efq{oeSusZ@tMlqJBRGXr&GE(wQTFp zld-OH+GtyeWAH?TbBnBQKh~t)98NixR5P}3zoEj)cQ5G{mP47J>T55c=EA|?I1J-c zWb(krxeDVohZmc24pl#Q#K?g0<)KbQlj^U+m|bopZ#FPPwi(+Bg(YpP(uQx(4MCa_ zwxizNu8DAc`O$gO;ZzQ@tT?kM-Y}m^Sd5IG&pLLl6~XzgcI7@aO?ImUKCua`5~RF@ zC^}~y5GnrtkmpOZWp0N-)z_}w5QN~}X=9yvl6Z%+u_B5t>s-_YFG?)wpffJRE3BG( zA7w)+aiWT6R&xL}zt-zn78(?;6m1J@3a;oLhC$AcepxJug?XpiB7L zFt-S0tUJcXO;}-0cG{MGvVhX&`F#CLlXZ15i>C%od!8KVyJLW_SC0=86|USzpH}B9 z?nO!PHcM`%r?T30E}ucysXw@YbGG|Fxhf-i`G&u7;$gN)xN}p=g!?NvhJ^RozrVqTV5cfrYguZjVS0x9cK&iA@ui>@ireM{@VFiZ>P1G zi+d~ul|eE`?G;y;#i^V$Ij8*!wv~C^?OGmlXhn>V@#;IQp3JX;a?2G4bXON}lfn(T zLP9!|h;?=HL1t5h(hCJE)~C50grsLwtxv7wC&MW4ggG6F=CO_|`BWljoD)#qThd0$ zrdz8*dFl+mN`q4G(28Pq{Gy@OzJpJ)$_czBw~*Wp_q_Afje)2o-{rnXWOVuI$qAmZ zxdj)JgjeEQ$dSvIYpoxtTjb0}8l)s%?|$vhr6khx;1TKd&t&T@5S%KJS?x1xMV;?o93A3}wvLo4b$3+VQZO$aBqLVqS-1SH_ zr)K&3x{^ERiEq23 zRiI-rb>?uJGp&f;)AHBKv9u|yGd=+WWQS3U-Ktx$9I1s3Azf_dlVEu8B}5e|u`+Xr3OAje56((4Ys>DpaBi}Qr!dnCyQPp6s(4bvjT%@Mia-P2?>a59?tmF1_SUVX6&5tn?$=x5(2Z$s%_ySXqi+hT8#j5IsSJ1PZ+)vLITWqp?Bc><;jSdT zYH zs*E;R^V{C|TvnzMz|xq=*l_q`T9Nr0Mrtn|pS)vrE<^0efttur-IrI~E*Z986pD`Q zU0EET{R&9Vt)#rJWp?3KtPhUq_%nzL#V81jW%7bLqiya<=Ro#7fBl@1B;67z#Iy6U z%@@Ol9(NrSH&YrQT>~B7$3p?7D)T~O`G`M%?WcH!@F!g<6Hrj2CZ%ZRtHeFW0B9hD zSO7EK4IkinMLxlS|0h4JpZC)lKVP_Z$1+#Q(4*aOVz! zlDrEP5>VzE3ELryb|YZA1}0jQ4I4*Xn}0jD5g^^T3K1QfSN%A$fsoobg4}o=sRk+Q z-S7>$=Eoz~j=8JP-12^ts)HntrQ8_VKpm$A=lMlTO)@jYc z!a{myXXgme-d1uKjHHi%C%-D&qHC;+K!($H(9Xu`xb#Eyr#`_o!~zUau2XHc#O|Om@ zu&AE+R=lTog|CnA*Rn%r_a2auz4GxK$qs+}bIeapo0S^7CcYGudCIOqN^$!9Th$j| z)6VmwUdDb-yVtPWzq?y=%jxY-%ID5gQl6&Va{Aok(30lKr5Opsy1Y=ETF5iC=^t(E zJNSJh3)eAQY9`V(QWSz9he=nZ&9yv6@^51U?uq0u1~MPR%n!!Ic&JN5{%s>-{9|L; zB84p!A+~o36s#I7>M*|yvIf?tFzWtwE(i0c`9ZO9I6lxzcUb9Te5t6gO5rDuGj&0_ zVU7wd8;dnNECfzF^L>< zkbiUgbiFY~D{Cxe0!|rVYAAq$RMQc(n89fGg`rC*-Sk^>&cI{X2On%^AvrHUQaVx)UDfbC5M2;w`tZ$V&7&# zk_`vN8?;A7Nnnh{`xkd)wxy>lx0)luq!sUkZdZx0^W;( zR3um>NQ$}?DHI1;gCRu&ico{jZE)`zzWSG~SSkIfI^i$i#*fOx10;&A49t?wQ+F&GthC*wHV1XNe0ud=%9tlJ@}j=DE^pbB!_$)H zZP{GW5LKIRC#uUx9JnGe05pk;h$=6|GG={eG!L&Fw2wiouh$&vd}dnpmM_iKMvFH> z2zDm7AU33w!iH*Gk>B>)XH(XQ9S)O)-_H~;o41RC6}xp~xLXXHY?cG?b|S`kAs_dN zbFTiv=s@>{-~!~7tdmZ_7W=`JuhE)tgR(1}4+4Rz(F9~QqjjB!;tX)~*E8=ZGcp>J z(L*?@3XOf4)X&&^SkgHYb8*Xty!DK2E+qo-tw65)i+8!VYOpvl5cNuTCrS)sWF!bwCldDzw^HXWIgzqiX{)lHgpV?ueE z=|%P;eluxxtm5&0dj_BAi@q4`UHw~St@b+sKfv33)XsemZ4k4P-3FtY^bn`t;n%#E zz88zOIJrBRA9y@}+zeZ6F^Ll=+I#qk z$2%ljns7km8BDyTX)i|S*Kg8hAr)i`1K03qj{PXoE78f5}35n&kIvu-E=AvxUy%V!1t(=)7IK>4P{19ZZPV;Zs*fmF1O{}kFe81ywR1rZJ zcP@&}J&Bo7Wgc8bRj95sec5bA8LRG=bOZVOd{EW>6WR`h6qjysVV@RH$&z)k$|(4% z!;9zeev;+T^Q$Z4tLB!57$~|c@9y!@i`?S-a?=43*dpt@QGrnDI3(Z%kcNYyCQ5j| zKDtLNM=}Z$%j{EQJ&KQl>xhsJ?v+`h27RJk&eM2K&1_C2Y&cIkf$-uM(BUDtB?qcN;#6YCexy~W+nF>)PXy~fowT~fv=l;oa5^vd%2N45D86j7H{-ELflf+?h1_Z7ZJJ=6`S)SZ*0w` zqf7vE^9J~lsRl(L&evE6Wk5mNIzDBkKAb#|FN>lN?~ufgAKREpr}vz{5GH14oDZ=9 z+I9-%BzVsusA_o0p5~08O);=tztJsmcd2fKy1b@t0l8;ieI+E~v|ul;y?2JVHSysc z8z>fh+b@!u=cI-)vB`L=Y)?v{qieiHSMl+#I>-SxL}$z`LgLOEDEjkmJt&0SAtBgR(T$HBMs!yEY%zGUz(rA8J&3cMDaHX+VL*%4pXL zSDQ+?%Z`msD3vk+IEhhvu9Z=DsplJ|7^xx93ojzYA)JB0IejNya_c`j`d^q)e_|^A zS6eQgA0r{%3}BF(QUqK}fc6K~bq$%lainwSy6JGLTV(%|^9+#CaS$z_v`_b3;8LT3 z$F^TId_16X+Miqr_d&A#){l7oos)ig@W#B_xEvPR=9FDaLs+}#4h``!#nCO)$hnDKQes_>sR*BQE2PHiDM*$Kz}6TDFb1_C*t;g~E@ya? zFMH8jU$_lLP~eu1O)6^rUA;isG-|kiWB%UB^D@_cg7F{om~}nR$5P%*AQXdcKJV2& zAa+?Az=@k9dH~*TZJ2*qNv<#aVI?6q-$-Wp zWvgsWLEN>B=XbL7QZyXY-Z*r(6gt^NoHV#d3#3R3O{wm|h-1_i_Jw!=JthE5BYW5h zG}C7gCW=P<+~)a1@d7tW?+UoieV>Bu3^9YQN!B&Q$u|OMv%wCh9jaaBO~IT_@RK!- zpc6slK13_X4R8l-mI2Knhv)+K$u&-Bs89cd5zrz6w>~{yS_Dlcp#chke;t`EIBuhI zP{e+`GrCCkAdAAMGQd&Z+<50B2iuC80k~BbW@RF)z*W0HFDoY&=YX3ofmT2t>s(uoTrC_ z0Y2E-H=70j?wAZY;Q2CQ|21^p+g&C+7hLk+M-gpLNUeEjJiAM`X z9wUV>rpLRa3qHP(MKh8OAUk@HCsKT)+QS2^mIOcU{5xoqA?RTY`6`E6is^T$OcNZp zw&nZnt+Q0)E<~-tC>uqLxWcfY+Eve90Fs?`F9gSh5tz~L?mrsal+ZYpPl^h&vDl6Z z=Qk9Zd%ijlX)#93tr+)MU39I6_)V~6<(1(SKj1LpW}>OTRTaWTR$e$!$w4-Dz^8!2 z7Y$|C`J*A=Jx>I3vN2+oj$_Y5TR;pBY(c=nR3x(ApC;;M$;O||fB#6H@%ZW?8z2x0 zb@c%KBcxVhvf5Qkg1d3f1kuNbVCvLj%Q{$-CDr2A6!{$guL810RLe(vdXp(+K*m2L`Sd{V4MW5ngJ|g45qgcWL~os^T&R1rkRdP z)arHwBYy&i7Qye_^LXpJL?>NT>-LsqP=xRr%Q9dQ&3I+Yd=XPU!;a9Lu1i3BEa|Ug z;qN;W)8?M91jQ`L2v!^6Saun0HL1Dh~zvhDp~3Ahuu9ArY{U zREQdSr<*>sgfNXoL~)Gay#+eDI1_Hb%-VB8nMo zL)TtA_K1v2rV=by54jLAG{PdPu9wy=OiFYgJ*-D3OZI&-&>7ddy~C6pZCUYkV1F+a z{^*UaW3gCz8-;ve1&R7ovS`L8S0)O_-J9lUZz%=w zMDtg+6$|Oajos`0=^SXe-T@|GKPHMdudKS+bi{kRR+qa>@*fd97Yp1pp3?;h9^RMS28%3+`%8|uCuu?D;e|MR;v)~ zzA#%-j$g2@KTi_}EPRC(f+Dn}D15Ydx&Prtyr2}GFEq;pr^=PBn=EJvNG|gEmKNo> z_SvR67jD*UJ1#pzIWUg_&s1jxoLXerUfNm4!7*x^D=J-H$vF#S#XNAQLNHUn^4y_s zpI@A{UjcOfG4Ah(IIb#X$N{6fD>Fm$PxAp85!ex&@)`BSS$o8ILM7 z8LhzUx2bMF+r2PgCeD=EUjn$C_oT*v7s;iJY16g2LrN$AL^SMc&Gf?f_Aq^m9Vo!@ zib${C+r#~OVV_^QXD=-9N_4bsgWSB=s5O{@fn0jDLS_pwvq#2+*sAOEYzC>_cr6sW z**a0vx-0#bBOPV z{bnDdOO*=|M90NFRtWnR6;qn`sVgFknyDd?Am_D*Ktj}(V}xE~n5OhyT8tgGw&vLw zI)jjp+)E$K816I9F=ox?9}ulbi$0;_atmMPLzRm7`^Xp%8`b1h0_ekae!{klLiVY4 z$>x6jd?bRtiBp1BUn6}$1}u0m{US%{uY@s=C9!46oR`?DT-XT=c;CGw%Zotj&J!Io z^}rEzyyW&auMfG7Q7?(n3>d;qs5AC%Bvufyjj5abw<~f0EOG_^^-D6GjNKcm@rcbZg^1qGdj2|z47^a1 z73nD=>7+b&-m5+>&1_S-!DlY!L2dcSLN*xJX(@Jd$^LXlu@M<%-%5&GFEEB~W3hGL-An&aRz=UG z8E;4T0aSpHj_sFQP+4=+A_?u;iNyDXU!s}737W*JtgfEf@bwTeOs3uL^6-6+@y;T7 zDaEVomSw%1AjuW)3!d4XZ$BE*VbJj9*!J=S0hg-e zN5i9-VOXaK`ABtVzIFL zhy4D?-M?cB{bMg}n4EAl(M`RBS^Nld-nr9yV-}EH? zcI1a6W=&!L|8;=%zOmcnXtMwjbKdAX$<-?*1Z@1XP;^DvcyE>nwf-k2iuJHqc`fD$XGQmek{QLQJFyoRauxCJW6u21#ez46G2fvL1Lg4eAJx!bA=FvxS9>jf)*5vekLQOv-t{2RuoPah;GGddF|2cb|MR#%<<$ zg_YH;%+2aKVsGMZdNmy<18VLMh_#6xf}rWj0)V0;C9_+AOS9ok!m|i8bdlR|SBVEL zRBIiExcB|>zE&FfIj72YZ96H&h+go(@b~ln!`4sH|=G#S79^RLO z)-?>lHCI?6X>gN#R>HD^p0QcD?iSGF#8#IkC(}TI>d+?*hh(**49?$Pv=YI)5;lnXly_P4dYxxRuJc(ILTtsIadV!dUysP6Uq1jRE{$meIk&?Pg zQCLP7P7gOoN__);NJdR22^n7UQnl90(>TLaCaW@vAuvR{SRtG+7Gw#r=G(pOL%393 zsTBxv(`?55_qCOck++pmd-=Cq|Fw1=!{Z)U0uGctHpx&!*M)2Ag`>A1&MD|(hN$C6 z1V#rPEqBo^pol``SfxN#vZ?6gK+VC;yP-%Lg}cm?31akoYSno;B(k{!5hm$2dZ+8p zs`C;jP%Ip~gu*zT)HKiKUw%IeJT}>qS!0;@^l7y)sdBHY4($%u~Zn z9OC0qHnnoA3#qFS%PWX0DO;0^F$a|9C6hw%NxlIrM(emfU8~y(%d-5V5BZ|S9Xfkc z_WpSN{i3R=sY8k=k%TO~j67tD-bjLZShL)ZRh?Z6Hc zQVW@h-=sOo7pF1W(!!X{%guQGjeuc$z{FU=_@;E-ihZBQA}hEDT^`n~ZWH^=vlnVf znp+D8-h*{6e8}O8vTPi5>x=VX1-v%$7CgFFItb9TT9)ZH5`0T@gNgl zVVOL%enW-ScBtqT;NFufKsFdtB*uS#2^xo2FLIDK3Mfs3*Ilv-vV?SC!_;6}x);wy zEZZ$Vl2Hw&uvk)B5WYgGX8}lI$ONm&RPu3%Kf}pe7o>#jeGUW4hWdnFMH=ZSze2SD7hOk0PzDG@BNP2I1ZKcIWe`KxWwi&mM>>T>@5)i-?YSzd)RtM<;5>-b0^{*dlrm z)nLFoG*Yrn=dQV-gil&Pj>$@{#2UV~6(R)BQPCRt%OcF-9a*nw+5^?t~;>U}G=4l+bQVe1^K&^=bXVdK> zHB4tU#sMw|kg5{MUY&Ti|LAkk!DmpMX+F=QXj*k;!6+eG)ruzMih~;^DXQg#0bo>z z!1UsA8Ut@Pu8*6W;`okz^y)JNhv6?L_AoTHE2qQmXxsCUMo2_DyKdUy@P+{{@;X30 zBWVNa2Zd1zm(DH%A}i8v48S#!F^g*;MI=Y;df!f22D@u(fwXx71#ji{hmgB3z3K+B zk%sLwT921C=nv_QqEm|(-uBrgU(aBPhM?el3qYe1fMVZp&#Q72FJ@99S}d!gR9Qmp zJ#4$*#!qgj&{mcO=9mvifGZ=!#7F$_Zl$l4)`6tX}29Sd(mNb8c0l0-4T6}~JJV8ooy zxBb+^U+?x$4g&!|?SKvz5P-C<-aI<8v9$cRt3TBROmjg<7Aak|W`_3axuHMg=4ODc zpq>$HDbZZ%eg2w!%|Y}h%5q7l0zj2I`1Gox93=f`l@x3)|3$s-IWTDHwxO)~o=1t= z4D=1^xDqjTd+2$JrmnPF!5&|QwHs5+*8K*-7`17~r6i zX2!MAx$oW6Ki!dda)n;RUce@?wdG=#<`@lPhsw zo*)9Vf4rDYgjjZPl6->bEo)Qj1{j+O8<1aPMbP(zRt*x_UM}nHKM>UH5)0FB z^DzNoiOqyV0(UO2oOU1n@}@>CM?^;gj6N4hO9{Y#&8GnxoV9HxTLWyEO%r0jh%w(> z#&Iqb9iOaxN)M#2UR^o8qE@n?(liKMN|Fq2Q}y$CVB1#ckkcbPPG}6ytYYz)<)%!( zHq<++*=WZ>opodI>G@U!+1Fy9rCng(N;*F`4Kz84!-ctRvHO1kR9B3OU8t-HDM}?# zwI3_yFjk1wKK$G3bI71H#`?T%5STM!@q2`oK;Bvdx%ATKTa==Zua)SW*$=_nS}b_b z6ICGYI(l;twl^^NVwY_7^iTRWpb7LZp+b`Klq=yr4bm&U(gRH2NcSFkT%>9|0%l6Y z%6!bKD3eR8L1-M*`U;I+gcV$kl>&nGpaeUh?Gs65%D`Ovo4SKi|n%`Uce&IL0HJ?1>%*-RmuUm z^2eyB{G+eoabSI{-08wXTr^{xxp)SUagnY`J2n;jf83crl3M<8@S=O{?9tBblwy@{4Or-MJ*`tx)CYg@8UfL!AHsRckpgEz{Rgfw~Xuy@S% z)fgD3Ex#-pwSVuSUJ3mKtoQKksDpXwGY9Lr)g4H`u2Fv??=SIkE2Huj Date: Thu, 12 Nov 2020 10:55:06 +0100 Subject: [PATCH 03/11] updated README.md --- .idea/compiler.xml | 6 ++++++ .idea/gradle.xml | 1 + .idea/misc.xml | 5 ++++- README.md | 3 ++- 4 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 .idea/compiler.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..61a9130 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 1b10434..2baa0fd 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -16,6 +16,7 @@ diff --git a/.idea/misc.xml b/.idea/misc.xml index be0cc41..00206b7 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,10 @@ - + + + + diff --git a/README.md b/README.md index 450e02b..d36b3e6 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,8 @@ Or create a BarChart ```kotlin val barChart = BarChart( - slices = provideSlices(), clickListener = null).build() + slices = provideSlices(), clickListener = null + ).build() chart.setBarChart(barChart) ``` From e3ca4936626e17d2e880ff91c56b08d9f9fea9db Mon Sep 17 00:00:00 2001 From: Stefan Gsottbauer Date: Thu, 12 Nov 2020 10:58:26 +0100 Subject: [PATCH 04/11] updated README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index d36b3e6..f401687 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,11 @@ Or use with custom legend adapter by inheriting from LegendAdapter chart.showLegend(legendLayout, CustomLegendAdapter()) ``` +Or if you use a barChart you can also change the orientation of the legendAdapter +```kotlin + chart4.showLegend(rootLayout = legendLayout, orientation = LinearLayoutManager.HORIZONTAL or LinearLayoutManager.VERTICAL) +``` + ## XML Attributes From fb346f138fff66a8bc2b454bcd7ba77d84b929a5 Mon Sep 17 00:00:00 2001 From: Stefan Gsottbauer Date: Thu, 12 Nov 2020 10:59:32 +0100 Subject: [PATCH 05/11] removed unused lines --- .../java/com/faskn/lib/ClickableBarChart.kt | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt b/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt index 353e03a..4e65eaf 100644 --- a/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt +++ b/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt @@ -52,10 +52,8 @@ class ClickableBarChart @JvmOverloads constructor( private var popupText: String? = null private var showPercentage = false private var currentAnimationPercentage = 0 - private var orientation: Orientation = Orientation.HORIZONTAL - init { initAttributes(attrs) } @@ -107,18 +105,6 @@ class ClickableBarChart @JvmOverloads constructor( slices = barChart?.slices } - - /*override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { - super.onSizeChanged(w, h, oldw, oldh) - - rectF = RectF( - 0f, - 0f, - width.coerceAtMost(height).toFloat(), - width.coerceAtMost(height).toFloat() - ) - }*/ - override fun onDraw(canvas: Canvas) { super.onDraw(canvas) @@ -149,7 +135,6 @@ class ClickableBarChart @JvmOverloads constructor( slicePaint ) } - } else { if (startPercentage < currentAnimationPercentage && endPercentage <= currentAnimationPercentage) { @@ -171,8 +156,6 @@ class ClickableBarChart @JvmOverloads constructor( } } - - startPercentage = endPercentage } } else { @@ -267,7 +250,6 @@ class ClickableBarChart @JvmOverloads constructor( val currentViewLocation = IntArray(2) this.getLocationOnScreen(currentViewLocation) - if (orientation == Orientation.VERTICAL) { popupView.doOnPreDraw { popupWindow.update( @@ -297,7 +279,6 @@ class ClickableBarChart @JvmOverloads constructor( invalidateAndRequestLayout() } - fun showPopup(show: Boolean) { showPopup = show } From e3a1c4c434c38ea1d170fda6bb30fc7c577e2195 Mon Sep 17 00:00:00 2001 From: Stefan Gsottbauer Date: Thu, 12 Nov 2020 14:48:18 +0100 Subject: [PATCH 06/11] =?UTF-8?q?=E2=9C=A8=20added=20ability=20to=20use=20?= =?UTF-8?q?custom=20layout=20manager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/faskn/lib/ClickableBarChart.kt | 19 ++++++++----------- .../java/com/faskn/lib/ClickablePieChart.kt | 14 ++++++++++---- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt b/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt index 4e65eaf..8afb9c8 100644 --- a/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt +++ b/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt @@ -54,6 +54,10 @@ class ClickableBarChart @JvmOverloads constructor( private var currentAnimationPercentage = 0 private var orientation: Orientation = Orientation.HORIZONTAL + private var defaultLayoutManager = + LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) + + init { initAttributes(attrs) } @@ -254,7 +258,7 @@ class ClickableBarChart @JvmOverloads constructor( popupView.doOnPreDraw { popupWindow.update( currentViewLocation[0] + (parent.measuredWidth / 2) - (it.width / 2), - (currentViewLocation[1] + parent.measuredHeight - (parent.measuredHeight * center) / 100), + (currentViewLocation[1] + parent.measuredHeight - (parent.measuredHeight * center) / 100), popupWindow.width, popupWindow.height ) @@ -286,18 +290,11 @@ class ClickableBarChart @JvmOverloads constructor( fun showLegend( rootLayout: ViewGroup, adapter: LegendAdapter = LegendAdapter(), - orientation: Int = LinearLayoutManager.VERTICAL + layoutManager: RecyclerView.LayoutManager = defaultLayoutManager ) { val recyclerView = RecyclerView(context) - val linearLayoutManager = - LinearLayoutManager( - context, if (orientation == LinearLayoutManager.VERTICAL) { - LinearLayoutManager.VERTICAL - } else { - LinearLayoutManager.HORIZONTAL - }, false - ) - recyclerView.layoutManager = linearLayoutManager + + recyclerView.layoutManager = layoutManager recyclerView.adapter = adapter slices?.toMutableList()?.let { adapter.setup(it) } recyclerView.overScrollMode = OVER_SCROLL_NEVER diff --git a/lib/src/main/java/com/faskn/lib/ClickablePieChart.kt b/lib/src/main/java/com/faskn/lib/ClickablePieChart.kt index a86f742..0aa44d7 100644 --- a/lib/src/main/java/com/faskn/lib/ClickablePieChart.kt +++ b/lib/src/main/java/com/faskn/lib/ClickablePieChart.kt @@ -62,6 +62,10 @@ class ClickablePieChart @JvmOverloads constructor( private var popupText: String? = null private var showPercentage = false + private var defaultLayoutManager = + LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) + + init { initAttributes(attrs) } @@ -288,11 +292,13 @@ class ClickablePieChart @JvmOverloads constructor( showPopup = show } - fun showLegend(rootLayout: ViewGroup, adapter: LegendAdapter = LegendAdapter()) { + fun showLegend( + rootLayout: ViewGroup, + adapter: LegendAdapter = LegendAdapter(), + layoutManager: RecyclerView.LayoutManager = defaultLayoutManager + ) { val recyclerView = RecyclerView(context) - val linearLayoutManager = - LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) - recyclerView.layoutManager = linearLayoutManager + recyclerView.layoutManager = layoutManager recyclerView.adapter = adapter slices?.toMutableList()?.let { adapter.setup(it) } recyclerView.overScrollMode = OVER_SCROLL_NEVER From 91777d57ac53330fe1e329534e89d7cdc682ae28 Mon Sep 17 00:00:00 2001 From: Stefan Gsottbauer Date: Thu, 12 Nov 2020 14:57:25 +0100 Subject: [PATCH 07/11] =?UTF-8?q?=F0=9F=90=9B=20updated=20lib=20to=20preve?= =?UTF-8?q?nt=20crashes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/faskn/clickablepiechart/MainActivity.kt | 5 ++++- lib/src/main/java/com/faskn/lib/ClickableBarChart.kt | 9 +++------ lib/src/main/java/com/faskn/lib/ClickablePieChart.kt | 9 +++------ 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/faskn/clickablepiechart/MainActivity.kt b/app/src/main/java/com/faskn/clickablepiechart/MainActivity.kt index a0dfa33..3ab3071 100644 --- a/app/src/main/java/com/faskn/clickablepiechart/MainActivity.kt +++ b/app/src/main/java/com/faskn/clickablepiechart/MainActivity.kt @@ -53,7 +53,10 @@ class MainActivity : AppCompatActivity() { chart4.setBarChart(barChartDSL) - chart4.showLegend(rootLayout = legendLayout4,orientation = LinearLayoutManager.HORIZONTAL) + chart4.showLegend( + rootLayout = legendLayout4, + layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false) + ) } private fun provideSlices(): ArrayList { diff --git a/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt b/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt index 8afb9c8..2048706 100644 --- a/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt +++ b/lib/src/main/java/com/faskn/lib/ClickableBarChart.kt @@ -54,10 +54,6 @@ class ClickableBarChart @JvmOverloads constructor( private var currentAnimationPercentage = 0 private var orientation: Orientation = Orientation.HORIZONTAL - private var defaultLayoutManager = - LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) - - init { initAttributes(attrs) } @@ -290,11 +286,12 @@ class ClickableBarChart @JvmOverloads constructor( fun showLegend( rootLayout: ViewGroup, adapter: LegendAdapter = LegendAdapter(), - layoutManager: RecyclerView.LayoutManager = defaultLayoutManager + layoutManager: RecyclerView.LayoutManager? = null ) { val recyclerView = RecyclerView(context) + recyclerView.layoutManager = + layoutManager ?: LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) - recyclerView.layoutManager = layoutManager recyclerView.adapter = adapter slices?.toMutableList()?.let { adapter.setup(it) } recyclerView.overScrollMode = OVER_SCROLL_NEVER diff --git a/lib/src/main/java/com/faskn/lib/ClickablePieChart.kt b/lib/src/main/java/com/faskn/lib/ClickablePieChart.kt index 0aa44d7..b324dd7 100644 --- a/lib/src/main/java/com/faskn/lib/ClickablePieChart.kt +++ b/lib/src/main/java/com/faskn/lib/ClickablePieChart.kt @@ -62,10 +62,6 @@ class ClickablePieChart @JvmOverloads constructor( private var popupText: String? = null private var showPercentage = false - private var defaultLayoutManager = - LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) - - init { initAttributes(attrs) } @@ -295,10 +291,11 @@ class ClickablePieChart @JvmOverloads constructor( fun showLegend( rootLayout: ViewGroup, adapter: LegendAdapter = LegendAdapter(), - layoutManager: RecyclerView.LayoutManager = defaultLayoutManager + layoutManager: RecyclerView.LayoutManager? = null ) { val recyclerView = RecyclerView(context) - recyclerView.layoutManager = layoutManager + recyclerView.layoutManager = + layoutManager ?: LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) recyclerView.adapter = adapter slices?.toMutableList()?.let { adapter.setup(it) } recyclerView.overScrollMode = OVER_SCROLL_NEVER From a41eb1363ac64d8a87e3473818e404b7be106ff0 Mon Sep 17 00:00:00 2001 From: Stefan Gsottbauer Date: Fri, 13 Nov 2020 12:36:48 +0100 Subject: [PATCH 08/11] =?UTF-8?q?=F0=9F=90=9B=20calculation=20of=20percent?= =?UTF-8?q?age=20was=20wrong?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/src/main/java/com/faskn/lib/BarChartDsl.kt | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/lib/src/main/java/com/faskn/lib/BarChartDsl.kt b/lib/src/main/java/com/faskn/lib/BarChartDsl.kt index a7a8f04..18bbc35 100644 --- a/lib/src/main/java/com/faskn/lib/BarChartDsl.kt +++ b/lib/src/main/java/com/faskn/lib/BarChartDsl.kt @@ -72,17 +72,9 @@ class BarChartBuilder { } private fun initPercentages() { - var remainder = 100 - slices.forEach { slice -> - val percentage = (slice.scaledValue!! * 100).toInt() - slice.percentage = percentage - remainder -= percentage - } - var i = 0 - while (remainder != 0) { - slices[i].percentage = slices[i].percentage!! + 1 - remainder -= 1 - i = (i + 1) % 4 + slices.forEachIndexed { index,slice -> + val percentage = (100 * slice.scaledValue!!).toInt() + slices[index].percentage = percentage } } From cc58dba85388792199dd9595ef7483c93223ec86 Mon Sep 17 00:00:00 2001 From: gsotti Date: Tue, 24 Nov 2020 12:47:46 +0100 Subject: [PATCH 09/11] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f401687..2487a87 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ allprojects { Step 2. Add the dependency ```gradle dependencies { - implementation 'com.github.furkanaskin:ClickablePieChart:1.0.7' + implementation 'com.github.gsotti:ClickablePieChart:1.0.12' } ``` From cc206c88833af4e84f7e144a59f68dedf14240a7 Mon Sep 17 00:00:00 2001 From: gsotti Date: Tue, 24 Nov 2020 12:48:13 +0100 Subject: [PATCH 10/11] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2487a87..1613ffa 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![](https://jitpack.io/v/furkanaskin/ClickablePieChart.svg)](https://jitpack.io/#furkanaskin/ClickablePieChart) +[![](https://jitpack.io/v/gsotti/ClickablePieChart.svg)](https://jitpack.io/#gsotti/ClickablePieChart) # ClickablePieChart Android Chart library, supported with **Kotlin DSL**. From 746964e953440bc6ed822592e25430cc39146a33 Mon Sep 17 00:00:00 2001 From: gsotti Date: Tue, 24 Nov 2020 12:54:17 +0100 Subject: [PATCH 11/11] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1613ffa..3d83735 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ allprojects { Step 2. Add the dependency ```gradle dependencies { - implementation 'com.github.gsotti:ClickablePieChart:1.0.12' + implementation 'com.github.gsotti:ClickablePieChart:1.0.13' } ```