package com.github.mikephil.charting.charts; import android.content.Context; import android.graphics.RectF; import android.util.AttributeSet; import android.util.Log; import com.github.mikephil.charting.components.YAxis.AxisDependency; import com.github.mikephil.charting.data.BarData; import com.github.mikephil.charting.data.BarDataSet; import com.github.mikephil.charting.data.BarEntry; import com.github.mikephil.charting.highlight.BarHighlighter; import com.github.mikephil.charting.highlight.Highlight; import com.github.mikephil.charting.interfaces.BarDataProvider; import com.github.mikephil.charting.renderer.BarChartRenderer; import com.github.mikephil.charting.renderer.XAxisRendererBarChart; import java.util.HashSet; /** * Chart that draws bars. * * @author Philipp Jahoda */ public class BarChart extends BarLineChartBase<BarData> implements BarDataProvider { /** * flag that enables or disables the highlighting arrow */ private boolean mDrawHighlightArrow = false; /** * if set to true, all values are drawn above their bars, instead of below their top */ private boolean mDrawValueAboveBar = true; /** * if set to true, all values of a stack are drawn individually, and not just their sum */ // private boolean mDrawValuesForWholeStack = true; /** * if set to true, a grey area is drawn behind each bar that indicates the maximum value */ private boolean mDrawBarShadow = false; public void setFixSet(HashSet<Integer> fixSet) { mRenderer.setFixSet(fixSet); } public BarChart(Context context) { super(context); } public BarChart(Context context, AttributeSet attrs) { super(context, attrs); } public BarChart(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void init() { super.init(); mRenderer = new BarChartRenderer(this, mAnimator, mViewPortHandler); mXAxisRenderer = new XAxisRendererBarChart(mViewPortHandler, mXAxis, mLeftAxisTransformer, this); mHighlighter = new BarHighlighter(this); mXChartMin = -0.5f; } @Override protected void calcMinMax() { super.calcMinMax(); // increase deltax by 1 because the bars have a width of 1 mDeltaX += 0.5f; // extend xDelta to make space for multiple datasets (if ther are one) mDeltaX *= mData.getDataSetCount(); float groupSpace = mData.getGroupSpace(); mDeltaX += mData.getXValCount() * groupSpace; mXChartMax = mDeltaX - mXChartMin; } /** * Returns the Highlight object (contains x-index and DataSet index) of the selected value at the given touch point * inside the BarChart. * * @param x * @param y * @return */ @Override public Highlight getHighlightByTouchPoint(float x, float y) { if (mDataNotSet || mData == null) { Log.e(LOG_TAG, "Can't select by touch. No data set."); return null; } else return mHighlighter.getHighlight(x, y); } /** * Returns the bounding box of the specified Entry in the specified DataSet. Returns null if the Entry could not be * found in the charts data. * * @param e * @return */ public RectF getBarBounds(BarEntry e) { BarDataSet set = mData.getDataSetForEntry(e); if (set == null) return null; float barspace = set.getBarSpace(); float y = e.getVal(); float x = e.getXIndex(); float barWidth = 0.5f; float spaceHalf = barspace / 2f; float left = x - barWidth + spaceHalf; float right = x + barWidth - spaceHalf; float top = y >= 0 ? y : 0; float bottom = y <= 0 ? y : 0; RectF bounds = new RectF(left, top, right, bottom); getTransformer(set.getAxisDependency()).rectValueToPixel(bounds); return bounds; } /** * set this to true to draw the highlightning arrow * * @param enabled */ public void setDrawHighlightArrow(boolean enabled) { mDrawHighlightArrow = enabled; } /** * returns true if drawing the highlighting arrow is enabled, false if not * * @return */ public boolean isDrawHighlightArrowEnabled() { return mDrawHighlightArrow; } /** * If set to true, all values are drawn above their bars, instead of below their top. * * @param enabled */ public void setDrawValueAboveBar(boolean enabled) { mDrawValueAboveBar = enabled; } /** * returns true if drawing values above bars is enabled, false if not * * @return */ public boolean isDrawValueAboveBarEnabled() { return mDrawValueAboveBar; } // /** // * if set to true, all values of a stack are drawn individually, and not // * just their sum // * // * @param enabled // */ // public void setDrawValuesForWholeStack(boolean enabled) { // mDrawValuesForWholeStack = enabled; // } // // /** // * returns true if all values of a stack are drawn, and not just their sum // * // * @return // */ // public boolean isDrawValuesForWholeStackEnabled() { // return mDrawValuesForWholeStack; // } /** * If set to true, a grey area is drawn behind each bar that indicates the maximum value. Enabling his will reduce * performance by about 50%. * * @param enabled */ public void setDrawBarShadow(boolean enabled) { mDrawBarShadow = enabled; } /** * returns true if drawing shadows (maxvalue) for each bar is enabled, false if not * * @return */ public boolean isDrawBarShadowEnabled() { return mDrawBarShadow; } @Override public BarData getBarData() { return mData; } /** * Returns the lowest x-index (value on the x-axis) that is still visible on the chart. * * @return */ @Override public int getLowestVisibleXIndex() { float step = mData.getDataSetCount(); float div = (step <= 1) ? 1 : step + mData.getGroupSpace(); float[] pts = new float[]{mViewPortHandler.contentLeft(), mViewPortHandler.contentBottom()}; getTransformer(AxisDependency.LEFT).pixelsToValue(pts); return (int) ((pts[0] <= getXChartMin()) ? 0 : (pts[0] / div) + 1); } /** * Returns the highest x-index (value on the x-axis) that is still visible on the chart. * * @return */ @Override public int getHighestVisibleXIndex() { float step = mData.getDataSetCount(); float div = (step <= 1) ? 1 : step + mData.getGroupSpace(); float[] pts = new float[]{mViewPortHandler.contentRight(), mViewPortHandler.contentBottom()}; getTransformer(AxisDependency.LEFT).pixelsToValue(pts); return (int) ((pts[0] >= getXChartMax()) ? getXChartMax() / div : (pts[0] / div)); } }