From 25cafdcfa8eef417d51df7cb5c6278d9df4a0ef8 Mon Sep 17 00:00:00 2001 From: Philipp Jahoda Date: Thu, 2 Oct 2014 19:30:34 +0200 Subject: [PATCH] Improved LimitLines, added feature to draw labels for LimitLines. --- .../mpchartexample/LineChartActivity.java | 8 + .../mpchartexample/RadarChartActivitry.java | 1 + .../mikephil/charting/charts/BarChart.java | 208 +----------------- .../charting/charts/BarLineChartBase.java | 31 +++ .../mikephil/charting/charts/RadarChart.java | 1 + .../github/mikephil/charting/data/Entry.java | 2 +- .../mikephil/charting/utils/LimitLine.java | 51 ++++- 7 files changed, 93 insertions(+), 209 deletions(-) diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity.java index 49075d5cfb..99f03a7d4f 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity.java @@ -24,6 +24,7 @@ import com.github.mikephil.charting.interfaces.OnChartValueSelectedListener; import com.github.mikephil.charting.utils.Legend; import com.github.mikephil.charting.utils.Legend.LegendForm; +import com.github.mikephil.charting.utils.LimitLine.LimitLabelPosition; import com.github.mikephil.charting.utils.LimitLine; import com.github.mikephil.charting.utils.XLabels; import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase; @@ -59,6 +60,9 @@ protected void onCreate(Bundle savedInstanceState) { mChart = (LineChart) findViewById(R.id.chart1); mChart.setOnChartGestureListener(this); mChart.setOnChartValueSelectedListener(this); + + mChart.setUnit(" $"); + mChart.setDrawUnitsInChart(true); // if enabled, the chart will always start at zero on the y-axis mChart.setStartAtZero(false); @@ -346,10 +350,14 @@ private void setData(int count, float range) { LimitLine ll1 = new LimitLine(130f); ll1.setLineWidth(4f); ll1.enableDashedLine(10f, 10f, 0f); + ll1.setDrawValue(true); + ll1.setLabelPosition(LimitLabelPosition.RIGHT); LimitLine ll2 = new LimitLine(-30f); ll2.setLineWidth(4f); ll2.enableDashedLine(10f, 10f, 0f); + ll2.setDrawValue(true); + ll2.setLabelPosition(LimitLabelPosition.RIGHT); data.addLimitLine(ll1); data.addLimitLine(ll2); diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RadarChartActivitry.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RadarChartActivitry.java index 91abc2b665..b5368a04e1 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RadarChartActivitry.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RadarChartActivitry.java @@ -15,6 +15,7 @@ import com.github.mikephil.charting.utils.Legend; import com.github.mikephil.charting.utils.Legend.LegendPosition; import com.github.mikephil.charting.utils.ColorTemplate; +import com.github.mikephil.charting.utils.LimitLine; import com.github.mikephil.charting.utils.XLabels; import com.github.mikephil.charting.utils.YLabels; import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase; diff --git a/MPChartLib/src/com/github/mikephil/charting/charts/BarChart.java b/MPChartLib/src/com/github/mikephil/charting/charts/BarChart.java index 53546978de..fff64d9e31 100644 --- a/MPChartLib/src/com/github/mikephil/charting/charts/BarChart.java +++ b/MPChartLib/src/com/github/mikephil/charting/charts/BarChart.java @@ -88,75 +88,6 @@ protected void init() { // calculate3DColors(); } - // @Override - // public void setColorTemplate(ColorTemplate ct) { - // super.setColorTemplate(ct); - // - // calculate3DColors(); - // } - - // /** array that holds all the colors for the top 3D effect */ - // private ArrayList> mTopColors; - // - // /** array that holds all the colors for the side 3D effect */ - // private ArrayList> mSideColors; - // - // /** - // * calculates the 3D color arrays - // */ - // protected void calculate3DColors() { - // - // // generate the colors for the 3D effect - // mTopColors = new ArrayList>(); - // mSideColors = new ArrayList>(); - // - // float[] hsv = new float[3]; - // - // for (int i = 0; i < mCt.getColors().size(); i++) { - // - // // Get the colors for the DataSet at the current index. If the index - // // is out of bounds, reuse DataSet colors. - // ArrayList colors = mCt.getDataSetColors(i); - // ArrayList topColors = new ArrayList(); - // ArrayList sideColors = new ArrayList(); - // - // for (int j = 0; j < colors.size(); j++) { - // - // // extract the color - // int c = colors.get(j); - // Color.colorToHSV(c, hsv); // convert to hsv - // - // // make brighter - // hsv[1] = hsv[1] - 0.1f; // less saturation - // hsv[2] = hsv[2] + 0.1f; // more brightness - // - // // convert back - // c = Color.HSVToColor(hsv); - // - // // assign - // topColors.add(c); - // - // // get color again - // c = colors.get(j); - // - // // convert - // Color.colorToHSV(c, hsv); - // - // // make darker - // hsv[1] = hsv[1] + 0.1f; // more saturation - // hsv[2] = hsv[2] - 0.1f; // less brightness - // - // // reassing - // c = Color.HSVToColor(hsv); - // - // sideColors.add(c); - // } - // - // mTopColors.add(topColors); - // mSideColors.add(sideColors); - // } - // } - @Override protected void calcMinMax(boolean fixedValues) { super.calcMinMax(fixedValues); @@ -438,144 +369,7 @@ protected void drawVerticalGrid() { } } } - - // @Override - // protected void drawData() { - // - // ArrayList topPaths = new ArrayList(); - // ArrayList sidePaths = new ArrayList(); - // - // ArrayList dataSets = (ArrayList) - // mCurrentData.getDataSets(); - // - // // preparations for 3D bars - // if (m3DEnabled) { - // - // float[] pts = new float[] { - // 0f, 0f, 1f, 0f - // }; - // - // // calculate the depth depending on scale - // - // transformPointArray(pts); - // - // pts[3] = pts[2] - pts[0]; - // pts[2] = 0f; - // pts[1] = 0f; - // pts[0] = 0f; - // - // Matrix invert = new Matrix(); - // - // mMatrixOffset.invert(invert); - // invert.mapPoints(pts); - // - // mMatrixTouch.invert(invert); - // invert.mapPoints(pts); - // - // mMatrixValueToPx.invert(invert); - // invert.mapPoints(pts); - // - // float depth = Math.abs(pts[3] - pts[1]) * mDepth; - // - // for (int i = 0; i < mCurrentData.getDataSetCount(); i++) { - // - // DataSet dataSet = dataSets.get(i); - // ArrayList series = dataSet.getYVals(); - // - // for (int j = 0; j < series.size(); j++) { - // - // float x = series.get(j).getXIndex(); - // float y = series.get(j).getVal(); - // float left = x + mBarSpace / 2f; - // float right = x + 1f - mBarSpace / 2f; - // float top = y >= 0 ? y : 0; - // - // // create the 3D effect paths for the top and side - // Path topPath = new Path(); - // topPath.moveTo(left, top); - // topPath.lineTo(left + mSkew, top + depth); - // topPath.lineTo(right + mSkew, top + depth); - // topPath.lineTo(right, top); - // - // topPaths.add(topPath); - // - // Path sidePath = new Path(); - // sidePath.moveTo(right, top); - // sidePath.lineTo(right + mSkew, top + depth); - // sidePath.lineTo(right + mSkew, depth); - // sidePath.lineTo(right, 0); - // - // sidePaths.add(sidePath); - // } - // } - // - // transformPaths(topPaths); - // transformPaths(sidePaths); - // } - // - // int cnt = 0; - // - // // 2D drawing - // for (int i = 0; i < mCurrentData.getDataSetCount(); i++) { - // - // BarDataSet dataSet = dataSets.get(i); - // ArrayList series = dataSet.getYVals(); - // - // // Get the colors for the DataSet at the current index. If the - // // index - // // is out of bounds, reuse DataSet colors. - // ArrayList colors = mCt.getDataSetColors(i % - // mCt.getColors().size()); - // ArrayList colors3DTop = mTopColors.get(i % - // mCt.getColors().size()); - // ArrayList colors3DSide = mSideColors.get(i % - // mCt.getColors().size()); - // - // // do the drawing - // for (int j = 0; j < dataSet.getEntryCount(); j++) { - // - // // Set the color for the currently drawn value. If the index - // // is - // // out of bounds, reuse colors. - // mRenderPaint.setColor(colors.get(j % colors.size())); - // - // int x = series.get(j).getXIndex(); - // float y = series.get(j).getVal(); - // float left = x + mBarSpace / 2f; - // float right = x + 1f - mBarSpace / 2f; - // float top = y >= 0 ? y : 0; - // float bottom = y <= 0 ? y : 0; - // - // mBarRect.set(left, top, right, bottom); - // - // transformRect(mBarRect); - // - // // avoid drawing outofbounds values - // if (isOffContentRight(mBarRect.left)) - // break; - // - // if (isOffContentLeft(mBarRect.right)) { - // cnt++; - // continue; - // } - // - // mDrawCanvas.drawRect(mBarRect, mRenderPaint); - // - // // 3D drawing - // if (m3DEnabled) { - // - // mRenderPaint.setColor(colors3DTop.get(j % colors3DTop.size())); - // mDrawCanvas.drawPath(topPaths.get(cnt), mRenderPaint); - // - // mRenderPaint.setColor(colors3DSide.get(j % colors3DSide.size())); - // mDrawCanvas.drawPath(sidePaths.get(cnt), mRenderPaint); - // } - // - // cnt++; - // } - // } - // } - + @Override protected void drawValues() { diff --git a/MPChartLib/src/com/github/mikephil/charting/charts/BarLineChartBase.java b/MPChartLib/src/com/github/mikephil/charting/charts/BarLineChartBase.java index 8beb8777e3..0b6cfe0af4 100644 --- a/MPChartLib/src/com/github/mikephil/charting/charts/BarLineChartBase.java +++ b/MPChartLib/src/com/github/mikephil/charting/charts/BarLineChartBase.java @@ -26,6 +26,7 @@ import com.github.mikephil.charting.listener.BarLineChartTouchListener; import com.github.mikephil.charting.utils.Highlight; import com.github.mikephil.charting.utils.Legend.LegendPosition; +import com.github.mikephil.charting.utils.LimitLine.LimitLabelPosition; import com.github.mikephil.charting.utils.LimitLine; import com.github.mikephil.charting.utils.PointD; import com.github.mikephil.charting.utils.SelInfo; @@ -912,6 +913,36 @@ private void drawLimitLines() { mLimitLinePaint.setStrokeWidth(l.getLineWidth()); mDrawCanvas.drawLine(pts[0], pts[1], pts[2], pts[3], mLimitLinePaint); + + // if drawing the limit-value is enabled + if (l.isDrawValueEnabled()) { + + // save text align + Align align = mValuePaint.getTextAlign(); + + float xOffset = Utils.convertDpToPixel(4f); + float yOffset = l.getLineWidth() + xOffset; + String label = mValueFormatter.getFormattedValue(l.getLimit()); + + if (mDrawUnitInChart) + label += mUnit; + + if (l.getLabelPosition() == LimitLabelPosition.RIGHT) { + + mValuePaint.setTextAlign(Align.RIGHT); + mDrawCanvas.drawText(label, getWidth() - mOffsetRight + - xOffset, + pts[1] - yOffset, mValuePaint); + + } else { + mValuePaint.setTextAlign(Align.LEFT); + mDrawCanvas.drawText(label, mOffsetLeft + + xOffset, + pts[1] - yOffset, mValuePaint); + } + + mValuePaint.setTextAlign(align); + } } } diff --git a/MPChartLib/src/com/github/mikephil/charting/charts/RadarChart.java b/MPChartLib/src/com/github/mikephil/charting/charts/RadarChart.java index 0ec7e6f9b1..2c0099e245 100644 --- a/MPChartLib/src/com/github/mikephil/charting/charts/RadarChart.java +++ b/MPChartLib/src/com/github/mikephil/charting/charts/RadarChart.java @@ -15,6 +15,7 @@ import com.github.mikephil.charting.data.RadarData; import com.github.mikephil.charting.data.RadarDataSet; import com.github.mikephil.charting.utils.Legend.LegendPosition; +import com.github.mikephil.charting.utils.LimitLine.LimitLabelPosition; import com.github.mikephil.charting.utils.LimitLine; import com.github.mikephil.charting.utils.Utils; import com.github.mikephil.charting.utils.XLabels; diff --git a/MPChartLib/src/com/github/mikephil/charting/data/Entry.java b/MPChartLib/src/com/github/mikephil/charting/data/Entry.java index 8971a1dd74..59e6fd80e3 100644 --- a/MPChartLib/src/com/github/mikephil/charting/data/Entry.java +++ b/MPChartLib/src/com/github/mikephil/charting/data/Entry.java @@ -149,7 +149,7 @@ public boolean equalTo(Entry e) { if (e.mXIndex != this.mXIndex) return false; - if (Math.abs(e.mVal - this.mVal) > 0.0001) + if (Math.abs(e.mVal - this.mVal) > 0.00001f) return false; return true; diff --git a/MPChartLib/src/com/github/mikephil/charting/utils/LimitLine.java b/MPChartLib/src/com/github/mikephil/charting/utils/LimitLine.java index f60ecb7353..7ed06e2418 100644 --- a/MPChartLib/src/com/github/mikephil/charting/utils/LimitLine.java +++ b/MPChartLib/src/com/github/mikephil/charting/utils/LimitLine.java @@ -22,9 +22,20 @@ public class LimitLine { /** the color of the limit line */ private int mLineColor = Color.rgb(237, 91, 91); + /** flag that indicates if the value of the limit line is drawn or not */ + private boolean mDrawValue = true; + /** the path effect of this LimitLine that makes dashed lines possible */ private DashPathEffect mDashPathEffect = null; + /** indicates the position of the LimitLine label */ + private LimitLabelPosition mLabelPosition = LimitLabelPosition.RIGHT; + + /** enum that indicates the position of the LimitLine label */ + public enum LimitLabelPosition { + LEFT, RIGHT + } + /** * Constructor with limit. * @@ -115,7 +126,7 @@ public void disableDashedLine() { public boolean isDashedLineEnabled() { return mDashPathEffect == null ? false : true; } - + /** * returns the DashPathEffect that is set for this LimitLine * @@ -124,4 +135,42 @@ public boolean isDashedLineEnabled() { public DashPathEffect getDashPathEffect() { return mDashPathEffect; } + + /** + * Set this to true to enable the value of the LimitLine to be drawn next to + * it. Default: true, not supported for RadarChart. + * + * @param enabled + */ + public void setDrawValue(boolean enabled) { + mDrawValue = enabled; + } + + /** + * Returns true if drawing the value is enabled, false if not. + * + * @return + */ + public boolean isDrawValueEnabled() { + return mDrawValue; + } + + /** + * Sets the position of the LimitLine value label (either on the right or on + * the left edge of the chart). Not supported for RadarChart. + * + * @param pos + */ + public void setLabelPosition(LimitLabelPosition pos) { + mLabelPosition = pos; + } + + /** + * Returns the position of the LimitLine label (value). + * + * @return + */ + public LimitLabelPosition getLabelPosition() { + return mLabelPosition; + } }