diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/RadarChart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/RadarChart.java deleted file mode 100644 index 15304dadd..000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/RadarChart.java +++ /dev/null @@ -1,381 +0,0 @@ - -package com.github.mikephil.charting.charts; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.RectF; -import android.util.AttributeSet; - -import com.github.mikephil.charting.components.YAxis; -import com.github.mikephil.charting.components.YAxis.AxisDependency; -import com.github.mikephil.charting.data.RadarData; -import com.github.mikephil.charting.highlight.RadarHighlighter; -import com.github.mikephil.charting.renderer.RadarChartRenderer; -import com.github.mikephil.charting.renderer.XAxisRendererRadarChart; -import com.github.mikephil.charting.renderer.YAxisRendererRadarChart; -import com.github.mikephil.charting.utils.Utils; -import com.github.mikephil.charting.utils.UtilsKtKt; - -import java.util.List; - -import androidx.annotation.NonNull; - -/** - * Implementation of the RadarChart, a "spidernet"-like chart. It works best - * when displaying 5-10 entries per DataSet. - * - * @author Philipp Jahoda - */ -public class RadarChart extends PieRadarChartBase { - - /** - * width of the main web lines - */ - private float mWebLineWidth = 2.5f; - - /** - * width of the inner web lines - */ - private float mInnerWebLineWidth = 1.5f; - - /** - * color for the main web lines - */ - private int mWebColor = Color.rgb(122, 122, 122); - - /** - * color for the inner web - */ - private int mWebColorInner = Color.rgb(122, 122, 122); - - /** - * transparency the grid is drawn with (0-255) - */ - private int mWebAlpha = 150; - - /** - * flag indicating if the web lines should be drawn or not - */ - private boolean mDrawWeb = true; - - /** - * modulus that determines how many labels and web-lines are skipped before the next is drawn - */ - private int mSkipWebLineCount = 0; - - /** - * the object reprsenting the y-axis labels - */ - private YAxis mYAxis; - - private List colorList; - - protected YAxisRendererRadarChart mYAxisRenderer; - protected XAxisRendererRadarChart mXAxisRenderer; - - public RadarChart(Context context) { - super(context); - } - - public RadarChart(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public RadarChart(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - @Override - protected void init() { - super.init(); - - mYAxis = new YAxis(AxisDependency.LEFT); - mYAxis.setLabelXOffset(10f); - - mWebLineWidth = UtilsKtKt.convertDpToPixel(1.5f); - mInnerWebLineWidth = UtilsKtKt.convertDpToPixel(0.75f); - - mRenderer = new RadarChartRenderer(this, mAnimator, mViewPortHandler); - mYAxisRenderer = new YAxisRendererRadarChart(mViewPortHandler, mYAxis, this); - mXAxisRenderer = new XAxisRendererRadarChart(mViewPortHandler, mXAxis, this); - - mHighlighter = new RadarHighlighter(this); - } - - @Override - protected void calcMinMax() { - super.calcMinMax(); - - mYAxis.calculate(mData.getYMin(AxisDependency.LEFT), mData.getYMax(AxisDependency.LEFT)); - mXAxis.calculate(0, mData.getMaxEntryCountSet().getEntryCount()); - } - - @Override - public void notifyDataSetChanged() { - if (mData == null) - return; - - calcMinMax(); - - mYAxisRenderer.computeAxis(mYAxis.mAxisMinimum, mYAxis.mAxisMaximum, mYAxis.isInverted()); - mXAxisRenderer.computeAxis(mXAxis.mAxisMinimum, mXAxis.mAxisMaximum, false); - - if (mLegend != null && !mLegend.isLegendCustom()) - mLegendRenderer.computeLegend(mData); - - calculateOffsets(); - } - - @Override - protected void onDraw(@NonNull Canvas canvas) { - super.onDraw(canvas); - - if (mData == null) - return; - -// if (mYAxis.isEnabled()) -// mYAxisRenderer.computeAxis(mYAxis.mAxisMinimum, mYAxis.mAxisMaximum, mYAxis.isInverted()); - - if (mXAxis.isEnabled()) - mXAxisRenderer.computeAxis(mXAxis.mAxisMinimum, mXAxis.mAxisMaximum, false); - - mXAxisRenderer.renderAxisLabels(canvas); - - if (mDrawWeb) - mRenderer.drawExtras(canvas); - - if (mYAxis.isEnabled() && mYAxis.isDrawLimitLinesBehindDataEnabled()) - mYAxisRenderer.renderLimitLines(canvas); - - mRenderer.drawData(canvas); - - if (valuesToHighlight()) - mRenderer.drawHighlighted(canvas, mIndicesToHighlight); - - if (mYAxis.isEnabled() && !mYAxis.isDrawLimitLinesBehindDataEnabled()) - mYAxisRenderer.renderLimitLines(canvas); - - mYAxisRenderer.renderAxisLabels(canvas); - - mRenderer.drawValues(canvas); - - mLegendRenderer.renderLegend(canvas); - - drawDescription(canvas); - - drawMarkers(canvas); - } - - /** - * Returns the factor that is needed to transform values into pixels. - * - */ - public float getFactor() { - RectF content = mViewPortHandler.getContentRect(); - return Math.min(content.width() / 2f, content.height() / 2f) / mYAxis.mAxisRange; - } - - /** - * Returns the angle that each slice in the radar chart occupies. - * - */ - public float getSliceAngle() { - return 360f / (float) mData.getMaxEntryCountSet().getEntryCount(); - } - - - public void setLayerColorList(List colorList) { - if (colorList == null || colorList.isEmpty()) { - return; - } - this.colorList = colorList; - } - - public boolean isCustomLayerColorEnable() { - if (mData == null) { - return false; - } - return colorList != null && colorList.size() == getYAxis().mEntryCount; - } - - public List getLayerColorList() { - return colorList; - } - - @Override - public int getIndexForAngle(float angle) { - - // take the current angle of the chart into consideration - float a = Utils.getNormalizedAngle(angle - getRotationAngle()); - - float sliceangle = getSliceAngle(); - - int max = mData.getMaxEntryCountSet().getEntryCount(); - - int index = 0; - - for (int i = 0; i < max; i++) { - - float referenceAngle = sliceangle * (i + 1) - sliceangle / 2f; - - if (referenceAngle > a) { - index = i; - break; - } - } - - return index; - } - - /** - * Returns the object that represents all y-labels of the RadarChart. - * - */ - public YAxis getYAxis() { - return mYAxis; - } - - /** - * Sets the width of the web lines that come from the center. - * - */ - public void setWebLineWidth(float width) { - mWebLineWidth = UtilsKtKt.convertDpToPixel(width); - } - - public float getWebLineWidth() { - return mWebLineWidth; - } - - /** - * Sets the width of the web lines that are in between the lines coming from - * the center. - * - */ - public void setWebLineWidthInner(float width) { - mInnerWebLineWidth = UtilsKtKt.convertDpToPixel(width); - } - - public float getWebLineWidthInner() { - return mInnerWebLineWidth; - } - - /** - * Sets the transparency (alpha) value for all web lines, default: 150, 255 - * = 100% opaque, 0 = 100% transparent - * - */ - public void setWebAlpha(int alpha) { - mWebAlpha = alpha; - } - - /** - * Returns the alpha value for all web lines. - * - */ - public int getWebAlpha() { - return mWebAlpha; - } - - /** - * Sets the color for the web lines that come from the center. Don't forget - * to use getResources().getColor(...) when loading a color from the - * resources. Default: Color.rgb(122, 122, 122) - * - */ - public void setWebColor(int color) { - mWebColor = color; - } - - public int getWebColor() { - return mWebColor; - } - - /** - * Sets the color for the web lines in between the lines that come from the - * center. Don't forget to use getResources().getColor(...) when loading a - * color from the resources. Default: Color.rgb(122, 122, 122) - * - */ - public void setWebColorInner(int color) { - mWebColorInner = color; - } - - public int getWebColorInner() { - return mWebColorInner; - } - - /** - * If set to true, drawing the web is enabled, if set to false, drawing the - * whole web is disabled. Default: true - * - */ - public void setDrawWeb(boolean enabled) { - mDrawWeb = enabled; - } - - /** - * Sets the number of web-lines that should be skipped on chart web before the - * next one is drawn. This targets the lines that come from the center of the RadarChart. - * - * @param count if count = 1 -> 1 line is skipped in between - */ - public void setSkipWebLineCount(int count) { - - mSkipWebLineCount = Math.max(0, count); - } - - /** - * Returns the modulus that is used for skipping web-lines. - * - */ - public int getSkipWebLineCount() { - return mSkipWebLineCount; - } - - @Override - protected float getRequiredLegendOffset() { - return mLegendRenderer.getLabelPaint().getTextSize() * 4.f; - } - - @Override - protected float getRequiredBaseOffset() { - return mXAxis.isEnabled() && mXAxis.isDrawLabelsEnabled() ? - mXAxis.mLabelWidth : - UtilsKtKt.convertDpToPixel(10f); - } - - @Override - public float getRadius() { - RectF content = mViewPortHandler.getContentRect(); - return Math.min(content.width() / 2f, content.height() / 2f); - } - - /** - * Returns the maximum value this chart can display on it's y-axis. - */ - public float getYChartMax() { - return mYAxis.mAxisMaximum; - } - - /** - * Returns the minimum value this chart can display on it's y-axis. - */ - public float getYChartMin() { - return mYAxis.mAxisMinimum; - } - - /** - * Returns the range of y-values this chart can display. - * - */ - public float getYRange() { - return mYAxis.mAxisRange; - } - - @Override - public String getAccessibilityDescription() { - return "This is a Radar chart"; - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/RadarChart.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/RadarChart.kt new file mode 100644 index 000000000..3708aa3ee --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/RadarChart.kt @@ -0,0 +1,305 @@ +package com.github.mikephil.charting.charts + +import android.content.Context +import android.graphics.Canvas +import android.graphics.Color +import android.util.AttributeSet +import com.github.mikephil.charting.components.YAxis +import com.github.mikephil.charting.components.YAxis.AxisDependency +import com.github.mikephil.charting.data.RadarData +import com.github.mikephil.charting.highlight.RadarHighlighter +import com.github.mikephil.charting.renderer.RadarChartRenderer +import com.github.mikephil.charting.renderer.XAxisRendererRadarChart +import com.github.mikephil.charting.renderer.YAxisRendererRadarChart +import com.github.mikephil.charting.utils.Utils +import com.github.mikephil.charting.utils.convertDpToPixel +import kotlin.math.max +import kotlin.math.min + +/** + * Implementation of the RadarChart, a "spidernet"-like chart. It works best when displaying 5-10 entries per DataSet. + */ +class RadarChart : PieRadarChartBase { + /** + * width of the main web lines + */ + private var mWebLineWidth = 2.5f + + /** + * width of the inner web lines + */ + private var mInnerWebLineWidth = 1.5f + + /** + * Sets the color for the web lines that come from the center. Don't forget + * to use getResources().getColor(...) when loading a color from the + * resources. Default: Color.rgb(122, 122, 122) + * + */ + /** + * color for the main web lines + */ + var webColor: Int = Color.rgb(122, 122, 122) + + /** + * Sets the color for the web lines in between the lines that come from the + * center. Don't forget to use getResources().getColor(...) when loading a + * color from the resources. Default: Color.rgb(122, 122, 122) + * + */ + /** + * color for the inner web + */ + var webColorInner: Int = Color.rgb(122, 122, 122) + + /** + * Returns the alpha value for all web lines. + * + */ + /** + * Sets the transparency (alpha) value for all web lines, default: 150, 255 + * = 100% opaque, 0 = 100% transparent + * + */ + /** + * transparency the grid is drawn with (0-255) + */ + var webAlpha: Int = 150 + + /** + * flag indicating if the web lines should be drawn or not + */ + private var mDrawWeb = true + + /** + * modulus that determines how many labels and web-lines are skipped before the next is drawn + */ + private var mSkipWebLineCount = 0 + + /** + * the object reprsenting the y-axis labels + */ + private var mYAxis: YAxis? = null + + private var colorList: MutableList = mutableListOf() + + protected var mYAxisRenderer: YAxisRendererRadarChart? = null + protected var mXAxisRenderer: XAxisRendererRadarChart? = null + + constructor(context: Context?) : super(context) + + constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) + + constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) + + override fun init() { + super.init() + + mYAxis = YAxis(AxisDependency.LEFT) + mYAxis!!.labelXOffset = 10f + + mWebLineWidth = 1.5f.convertDpToPixel() + mInnerWebLineWidth = 0.75f.convertDpToPixel() + + mRenderer = RadarChartRenderer(this, mAnimator, mViewPortHandler) + mYAxisRenderer = YAxisRendererRadarChart(mViewPortHandler, mYAxis!!, this) + mXAxisRenderer = XAxisRendererRadarChart(mViewPortHandler, mXAxis, this) + + mHighlighter = RadarHighlighter(this) + } + + override fun calcMinMax() { + super.calcMinMax() + + mYAxis!!.calculate(mData.getYMin(AxisDependency.LEFT), mData.getYMax(AxisDependency.LEFT)) + mXAxis.calculate(0f, mData.maxEntryCountSet!!.entryCount.toFloat()) + } + + override fun notifyDataSetChanged() { + if (mData == null) return + + calcMinMax() + + mYAxisRenderer!!.computeAxis(mYAxis!!.mAxisMinimum, mYAxis!!.mAxisMaximum, mYAxis!!.isInverted) + mXAxisRenderer!!.computeAxis(mXAxis.mAxisMinimum, mXAxis.mAxisMaximum, false) + + if (mLegend != null && !mLegend.isLegendCustom) mLegendRenderer.computeLegend(mData) + + calculateOffsets() + } + + protected override fun onDraw(canvas: Canvas) { + super.onDraw(canvas) + + if (mData == null) return + + // if (mYAxis.isEnabled()) +// mYAxisRenderer.computeAxis(mYAxis.mAxisMinimum, mYAxis.mAxisMaximum, mYAxis.isInverted()); + if (mXAxis.isEnabled) mXAxisRenderer!!.computeAxis(mXAxis.mAxisMinimum, mXAxis.mAxisMaximum, false) + + mXAxisRenderer!!.renderAxisLabels(canvas) + + if (mDrawWeb) mRenderer.drawExtras(canvas) + + if (mYAxis!!.isEnabled && mYAxis!!.isDrawLimitLinesBehindDataEnabled) mYAxisRenderer!!.renderLimitLines(canvas) + + mRenderer.drawData(canvas) + + if (valuesToHighlight()) mRenderer.drawHighlighted(canvas, mIndicesToHighlight) + + if (mYAxis!!.isEnabled && !mYAxis!!.isDrawLimitLinesBehindDataEnabled) mYAxisRenderer!!.renderLimitLines(canvas) + + mYAxisRenderer!!.renderAxisLabels(canvas) + + mRenderer.drawValues(canvas) + + mLegendRenderer.renderLegend(canvas) + + drawDescription(canvas) + + drawMarkers(canvas) + } + + val factor: Float + /** + * Returns the factor that is needed to transform values into pixels. + * + */ + get() { + val content = mViewPortHandler.contentRect + return min(content.width() / 2f, content.height() / 2f) / mYAxis!!.mAxisRange + } + + val sliceAngle: Float + /** + * Returns the angle that each slice in the radar chart occupies. + * + */ + get() = 360f / mData.maxEntryCountSet!!.entryCount.toFloat() + + + val isCustomLayerColorEnable: Boolean + get() { + if (mData == null) { + return false + } + return colorList.size == this.yAxis.mEntryCount + } + + var layerColorList: MutableList + get() = colorList + set(colorList) { + if (colorList.isEmpty()) { + return + } + this.colorList = colorList + } + + override fun getIndexForAngle(angle: Float): Int { + // take the current angle of the chart into consideration + + val a = Utils.getNormalizedAngle(angle - rotationAngle) + + val sliceangle = this.sliceAngle + + val max = mData.maxEntryCountSet!!.entryCount + + var index = 0 + + for (i in 0.. a) { + index = i + break + } + } + + return index + } + + val yAxis: YAxis + /** + * Returns the object that represents all y-labels of the RadarChart. + * + */ + get() = mYAxis!! + + var webLineWidth: Float + get() = mWebLineWidth + /** + * Sets the width of the web lines that come from the center. + * + */ + set(width) { + mWebLineWidth = width.convertDpToPixel() + } + + var webLineWidthInner: Float + get() = mInnerWebLineWidth + /** + * Sets the width of the web lines that are in between the lines coming from + * the center. + * + */ + set(width) { + mInnerWebLineWidth = width.convertDpToPixel() + } + + /** + * If set to true, drawing the web is enabled, if set to false, drawing the + * whole web is disabled. Default: true + * + */ + fun setDrawWeb(enabled: Boolean) { + mDrawWeb = enabled + } + + var skipWebLineCount: Int + get() = mSkipWebLineCount + /** + * Sets the number of web-lines that should be skipped on chart web before the + * next one is drawn. This targets the lines that come from the center of the RadarChart. + * + * @param count if count = 1 -> 1 line is skipped in between + */ + set(count) { + mSkipWebLineCount = max(0, count) + } + + override val requiredLegendOffset: Float + get() = mLegendRenderer.labelPaint.textSize * 4f + + override val requiredBaseOffset: Float + get() = if (mXAxis.isEnabled && mXAxis.isDrawLabelsEnabled) mXAxis.mLabelWidth.toFloat() else 10f.convertDpToPixel() + + override val radius: Float + get() { + val content = mViewPortHandler.contentRect + return min(content.width() / 2f, content.height() / 2f) + } + + /** + * Returns the maximum value this chart can display on it's y-axis. + */ + override fun getYChartMax(): Float { + return mYAxis!!.mAxisMaximum + } + + /** + * Returns the minimum value this chart can display on it's y-axis. + */ + override fun getYChartMin(): Float { + return mYAxis!!.mAxisMinimum + } + + val yRange: Float + /** + * Returns the range of y-values this chart can display. + */ + get() = mYAxis!!.mAxisRange + + override fun getAccessibilityDescription(): String { + return "This is a Radar chart" + } +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/RadarHighlighter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/RadarHighlighter.kt index 69a8da737..5272b9448 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/RadarHighlighter.kt +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/highlight/RadarHighlighter.kt @@ -10,7 +10,7 @@ open class RadarHighlighter(chart: RadarChart) : PieRadarHighlighter override fun getClosestHighlight(index: Int, x: Float, y: Float): Highlight? { val highlights = getHighlightsAtIndex(index) - val distanceToCenter = chartPieRadar.distanceToCenter(x, y) / chartPieRadar.getFactor() + val distanceToCenter = chartPieRadar.distanceToCenter(x, y) / chartPieRadar.factor var closest: Highlight? = null var distance = Float.MAX_VALUE @@ -40,7 +40,7 @@ open class RadarHighlighter(chart: RadarChart) : PieRadarHighlighter val phaseX = chartPieRadar.animator.phaseX val phaseY = chartPieRadar.animator.phaseY val sliceAngle = chartPieRadar.sliceAngle - val factor = chartPieRadar.getFactor() + val factor = chartPieRadar.factor val pOut = MPPointF.getInstance(0f, 0f) for (i in 0.. = ArrayList() + val colorList: MutableList = ArrayList() colorList.add(Color.rgb(222, 166, 111)) colorList.add(Color.rgb(220, 206, 138)) colorList.add(Color.rgb(243, 255, 192)) colorList.add(Color.rgb(240, 255, 240)) colorList.add(Color.rgb(250, 255, 250)) - binding.chart1.setLayerColorList(colorList) + binding.chart1.layerColorList = colorList binding.chart1.invalidate() }