/* * Copyright 2014 Diogo Bernardino * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.db.chart.view; import android.content.Context; import android.util.AttributeSet; import com.db.chart.model.Bar; import com.db.chart.model.BarSet; import com.db.chart.model.ChartSet; import java.util.ArrayList; /** * Implements a bar chart extending {@link com.db.chart.view.BaseStackBarChartView} */ public abstract class BaseStackBarChartView extends BaseBarChartView { /** * Whether to calculate max value or not */ protected boolean mCalcMaxValue; public BaseStackBarChartView(Context context, AttributeSet attrs) { super(context, attrs); mCalcMaxValue = true; } public BaseStackBarChartView(Context context) { super(context); mCalcMaxValue = true; } /** * Calculates Bar width based on the distance of two horizontal labels. * * @param nSets Number of sets (not really necessary for stack bars) * @param x0 Coordinate(n) * @param x1 Coordinate(n+1) */ @Override protected void calculateBarsWidth(int nSets, float x0, float x1) { barWidth = x1 - x0 - style.barSpacing; } /** * Finds the set that will stay in the bottom of the bar. * * @param entryIndex Entry index * @param data {@link java.util.ArrayList} of {@link com.db.chart.model.ChartSet} * to use while drawing the Chart * @return The bottom set index */ protected static int discoverBottomSet(int entryIndex, ArrayList<ChartSet> data) { int dataSize = data.size(); int index; boolean hasNegativeValues = false; for (index = 0; index < dataSize; index++) { if (data.get(index).getEntry(entryIndex).getValue() < 0) { hasNegativeValues = true; break; } } if (hasNegativeValues) { // Find last value < 0 for (index = dataSize - 1; index >= 0; index--) { if (data.get(index).getEntry(entryIndex).getValue() < 0) break; } } else { // Find first non null value for (index = 0; index < dataSize; index++) { if (data.get(index).getEntry(entryIndex).getValue() != 0) break; } } return index; } /** * Finds the set that will be on top. * * @param entryIndex Entry index * @param data {@link java.util.ArrayList} of {@link com.db.chart.model.ChartSet} * to use while drawing the Chart * @return The top set index */ protected static int discoverTopSet(int entryIndex, ArrayList<ChartSet> data) { int dataSize = data.size(); int index; boolean hasPositiveValues = false; for (index = 0; index < dataSize; index++) { if (data.get(index).getEntry(entryIndex).getValue() > 0) { hasPositiveValues = true; break; } } if (hasPositiveValues) { // Find last value > 0 for (index = dataSize - 1; index >= 0; index--) if (data.get(index).getEntry(entryIndex).getValue() > 0) break; } else { // Find first non null value for (index = 0; index < dataSize; index++) { if (data.get(index).getEntry(entryIndex).getValue() != 0) break; } } return index; } /** * This method will calculate what needs to be the max axis value that fits all the sets * aggregated, one on top of the other. */ protected void calculateMaxStackBarValue() { float positiveStackValue; float negativeStackValue; BarSet barSet; Bar bar; int maxStackValue = 0; int minStackValue = 0; int dataSize = data.size(); int setSize = data.get(0).size(); for (int i = 0; i < setSize; i++) { positiveStackValue = 0; negativeStackValue = 0; for (int j = 0; j < dataSize; j++) { barSet = (BarSet) data.get(j); bar = (Bar) barSet.getEntry(i); if (bar.getValue() >= 0) positiveStackValue += bar.getValue(); else negativeStackValue += bar.getValue(); } if (maxStackValue < (int) Math.ceil(positiveStackValue)) maxStackValue = (int) Math.ceil(positiveStackValue); if (minStackValue > (int) Math.ceil(negativeStackValue)) minStackValue = (int) Math.ceil(negativeStackValue); } while (maxStackValue % this.getStep() != 0) maxStackValue += 1; while (minStackValue % this.getStep() != 0) minStackValue -= 1; super.setAxisBorderValues(minStackValue, maxStackValue, this.getStep()); } /* * -------------------------------- * Overriden methods from ChartView * -------------------------------- */ @Override public ChartView setAxisBorderValues(int minValue, int maxValue, int step) { mCalcMaxValue = false; return super.setAxisBorderValues(minValue, maxValue, step); } @Override public void show() { if (mCalcMaxValue) calculateMaxStackBarValue(); super.show(); } }