/*
* 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.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Region;
import android.util.AttributeSet;
import android.util.Log;
import com.db.chart.model.Bar;
import com.db.chart.model.BarSet;
import com.db.chart.model.ChartSet;
import com.db.williamchart.R;
import java.util.ArrayList;
/**
* Implements a {@link com.db.chart.view.HorizontalBarChartView} extending {@link com.db.chart.view.ChartView}
*/
public class HorizontalBarChartView extends BaseBarChartView {
public HorizontalBarChartView(Context context, AttributeSet attrs) {
super(context, attrs);
setOrientation(Orientation.HORIZONTAL);
setMandatoryBorderSpacing();
}
public HorizontalBarChartView(Context context) {
super(context);
setOrientation(Orientation.HORIZONTAL);
setMandatoryBorderSpacing();
}
/**
* Method responsible to draw bars with the parsed screen points.
*
* @param canvas The canvas to draw on
* @param data {@link java.util.ArrayList} of {@link com.db.chart.model.ChartSet}
* to use while drawing the Chart
*/
@Override
public void onDrawChart(Canvas canvas, ArrayList<ChartSet> data) {
final int nSets = data.size();
final int nEntries = data.get(0).size();
final int yZeroCoord = (int) this.getZeroPosition();
float offset;
BarSet barSet;
Bar bar;
for (int i = nEntries - 1; i >= 0; i--) {
// Set first offset to draw a group of bars
offset = data.get(0).getEntry(i).getY() - drawingOffset;
for(int j = 0; j < nSets; j++){
barSet = (BarSet) data.get(j);
bar = (Bar) barSet.getEntry(i);
// If entry value is 0 it won't be drawn
if(!barSet.isVisible() || bar.getValue() == 0)
continue;
style.barPaint.setColor(bar.getColor());
style.applyAlpha(style.barPaint, barSet.getAlpha());
// If bar needs background
if(style.hasBarBackground)
drawBarBackground(canvas,
this.getInnerChartLeft(), offset,
this.getInnerChartRight(), (offset + barWidth));
// Draw bar
if(bar.getValue() > 0)
// Draw positive bar
drawBar(canvas,
yZeroCoord, offset,
bar.getX(), offset + barWidth);
else
// Draw negative bar
drawBar(canvas,
bar.getX(), offset,
yZeroCoord, offset + barWidth);
offset += barWidth;
// If last bar of group no set spacing is necessary
if(j != nSets - 1)
offset += style.setSpacing;
}
}
}
/**
* (Optional) To be overriden in case the view needs to execute some code before
* starting the drawing.
*
* @param data Array of {@link ChartSet} to do the necessary preparation just before onDraw
*/
@Override
protected void onPreDrawChart(ArrayList<ChartSet> data){
// In case of only on entry
if(data.get(0).size() == 1){
style.barSpacing = 0;
calculateBarsWidth(data.size(), 0, this.getInnerChartBottom()
- this.getInnerChartTop()
- super.verController.borderSpacing * 2);
// In case of more than one entry
}else
calculateBarsWidth(data.size(), data.get(0).getEntry(1).getY(),
data.get(0).getEntry(0).getY());
calculatePositionOffset(data.size());
}
/**
* (Optional) To be overridden in order for each chart to define its own clickable regions.
* This way, classes extending ChartView will only define their clickable regions.
*
* Important: the returned vector must match the order of the data passed
* by the user. This ensures that onTouchEvent will return the correct index.
*
* @param data {@link java.util.ArrayList} of {@link com.db.chart.model.ChartSet} to use
* while defining each region of a {@link com.db.chart.view.HorizontalBarChartView}
* @return {@link java.util.ArrayList} of {@link android.graphics.Region} with regions
* where click will be detected
*/
@Override
public ArrayList<ArrayList<Region>> defineRegions(ArrayList<ChartSet> data) {
int nSets = data.size();
int nEntries = data.get(0).size();
int yZeroCoord = (int) this.getZeroPosition();
final ArrayList<ArrayList<Region>> result = new ArrayList<ArrayList<Region>>(nSets);
for(int i = 0; i < nSets; i++)
result.add(new ArrayList<Region>(nEntries));
float offset;
BarSet barSet;
Bar bar;
for (int i = nEntries - 1; i >= 0; i--) {
// Set first offset to draw a group of bars
offset = data.get(0).getEntry(i).getY() - drawingOffset;
for(int j = 0; j < nSets; j++){
barSet = (BarSet) data.get(j);
bar = (Bar) barSet.getEntry(i);
if(bar.getValue() > 0)
result.get(j).add(new Region(
yZeroCoord,
(int) offset,
(int) bar.getX(),
(int) (offset + barWidth)));
else
result.get(j).add(new Region(
(int) bar.getX(),
(int) offset,
yZeroCoord,
(int) (offset + barWidth)));
// If last bar of group no set spacing is necessary
if(j != nSets - 1)
offset += style.setSpacing;
}
}
return result;
}
}