Hi Grant and all,
I think I finally resolved the issue on calculating the Y Scale on BarChart Charts.
What I did is modify the updateChartModelData method code in order to introduce a method to calculate Scale in order to BarChart renders properly with big Y values.
I tested and I'm using this code.
I posted here because I think it could help others.
Here is the code changes I made in BarChartProvider class:
Code:
public void updateChartModelData(List<M> models) {
Integer maxValue=this.getMaxYValue(models);
Scale scale=this.calculateBaseScale(maxValue);
bc.getValues().clear();
chartData.getXAxis().setXAxisLabels(null);
chartData.getYAxis().setMax(scale.getBase().intValue());
chartData.getYAxis().setMin(0);
chartData.getYAxis().setSteps(scale.getInterval().intValue());
for (M m : models) {
if (modelXLabel != null) chartData.getXAxis().addLabels((String)m.get(modelXLabel));
Object v = m.get(modelYValue);
if (v instanceof String) {
bc.addValues(new Double((String)v));
}
else {
bc.addValues((Number)v);
}
}
}
protected Scale calculateBaseScale(Integer maxValue){
double result=0;
double interval=0;
int divideCount=0;
Double base=0.0;
int intBase;
boolean found=false;
result=maxValue;
if(result>1000){
while(!found){
result=result / 1000;
divideCount++;
if(result<1000){
found=true;
}
}
}
if(result<1000 && result>=500){
interval=100;
}
if(result<500 && result>=200){
interval=50;
}
if(result<200 && result>=100){
interval=20;
}
if(result<100 && result>=50){
interval=10;
}
if(result<50 && result>=20){
interval=5;
}
if(result<20 && result>=10){
interval=2;
}
if(result<10 && result>=5){
interval=1;
}
if(result<5 && result>=2){
interval=0.5;
}
if(result<2 && result>=1){
interval=0.2;
}
base=result/interval;
intBase=base.intValue();
base=intBase*interval;
for(int i=0; i<divideCount;i++){
base=base*1000;
interval=interval*1000;
}
base=base+interval;
Scale scale=new Scale(base, interval);
return scale;
}
protected Integer getMaxYValue(List<M> models){
Double maxValue=0.0;
Double currentValue;
for(M m : models){
Object v = m.get(modelYValue);
if (v instanceof String) {
currentValue=new Double((String)v);
}else {
currentValue=(Double)v;
}
if(currentValue>maxValue)
maxValue=currentValue;
}
return maxValue.intValue();
}
/**
* Gets the model y value.
*
* @return the model y value
*/
public String getModelYValue() {
return modelYValue;
}
/**
* Sets the model y value.
*
* @param value the new model y value
*/
public void setModelYValue(String value) {
this.modelYValue = value;
}
/**
* Gets the model x label.
*
* @return the model x label
*/
public String getModelXLabel() {
return modelXLabel;
}
/**
* Sets the model x label.
*
* @param modelXLabel the new model x label
*/
public void setModelXLabel(String modelXLabel) {
this.modelXLabel = modelXLabel;
}
/**
* Gets the bar chart.
*
* @return the bar chart
*/
public BarChart getBarChart() {
return bc;
}
/**
* Sets the bar chart.
*
* @param bc the new bar chart
*/
public void setBarChart(BarChart bc) {
this.bc = bc;
}
protected class Scale{
private Double base;
private Double interval;
protected Scale(Double base, Double interval){
this.interval=interval;
this.base=base;
}
protected Double getBase(){
return base;
}
protected Double getInterval(){
return interval;
}
}
The changes are:
Method to calculate the Max Value from a List of Models : getMaxYValue(models).
The Private Scale class to hold base and interval values
Method to calculate the Scale giving maxValue : calculateBaseScale(maxValue).
Please feel free to use this code.
Regards.
Daniel