Skip to content

Commit

Permalink
FIX #55
Browse files Browse the repository at this point in the history
  • Loading branch information
stockiNail committed May 16, 2020
1 parent de56774 commit e258005
Show file tree
Hide file tree
Showing 12 changed files with 263 additions and 89 deletions.
11 changes: 10 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,18 @@ Going to next release

Here you can find the list of enhancements and updates available on `master` branch before which will be part of new official release:

### Breaking changes

* change `FormatterCallback` interface for `DataLabelsPlugin` enabling the formatting different kind of values of datasets which can be doubles, strings (for lining datasets) and arrays of doubles (for floating bars datasets).
* change `RenderItem` object for `LabelsPlugin` managing different kinds of values of datasets which can be doubles, strings (for lining datasets) and arrays of doubles (for floating bars datasets).

### Features

* implement **floating-bars** for BAR datasets.
* implement **floating-bars** for BAR datasets. Thanks @rr22x.

### Fixed Bugs

* [#55](https://github.com/pepstock-org/Charba/issues/55) implement **floating-bars** for BAR datasets. Thanks @rr22x.

License
-------
Expand Down
24 changes: 13 additions & 11 deletions src/org/pepstock/charba/client/data/BarDataset.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ public class BarDataset extends HovingFlexDataset implements HasDataPoints, HasO
// default label
private static final String DEFAULT_LABEL = Constants.EMPTY_STRING;

/**
* Floating bars data factory to create {@link FloatingData}s.
*/
public static final FloatingDatatFactory FLOATING_BAR_DATA_FACTORY = new FloatingDatatFactory();

/**
* If set to 'flex', the base sample widths are calculated automatically based on the previous and following samples so that they take the full available widths without
* overlap. Then, bars are sized using barPercentage and categoryPercentage. There is no gap when the percentage options are 1. This mode generates bars with different widths
Expand All @@ -65,9 +70,6 @@ public class BarDataset extends HovingFlexDataset implements HasDataPoints, HasO
private static final int DEFAULT_MAX_BAR_THICKNESS = 0;

private static final int DEFAULT_MIN_BAR_LENGTH = 0;

// floating data factory
private static final FloatingDatatFactory FLOATING_DATA_FACTORY = new FloatingDatatFactory();

// ---------------------------
// -- CALLBACKS PROXIES ---
Expand Down Expand Up @@ -412,11 +414,11 @@ public BorderSkipped getBorderSkipped() {
// otherwise returns the enum value as string
return getValue(Property.BORDER_SKIPPED, BorderSkipped.values(), getDefaultValues().getElements().getRectangle().getBorderSkipped());
}

/**
* Returns the data property of a dataset for a chart is specified as an array of floating data.
*
* @return a list of floating data or an empty list if the data type is not {@link DataType#FLOATING}.
* @return a list of floating data or an empty list if the data type is not {@link DataType#ARRAYS}.
*/
public List<FloatingData> getFloatingData() {
return getFloatingData(false);
Expand All @@ -426,23 +428,23 @@ public List<FloatingData> getFloatingData() {
* Returns the data property of a dataset for a chart is specified as an array of floating data.
*
* @param binding if <code>true</code> binds the new array list into container
* @return a list of floating data or an empty list if the data type is not {@link DataType#FLOATING}.
* @return a list of floating data or an empty list if the data type is not {@link DataType#ARRAYS}.
*/
public List<FloatingData> getFloatingData(boolean binding) {
// checks if is a floating data type
if (has(InternalProperty.DATA) && DataType.FLOATING.equals(getDataType())) {
if (has(InternalProperty.DATA) && DataType.ARRAYS.equals(getDataType())) {
// gets array
ArrayDoubleArray array = getArrayValue(InternalProperty.DATA);
// returns floating data
return ArrayListHelper.list(array, FLOATING_DATA_FACTORY);
return ArrayListHelper.list(array, FLOATING_BAR_DATA_FACTORY);
}
// checks if wants to bind the array
if (binding) {
ArrayDoubleArrayList<FloatingData> result = new ArrayDoubleArrayList<>();
// set value
setArrayValue(InternalProperty.DATA, ArrayDoubleArray.fromOrEmpty(result));
// sets data type
setValue(InternalProperty.CHARBA_DATA_TYPE, DataType.FLOATING);
setValue(InternalProperty.CHARBA_DATA_TYPE, DataType.ARRAYS);
// returns list
return result;
}
Expand All @@ -458,7 +460,7 @@ public List<FloatingData> getFloatingData(boolean binding) {
public void setFloatingData(FloatingData... floatingData) {
setArrayValue(InternalProperty.DATA, ArrayDoubleArray.fromOrNull(floatingData));
// sets data type checking if the key exists
setValue(InternalProperty.CHARBA_DATA_TYPE, has(InternalProperty.DATA) ? DataType.FLOATING : DataType.UNKNOWN);
setValue(InternalProperty.CHARBA_DATA_TYPE, has(InternalProperty.DATA) ? DataType.ARRAYS : DataType.UNKNOWN);
}

/**
Expand All @@ -469,7 +471,7 @@ public void setFloatingData(FloatingData... floatingData) {
public void setFloatingData(List<FloatingData> floatingData) {
setArrayValue(InternalProperty.DATA, ArrayDoubleArray.fromOrNull(floatingData));
// sets data type checking if the key exists
setValue(InternalProperty.CHARBA_DATA_TYPE, has(InternalProperty.DATA) ? DataType.FLOATING : DataType.UNKNOWN);
setValue(InternalProperty.CHARBA_DATA_TYPE, has(InternalProperty.DATA) ? DataType.ARRAYS : DataType.UNKNOWN);
}

/**
Expand Down
41 changes: 41 additions & 0 deletions src/org/pepstock/charba/client/data/FloatingData.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public FloatingData(double start, double end) {

/**
* Returns the start point of a bar.
*
* @return the start point of a bar
*/
public double getStart() {
Expand All @@ -64,6 +65,7 @@ public double getStart() {

/**
* Returns the end point of a bar.
*
* @return the end point of a bar
*/
public double getEnd() {
Expand All @@ -82,4 +84,43 @@ public void setValues(double start, double end) {
// adds new items
super.push(start, end);
}

/**
* Returns the value which is calculating subtracting the start point from end point.
*
* @return the value which is calculating subtracting the start point from end point
*/
public double getValue() {
// gets values from array
double start = getStart();
double end = getEnd();
// checks if the values are consistent
if (Double.isNaN(start) || Double.isNaN(end)) {
// if not consistent, returns 0
return 0D;
}
// if here the array is consistent then
// returns the end minus start
return end - start;
}

/**
* Returns the absolute value which is calculating subtracting the start point from end point.
*
* @return the absolute value which is calculating subtracting the start point from end point
*/
public double getAbsValue() {
return Math.abs(getValue());
}

/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "[" + getStart() + "," + getEnd() + "]";
}

}
15 changes: 13 additions & 2 deletions src/org/pepstock/charba/client/data/FloatingDatatFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
import org.pepstock.charba.client.commons.NativeArrayContainerFactory;

/**
* Factory to create a floating data from a native array, used for array container lists.
* Factory to create a floating data from a native array, used for array container lists.<br>
* The array must contain and only 2 values.
*
* @author Andrea "Stock" Stocchero
*/
Expand All @@ -32,7 +33,17 @@ public final class FloatingDatatFactory implements NativeArrayContainerFactory<A
*/
@Override
public FloatingData create(ArrayDouble nativeArray) {
return new FloatingData(nativeArray);
// checks consistency of array
if (nativeArray != null) {
// the array must contains and only 2 values
if (nativeArray.length() == 2) {
return new FloatingData(nativeArray);
}
// exception
throw new IllegalArgumentException("The array contains " + nativeArray.length() + " instead of 2");
}
// exception
throw new IllegalArgumentException("The array is not consistent");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import org.pepstock.charba.client.datalabels.enums.TextAlign;
import org.pepstock.charba.client.datalabels.events.AbstractEventHandler;
import org.pepstock.charba.client.enums.Display;
import org.pepstock.charba.client.items.DataItem;
import org.pepstock.charba.client.plugins.AbstractPluginCachedOptions;

import jsinterop.annotations.JsFunction;
Expand Down Expand Up @@ -170,7 +171,7 @@ interface ProxyFormatterCallback {
* @param context native object as context.
* @return string with formatted value.
*/
String call(CallbackFunctionContext contextFunction, double value, NativeObject context);
String call(CallbackFunctionContext contextFunction, Object value, NativeObject context);
}

// ---------------------------
Expand Down Expand Up @@ -1534,13 +1535,13 @@ public void setPadding(PaddingCallback paddingCallback) {
* @param value value to be formatted
* @return a string as formatted value
*/
private String onFormatter(ScriptableContext context, double value) {
private String onFormatter(ScriptableContext context, Object value) {
// gets chart instance
IsChart chart = ScriptableUtils.retrieveChart(context, formatterCallback);
// checks if the handler is set
if (IsChart.isValid(chart)) {
// calls callback
String result = formatterCallback.invoke(chart, value, context);
String result = formatterCallback.invoke(chart, new DataItem(value), context);
// checks result
if (result != null) {
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

import org.pepstock.charba.client.IsChart;
import org.pepstock.charba.client.callbacks.ScriptableContext;
import org.pepstock.charba.client.data.FloatingData;
import org.pepstock.charba.client.datalabels.DataLabelsPlugin;
import org.pepstock.charba.client.items.DataItem;

/**
* Callback interface of {@link DataLabelsPlugin#ID} plugin to set <code>formatter</code> property at runtime, using the chart instance and the plugin context.<br>
Expand All @@ -33,10 +35,10 @@ public interface FormatterCallback {
* Returns the <code>formatter</code> property at runtime, using the chart instance and the plugin context.
*
* @param chart chart instance
* @param value to be formatted
* @param dataItem value container to be formatted, Can be a simple <code>double</code>, {@link String} or a {@link FloatingData}.
* @param context {@link DataLabelsPlugin#ID} plugin context instance
* @return the label value to be showed
*/
String invoke(IsChart chart, double value, ScriptableContext context);
String invoke(IsChart chart, DataItem dataItem, ScriptableContext context);

}
2 changes: 1 addition & 1 deletion src/org/pepstock/charba/client/enums/DataType.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public enum DataType implements Key
* The data property is set as array of floating data.<br>
* Only for <b>BAR</b> datasets.
*/
FLOATING("floating"),
ARRAYS("arrays"),
/**
* The data property is set as array of strings.
*/
Expand Down
8 changes: 4 additions & 4 deletions src/org/pepstock/charba/client/impl/callbacks/Percentage.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,14 @@ private static double getTotalForStacked(IsChart chart, ScriptableContext contex
DataPoint point = hasDataPoints.getDataPoints().get(context.getIndex());
// adds the Y value to the total
total = total + Math.abs(point.getY());
} else if (DataType.FLOATING.equals(ds.getDataType()) && ds instanceof BarDataset) {
} else if (DataType.ARRAYS.equals(ds.getDataType()) && ds instanceof BarDataset) {
// then dataset is floating bar chart
// and then cast it
BarDataset barDataset = (BarDataset) ds;
// gets the floating data
FloatingData data = barDataset.getFloatingData().get(context.getIndex());
// adds the absolute differences between start and end
total = total + Math.abs(data.getEnd() - data.getStart());
total = total + data.getAbsValue();
} else if (DataType.NUMBERS.equals(ds.getDataType())) {
// if here, the dataset has got data as doubles
// then it get the double at data index
Expand Down Expand Up @@ -156,7 +156,7 @@ private static double getTotal(IsChart chart, ScriptableContext context) {
// adds the Y value to the total
total = total + Math.abs(dataPoint.getY());
}
} else if (DataType.FLOATING.equals(ds.getDataType()) && ds instanceof BarDataset) {
} else if (DataType.ARRAYS.equals(ds.getDataType()) && ds instanceof BarDataset) {
// then dataset is floating bar chart
// and then cast it
BarDataset barDataset = (BarDataset) ds;
Expand All @@ -165,7 +165,7 @@ private static double getTotal(IsChart chart, ScriptableContext context) {
// scans data
for (FloatingData dataFloat : data) {
// adds the absolute differences between start and end
total = total + Math.abs(dataFloat.getEnd() - dataFloat.getStart());
total = total + dataFloat.getAbsValue();
}
} else if (DataType.NUMBERS.equals(ds.getDataType())) {
// if here, the dataset has got data as doubles
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import org.pepstock.charba.client.commons.Constants;
import org.pepstock.charba.client.datalabels.DataLabelsPlugin;
import org.pepstock.charba.client.datalabels.callbacks.FormatterCallback;
import org.pepstock.charba.client.enums.DataType;
import org.pepstock.charba.client.items.DataItem;
import org.pepstock.charba.client.utils.Utilities;

/**
Expand Down Expand Up @@ -104,22 +106,30 @@ public boolean isStacked() {
/*
* (non-Javadoc)
*
* @see org.pepstock.charba.client.datalabels.callbacks.FormatterCallback#format(org.pepstock.charba.client.IsChart, double,
* @see org.pepstock.charba.client.datalabels.callbacks.FormatterCallback#invoke(org.pepstock.charba.client.IsChart, org.pepstock.charba.client.items.DataItem,
* org.pepstock.charba.client.callbacks.ScriptableContext)
*/
@Override
public String invoke(IsChart chart, double value, ScriptableContext context) {
// the arguments are checked because
// they will be checked inside percentage compute method
// computes the percentage
double percentage = Percentage.compute(chart, value, context, stacked);
// checks if consistent
if (Double.isNaN(percentage)) {
// if not, returns NaN as string
return NAN_AS_STRING;
public String invoke(IsChart chart, DataItem dataItem, ScriptableContext context) {
// checks if the data type is a possible numbers
if (DataType.NUMBERS.equals(dataItem.getDataType()) || DataType.ARRAYS.equals(dataItem.getDataType())) {
// calculates the value to use for percentage
double value = DataType.ARRAYS.equals(dataItem.getDataType()) ? dataItem.getValueAsFloatingData().getAbsValue() : dataItem.getValue();
// the arguments are not checked because
// they will be checked inside percentage compute method
// computes the percentage
double percentage = Percentage.compute(chart, value, context, stacked);
// checks if consistent
if (Double.isNaN(percentage)) {
// if not, returns NaN as string
return NAN_AS_STRING;
}
// applies the number format to the percentage
return Utilities.applyPrecision(value, precision) + Constants.PERCENT;
}
// applies the number format to the percentage
return Utilities.applyPrecision(value, precision) + Constants.PERCENT;
// if here, the data type of value is not a number
// then returns NaN as string
return NAN_AS_STRING;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ private IsColor[] getColorsFromData(Dataset dataset, List<IsColor> colors, boole
// ONLY datasets which implements the interface have got the data POINTS
HasDataPoints dataPointsDataset = (HasDataPoints) dataset;
amountOfData = dataPointsDataset.getDataPoints().size();
} else if (DataType.FLOATING.equals(type) && dataset instanceof BarDataset) {
} else if (DataType.ARRAYS.equals(type) && dataset instanceof BarDataset) {
// ONLY BAR datasets have got the data FLOATING
BarDataset barDataset = (BarDataset) dataset;
amountOfData = barDataset.getFloatingData().size();
Expand Down
Loading

0 comments on commit e258005

Please sign in to comment.