update highcharts Gwt from version 1.1.3 to 1.3.0

Includes also the checkbox position fix in BaseChart.java
This commit is contained in:
fmittag committed 2012-05-18 17:12:03 +02:00
1 parent d13b15efa1
commit fa583842de
8 files changed
+562 -64

No files matched your search

@@ -2,21 +2,21 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Moxie Apps GWT Highcharts
Bundle-SymbolicName: org.moxieapps.gwt.highcharts
Bundle-Version: 1.1.4.qualifier
Bundle-Version: 1.3.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Export-Package: org.moxieapps.gwt.highcharts.client.plotOptions;uses:="o
rg.moxieapps.gwt.highcharts.client,com.google.gwt.json.client,org.moxie
apps.gwt.highcharts.client.events,org.moxieapps.gwt.highcharts.client.l
abels";version="1.1.3",org.moxieapps.gwt.highcharts;version="1.1.3",org
abels";version="1.3.0",org.moxieapps.gwt.highcharts;version="1.3.0",org
.moxieapps.gwt.highcharts.client;uses:="com.google.gwt.core.client,com.
google.gwt.dom.client,com.google.gwt.json.client,org.moxieapps.gwt.high
charts.client.plotOptions,com.google.gwt.user.client,org.moxieapps.gwt.
highcharts.client.events,org.moxieapps.gwt.highcharts.client.labels,com
.google.gwt.user.client.ui";version="1.1.3",org.moxieapps.gwt.highchart
.google.gwt.user.client.ui";version="1.3.0",org.moxieapps.gwt.highchart
s.client.events;uses:="com.google.gwt.core.client,com.google.gwt.dom.cl
ient,org.moxieapps.gwt.highcharts.client";version="1.1.3",org.moxieapps
ient,org.moxieapps.gwt.highcharts.client";version="1.3.0",org.moxieapps
.gwt.highcharts.client.labels;uses:="com.google.gwt.core.client,org.mox
ieapps.gwt.highcharts.client,com.google.gwt.json.client";version="1.1.3
ieapps.gwt.highcharts.client,com.google.gwt.json.client";version="1.3.0
"
Import-Package: com.google.gwt.core.client,com.google.gwt.dom.client,com
.google.gwt.json.client,com.google.gwt.user.client,com.google.gwt.user.
@@ -16,6 +16,8 @@
package org.moxieapps.gwt.highcharts.client;
import org.moxieapps.gwt.highcharts.client.events.AxisSetExtremesEventHandler;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Document;
import com.google.gwt.json.client.JSONObject;
@@ -46,6 +48,12 @@ public abstract class Axis<T extends Axis> extends Configurable<T> {
*/
LINEAR("linear"),
/**
* Scale the axis tick values logarithmically instead of linearly.
* @since 1.2.0
*/
LOGARITHMIC("logarithmic"),
/**
* In a datetime axis, the numbers are given in milliseconds, and tick
* marks are placed on appropriate values like full hours or days.
@@ -125,6 +133,8 @@ public abstract class Axis<T extends Axis> extends Configurable<T> {
// come into the axis after it is rendered
private String id;
private AxisSetExtremesEventHandler axisSetExtremesEventHandler;
/**
* Use the {@link Chart#getXAxis()} or {@link Chart#getYAxis()} methods to get access
* to the axis instances on the chart.
@@ -137,6 +147,36 @@ public abstract class Axis<T extends Axis> extends Configurable<T> {
setOption("id", id);
}
/**
* Set a callback handler that will be invoked whenever the minimum and maximum is set for the axis, either by calling the
* {@link #setExtremes(Number, Number)} method or by selecting an area in the chart.
*
* Additional information about the new extremes value (such as the new minimum and maximum) can be
* found via the {@link org.moxieapps.gwt.highcharts.client.events.AxisSetExtremesEvent} instance
* that is passed to the handler's {@link org.moxieapps.gwt.highcharts.client.events.AxisSetExtremesEventHandler#onSetExtremes(org.moxieapps.gwt.highcharts.client.events.AxisSetExtremesEvent)} method.
*
* @param axisSetExtremesEventHandler The handler that should be invoked whenever a set extremes event occurs.
* @return A reference to this {@link Axis} instance for convenient method chaining.
*
* @since 1.3.0
*/
public T setAxisSetExtremesEventHandler(AxisSetExtremesEventHandler axisSetExtremesEventHandler) {
this.axisSetExtremesEventHandler = axisSetExtremesEventHandler;
return getThis();
}
/**
* Returns the custom event handler that has been set on the axis, or null if no event
* handler has been set.
*
* @return The custom event handler that has been applied, or null if it has not been set.
*
* @since 1.3.0
*/
public AxisSetExtremesEventHandler getAxisSetExtremesEventHandler() {
return this.axisSetExtremesEventHandler;
}
/**
* Create a new plot line that can be configured, and then added to this axis instance via the
* {@link #setPlotLines(PlotLine...)} method.
@@ -302,10 +342,10 @@ public abstract class Axis<T extends Axis> extends Configurable<T> {
if (nativeAxis != null) {
if (animation == null || animation.getOptions() == null) {
final boolean animationFlag = animation != null;
nativeSetExtremes(nativeAxis, min, max, redraw, animationFlag);
nativeSetExtremes(nativeAxis, min.doubleValue(), max.doubleValue(), redraw, animationFlag);
} else {
final JavaScriptObject animationOptions = animation.getOptions().getJavaScriptObject();
nativeSetExtremes(nativeAxis, min, max, redraw, animationOptions);
nativeSetExtremes(nativeAxis, min.doubleValue(), max.doubleValue(), redraw, animationOptions);
}
}
} else {
@@ -354,6 +394,10 @@ public abstract class Axis<T extends Axis> extends Configurable<T> {
return chart.get(this.id);
}
/* package */ String getId() {
return this.id;
}
// Save some typing in the getExtremes() method
private Number getNumberFromJSONObject(JSONObject jsonObject, String key) {
JSONValue jsonValue = jsonObject.get(key);
@@ -513,7 +557,7 @@ public abstract class Axis<T extends Axis> extends Configurable<T> {
private Number min;
/**
* Convenience method for setting the 'max' option for the axis. Equivalent to:
* Convenience method for setting the 'min' option for the axis. Equivalent to:
* <pre><code>
* axis.setOption("min", 10);
* </code></pre>
@@ -525,7 +569,7 @@ public abstract class Axis<T extends Axis> extends Configurable<T> {
* To change the min/max value of the chart after render time use the {@link #setExtremes(Number, Number)}
* method instead.
*
* @param min The maximum value of the axis, or null to automatically calculate the maximum.
* @param min The minimum value of the axis, or null to automatically calculate the minimum.
* @return A reference to this {@link Axis} instance for convenient method chaining.
*/
public T setMin(Number min) {
@@ -925,10 +969,16 @@ public abstract class Axis<T extends Axis> extends Configurable<T> {
}
/**
* Convenience method for setting the 'title/text' axis option. Equivalent to:
* Convenience method for setting the 'title/text' axis option, before or after
* the chart is rendered. Before the chart is rendered this is equivalent to:
* <pre><code>
* axis.setOption("/title/text", "A Fine Axis Indeed");
* </code></pre>
* After the chart is rendered this is equivalent to a direct JS call like
* <pre><code>
* Axis.setTitle({text: "A Fine Axis Indeed"});
* </code></pre>
*
* The actual text of the axis title. It can contain basic HTML text markup like
* &lt;b&gt;, &lt;i&gt; and spans with style. Defaults to null for the x-axis
* and "Y-values" for the y-axis.
@@ -942,15 +992,56 @@ public abstract class Axis<T extends Axis> extends Configurable<T> {
* @return A reference to this {@link Axis} instance for convenient method chaining.
*/
public T setAxisTitleText(String title) {
return this.setOption("/title/text", title);
return this.setAxisTitleText(title, true);
}
/**
* Convenience method for setting the 'title/text' axis option. Equivalent to:
* Convenience method for setting the 'title/text' axis option, before or after
* the chart is rendered (explicitly controlling whether or not the new title will
* be immediately drawn in the case of being called after the chart is rendered).
* Before the chart is rendered this is equivalent to:
* <pre><code>
* axis.setOption("/title/text", "A Fine Axis Indeed");
* </code></pre>
* After the chart is rendered this is equivalent to a JS call like:
* <pre><code>
* Axis.setTitle({text: "A Fine Axis Indeed"}, true);
* </code></pre>
*
* The actual text of the axis title. It can contain basic HTML text markup like
* &lt;b&gt;, &lt;i&gt; and spans with style. Defaults to null for the x-axis
* and "Y-values" for the y-axis.
* <p/>
* Note that for more control over the title, utilize the {@link #setAxisTitle(AxisTitle)}
* method instead.
* <p/>
* Also note that to hide an axis title completely, simply set the text to null.
*
* @param title Sets the title of axis, or null to hide the title.
* @param redraw Whether to redraw the chart now or hold until the next {@link org.moxieapps.gwt.highcharts.client.BaseChart#redraw()}
* @return A reference to this {@link Axis} instance for convenient method chaining.
* @since 1.2.0
*/
public T setAxisTitleText(String title, boolean redraw) {
if(getNativeAxis() != null) {
this.setAxisTitle(new AxisTitle().setText(title), redraw);
} else {
this.setOption("/title/text", title);
}
return getThis();
}
/**
* Convenience method for setting the 'title/text' axis option, before or after
* the chart is rendered. Before the chart is rendered this is equivalent to:
* <pre><code>
* axis.setOption("/title/text", "A Fine Axis Indeed");
* axis.setOption("/title/align", AxisTitle.Align.HIGH);
* </code></pre>
* After the chart is rendered this is equivalent to a JS call like:
* <pre><code>
* Axis.setTitle({text: "A Fine Axis Indeed", align: "high"});
* </code></pre>
* <p/>
* Note that if you call this method it will overwrite any existing
* settings that have already been applied to the title (e.g. if you
@@ -964,6 +1055,40 @@ public abstract class Axis<T extends Axis> extends Configurable<T> {
* @return A reference to this {@link Axis} instance for convenient method chaining.
*/
public T setAxisTitle(AxisTitle title) {
return this.setAxisTitle(title, true);
}
/**
* Convenience method for setting the 'title/text' axis option, before or after
* the chart is rendered (explicitly controlling whether or not the new title will
* be immediately drawn in the case of being called after the chart is rendered).
* Before the chart is rendered this is equivalent to:
* <pre><code>
* axis.setOption("/title/text", "A Fine Axis Indeed");
* axis.setOption("/title/align", AxisTitle.Align.HIGH);
* </code></pre>
* After the chart is rendered this is equivalent to a JS call like:
* <pre><code>
* Axis.setTitle({text: "A Fine Axis Indeed", align: "high"});
* </code></pre>
* <p/>
* Note that if you call this method it will overwrite any existing
* settings that have already been applied to the title (e.g. if you
* had previously called the {@link #setAxisTitleText(String)} method that change
* will get overwritten by this call.)
* <p/>
* Note that if you only want to change the text of the axis, you can simply
* use the {@link #setAxisTitleText(String)} method instead.
*
* @param title Sets the axis title options, or null to hide the title.
* @param redraw Whether to redraw the chart now or hold until the next {@link org.moxieapps.gwt.highcharts.client.BaseChart#redraw()}
* @return A reference to this {@link Axis} instance for convenient method chaining.
* @since 1.2.0
*/
public T setAxisTitle(AxisTitle title, boolean redraw) {
if(getNativeAxis() != null) {
nativeSetTitle(getNativeAxis(), title != null ? title.getOptions().getJavaScriptObject() : null, redraw);
}
return this.setOption("/title", title != null ? title.getOptions() : null);
}
@@ -1065,11 +1190,11 @@ public abstract class Axis<T extends Axis> extends Configurable<T> {
return instance;
}
private static native void nativeSetExtremes(JavaScriptObject axis, Number min, Number max, boolean redraw, boolean animation) /*-{
private static native void nativeSetExtremes(JavaScriptObject axis, double min, double max, boolean redraw, boolean animation) /*-{
axis.setExtremes(min, max, redraw, animation);
}-*/;
private static native void nativeSetExtremes(JavaScriptObject axis, Number min, Number max, boolean redraw, JavaScriptObject animationOptions) /*-{
private static native void nativeSetExtremes(JavaScriptObject axis, double min, double max, boolean redraw, JavaScriptObject animationOptions) /*-{
axis.setExtremes(min, max, redraw, animationOptions);
}-*/;
@@ -1092,4 +1217,8 @@ public abstract class Axis<T extends Axis> extends Configurable<T> {
private native void nativeRemovePlotBand(JavaScriptObject axis, String id)/*-{
axis.removePlotBand(id);
}-*/;
private native void nativeSetTitle(JavaScriptObject axis, JavaScriptObject titleOptions, boolean redraw)/*-{
axis.setTitle(titleOptions, redraw);
}-*/;
}
@@ -26,6 +26,7 @@ import com.google.gwt.user.client.ui.Widget;
import org.moxieapps.gwt.highcharts.client.events.*;
import org.moxieapps.gwt.highcharts.client.labels.AxisLabelsData;
import org.moxieapps.gwt.highcharts.client.labels.DataLabelsData;
import org.moxieapps.gwt.highcharts.client.labels.LegendLabelsData;
import org.moxieapps.gwt.highcharts.client.labels.StackLabelsData;
import org.moxieapps.gwt.highcharts.client.plotOptions.*;
@@ -485,6 +486,9 @@ public abstract class BaseChart<T> extends Widget {
return this.setOption("/labels/style", style != null ? style.getOptions() : null);
}
// We need to maintain a local reference to legend to deal with the formatter function
private Legend legend;
/**
* Convenience method for setting the 'legend' options of the chart. Equivalent to:
* <pre><code>
@@ -498,6 +502,7 @@ public abstract class BaseChart<T> extends Widget {
* @return A reference to this {@link BaseChart} instance for convenient method chaining.
*/
public T setLegend(Legend legend) {
this.legend = legend;
return this.setOption("/legend", legend != null ? legend.getOptions() : null);
}
@@ -1415,8 +1420,8 @@ public abstract class BaseChart<T> extends Widget {
* @param persistent 'true' to retain the data associated with the points in the series in the chart locally
* within a GWT managed Java array (as well as within the DOM via the core Highcharts JS library).
* Defaults to 'false' for memory savings.
* @since 1.2.0
* @return A reference to this {@link BaseChart} instance for convenient method chaining.
* @since 1.2.0
*/
public T setPersistent(boolean persistent) {
this.persistent = persistent;
@@ -1772,6 +1777,30 @@ public abstract class BaseChart<T> extends Widget {
return yAxes.get(axisIndex);
}
/**
* Get a axis by id
* @param axisId the id of the Axis
* @return the Axis instance, may be XAxis or YAxis, null if not found
*/
private Axis<?> getAxis(String axisId) {
if (axisId == null) {
return null;
}
for (XAxis xAxis : xAxes) {
if (axisId.equals(xAxis.getId())) {
return xAxis;
}
}
for (YAxis yAxis : yAxes) {
if (axisId.equals(yAxis.getId())) {
return yAxis;
}
}
return null;
}
/**
* Redraw the chart after changes have been done to the data or axis extremes. All methods for
* updating axes, series or points have a parameter for redrawing the chart. This is true by default.
@@ -1808,18 +1837,28 @@ public abstract class BaseChart<T> extends Widget {
protected void onLoad() {
// Build some arrays that we can pass into the JS function so that it knows how many custom callback functions it needs to wire
// up on the client side for formatter functions.
// up on the client side for formatter functions and event handlers.
JSONArray xAxisLabelFormatters = new JSONArray();
JSONArray xAxisEventHandlers = new JSONArray();
for (int i = 0, xAxesSize = xAxes.size(); i < xAxesSize; i++) {
XAxis xAxis = xAxes.get(i);
xAxisLabelFormatters.set(i, JSONBoolean.getInstance(xAxis.getLabels() != null && xAxis.getLabels().getFormatter() != null));
JSONObject axisEventHandlers = new JSONObject();
axisEventHandlers.put("setExtremes", JSONBoolean.getInstance(xAxis.getAxisSetExtremesEventHandler() != null));
xAxisEventHandlers.set(i, axisEventHandlers);
}
JSONArray yAxisLabelFormatters = new JSONArray();
JSONArray yAxisStackLabelFormatters = new JSONArray();
JSONArray yAxisEventHandlers = new JSONArray();
for (int i = 0, yAxesSize = yAxes.size(); i < yAxesSize; i++) {
YAxis yAxis = yAxes.get(i);
yAxisLabelFormatters.set(i, JSONBoolean.getInstance(yAxis.getLabels() != null && yAxis.getLabels().getFormatter() != null));
yAxisStackLabelFormatters.set(i, JSONBoolean.getInstance(yAxis.getStackLabels() != null && yAxis.getStackLabels().getFormatter() != null));
JSONObject axisEventHandlers = new JSONObject();
axisEventHandlers.put("setExtremes", JSONBoolean.getInstance(yAxis.getAxisSetExtremesEventHandler() != null));
yAxisEventHandlers.set(i, axisEventHandlers);
}
// Build a similar object for dealing with all of the data label formatters that may be set on the plot options
@@ -1912,9 +1951,12 @@ public abstract class BaseChart<T> extends Widget {
getChartTypeName(),
createNativeOptions(),
toolTip != null && toolTip.getToolTipFormatter() != null,
legend != null && legend.getLabelsFormatter() != null,
chartEventHandlers.getJavaScriptObject(),
seriesEventHandlers.getJavaScriptObject(),
pointEventHandlers.getJavaScriptObject(),
xAxisEventHandlers.getJavaScriptObject(),
yAxisEventHandlers.getJavaScriptObject(),
xAxisLabelFormatters.getJavaScriptObject(),
yAxisLabelFormatters.getJavaScriptObject(),
yAxisStackLabelFormatters.getJavaScriptObject(),
@@ -1932,22 +1974,6 @@ public abstract class BaseChart<T> extends Widget {
}
/**
* Fixing a bug currently in the base Highcharts implementation regarding the placement of the checkbox in the legend.
* Requires the symbol padding (see {@link Legend#setSymbolPadding(Number)}) to be set to <code>20</code>. Invoked
* whenever a series is added / displayed in a rendered chart.<p>
*
* The implementation moves the legend item text 15px to the left, using the space made by setting the symbol
* padding to 20px; the checkbox is moved 18px to the left with the top margin set to 0px.
*/
private static native JavaScriptObject nativeAdjustCheckboxPosition(JavaScriptObject series) /*-{
if (series.legendItem && series.checkbox) {
series.legendItem.translate(-15, 0);
series.checkbox.style.marginLeft = '-18px'
series.checkbox.style.marginTop = '0px'
}
}-*/;
/**
* To be overridden in a sub class to return the JS type name of the chart instance that
* should be created when the chart is rendered. E.g. "Chart", "StockChart", etc.
@@ -2065,7 +2091,7 @@ public abstract class BaseChart<T> extends Widget {
return JSONNull.getInstance();
}
private static void copyPointsToJSONArray(Point[] points, JSONArray jsonArray) {
private void copyPointsToJSONArray(Point[] points, JSONArray jsonArray) {
for (int i = 0, pointsLength = points.length; i < pointsLength; i++) {
final Point point = points[i];
jsonArray.set(i, convertPointToJSON(point));
@@ -2073,14 +2099,20 @@ public abstract class BaseChart<T> extends Widget {
}
// Purposefully package scope so we can get to this method from the Series and Point classes as well
static JSONValue convertPointToJSON(Point point) {
JSONValue convertPointToJSON(Point point) {
JSONObject options = point.getOptions();
if (options != null) {
return addPointScalarValues(point, options);
addPointScalarValues(point, options);
return addPointId(point, options);
} else if(point.hasNativeProperties()) {
options = new JSONObject();
addPointScalarValues(point, options);
addPointId(point, options);
return Point.addPointNativeProperties(point, options);
} else if(isPersistent()) {
options = new JSONObject();
addPointScalarValues(point, options);
return addPointId(point, options);
} else if (point.getX() != null) {
JSONArray jsonArray = new JSONArray();
jsonArray.set(0, new JSONNumber(point.getX().doubleValue()));
@@ -2104,6 +2136,19 @@ public abstract class BaseChart<T> extends Widget {
}
}
// Purposefully package scope
JSONValue addPointId(Point point, JSONObject options) {
if (isPersistent()) {
String id = point.getId();
if(id == null) {
id = Document.get().createUniqueId();
point.setId(id);
}
options.put("id", new JSONString(id));
}
return options;
}
// Purposefully package scope
static JSONValue addPointScalarValues(Point point, JSONObject options) {
if (point.getX() != null) {
@@ -2141,9 +2186,12 @@ public abstract class BaseChart<T> extends Widget {
private native JavaScriptObject nativeRenderChart(String chartTypeName,
JavaScriptObject options,
boolean toolTipFormatterFlag,
boolean legendLabelsFormatterFlag,
JavaScriptObject chartEventHandlerFlags,
JavaScriptObject seriesEventHandlerFlags,
JavaScriptObject pointEventHandlerFlags,
JavaScriptObject xAxisEventHandlerFlags,
JavaScriptObject yAxisEventHandlerFlags,
JavaScriptObject xAxisLabelFormatterFlags,
JavaScriptObject yAxisLabelFormatterFlags,
JavaScriptObject yAxisStackLabelFormatterFlags,
@@ -2190,6 +2238,32 @@ public abstract class BaseChart<T> extends Widget {
}
}
// Add in GWT interceptor callback functions for the various X axis event handlers
for (i = 0; i < xAxisEventHandlerFlags.length; i++) {
if (!xAxisEventHandlerFlags[i]) continue;
var xAxisA = xAxisEventHandlerFlags.length == 1 ? options.xAxis : options.xAxis[i];
xAxisA.events = xAxisA.events || {};
for (var type4 in xAxisEventHandlerFlags[i]) {
xAxisA.events[type4] = function(e) {
return self.@org.moxieapps.gwt.highcharts.client.BaseChart::axisEventCallback(Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;)(this.options.id, e, arguments.callee.type);
};
xAxisA.events[type4].type = type4;
}
}
// Add in GWT interceptor callback functions for the various Y axis event handlers
for (i = 0; i < yAxisEventHandlerFlags.length; i++) {
if (!yAxisEventHandlerFlags[i]) continue;
var yAxisA = yAxisEventHandlerFlags.length == 1 ? options.yAxis : options.yAxis[i];
yAxisA.events = yAxisA.events || {};
for (var type5 in yAxisEventHandlerFlags[i]) {
yAxisA.events[type5] = function(e) {
return self.@org.moxieapps.gwt.highcharts.client.BaseChart::axisEventCallback(Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;)(this.options.id, e, arguments.callee.type);
};
yAxisA.events[type5].type = type5;
}
}
// Add in GWT interceptor callback functions for the various formatters so that we can move from
// the native JS world back to the Java world...
if (toolTipFormatterFlag) {
@@ -2202,47 +2276,57 @@ public abstract class BaseChart<T> extends Widget {
return result;
};
}
if (legendLabelsFormatterFlag) {
options.legend = options.legend || {};
options.legend.labelFormatter = function() {
var result = self.@org.moxieapps.gwt.highcharts.client.BaseChart::legendLabelsFormatterCallback(Lcom/google/gwt/core/client/JavaScriptObject;)(this);
if (result == null) {
return false;
}
return result;
};
}
// X axis label formatters
for (i = 0; i < xAxisLabelFormatterFlags.length; i++) {
if (!xAxisLabelFormatterFlags[i]) continue;
var xAxis = xAxisLabelFormatterFlags.length == 1 ? options.xAxis : options.xAxis[i];
xAxis.labels = xAxis.labels || {};
xAxis.labels.formatter = function() {
var xAxisB = xAxisLabelFormatterFlags.length == 1 ? options.xAxis : options.xAxis[i];
xAxisB.labels = xAxisB.labels || {};
xAxisB.labels.formatter = function() {
return self.@org.moxieapps.gwt.highcharts.client.BaseChart::xAxisLabelFormatterCallback(Lcom/google/gwt/core/client/JavaScriptObject;I)(this, arguments.callee.index);
};
xAxis.labels.formatter.index = i;
xAxisB.labels.formatter.index = i;
}
// Y axis label formatters
for (i = 0; i < yAxisLabelFormatterFlags.length && i < yAxisStackLabelFormatterFlags.length; i++) {
var yAxis = yAxisLabelFormatterFlags.length == 1 ? options.yAxis : options.yAxis[i];
var yAxisB = yAxisLabelFormatterFlags.length == 1 ? options.yAxis : options.yAxis[i];
if (yAxisLabelFormatterFlags[i]) {
yAxis.labels = yAxis.labels || {};
yAxis.labels.formatter = function() {
yAxisB.labels = yAxisB.labels || {};
yAxisB.labels.formatter = function() {
return self.@org.moxieapps.gwt.highcharts.client.BaseChart::yAxisLabelFormatterCallback(Lcom/google/gwt/core/client/JavaScriptObject;I)(this, arguments.callee.index);
};
yAxis.labels.formatter.index = i;
yAxisB.labels.formatter.index = i;
}
if (yAxisStackLabelFormatterFlags[i]) {
yAxis.stackLabels = yAxis.stackLabels || {};
yAxis.stackLabels.formatter = function() {
yAxisB.stackLabels = yAxisB.stackLabels || {};
yAxisB.stackLabels.formatter = function() {
return self.@org.moxieapps.gwt.highcharts.client.BaseChart::yAxisStackLabelFormatterCallback(Lcom/google/gwt/core/client/JavaScriptObject;I)(this, arguments.callee.index);
};
yAxis.stackLabels.formatter.index = i;
yAxisB.stackLabels.formatter.index = i;
}
}
// Plot options data label formatters
for (var type4 in plotOptionsLabelsFormatterFlags) {
if (type4.indexOf("gwt") < 0 && plotOptionsLabelsFormatterFlags[type4]) {
for (var type6 in plotOptionsLabelsFormatterFlags) {
if (type6.indexOf("gwt") < 0 && plotOptionsLabelsFormatterFlags[type6]) {
options.plotOptions = options.plotOptions || {};
options.plotOptions[type4] = options.plotOptions[type4] || {};
options.plotOptions[type4].dataLabels = options.plotOptions[type4].dataLabels || {};
options.plotOptions[type4].dataLabels.formatter = function() {
options.plotOptions[type6] = options.plotOptions[type6] || {};
options.plotOptions[type6].dataLabels = options.plotOptions[type6].dataLabels || {};
options.plotOptions[type6].dataLabels.formatter = function() {
return self.@org.moxieapps.gwt.highcharts.client.BaseChart::plotOptionsLabelsFormatterCallback(Lcom/google/gwt/core/client/JavaScriptObject;Ljava/lang/String;)(this, arguments.callee.type);
};
options.plotOptions[type4].dataLabels.formatter.type = type4;
options.plotOptions[type6].dataLabels.formatter.type = type6;
}
}
@@ -2317,6 +2401,16 @@ public abstract class BaseChart<T> extends Widget {
return true;
}
@SuppressWarnings({"UnusedDeclaration"})
private boolean axisEventCallback(String axisId, JavaScriptObject nativeEvent, String eventType) {
Axis<?> axis = getAxis(axisId);
//noinspection SimplifiableIfStatement
if ("setExtremes".equals(eventType) && axis != null && axis.getAxisSetExtremesEventHandler() != null) {
return axis.getAxisSetExtremesEventHandler().onSetExtremes(new AxisSetExtremesEvent(nativeEvent, axis));
}
return true;
}
@SuppressWarnings({"UnusedDeclaration"})
private String toolTipFormatterCallback(JavaScriptObject nativeData) {
if (toolTip == null || toolTip.getToolTipFormatter() == null) {
@@ -2325,6 +2419,14 @@ public abstract class BaseChart<T> extends Widget {
return toolTip.getToolTipFormatter().format(new ToolTipData(nativeData));
}
@SuppressWarnings({"UnusedDeclaration"})
private String legendLabelsFormatterCallback(JavaScriptObject nativeData) {
if (legend == null || legend.getLabelsFormatter() == null) {
return null;
}
return legend.getLabelsFormatter().format(new LegendLabelsData(nativeData));
}
@SuppressWarnings({"UnusedDeclaration"})
private String xAxisLabelFormatterCallback(JavaScriptObject nativeData, int axisIndex) {
if (xAxes == null || xAxes.size() <= axisIndex ||
@@ -2385,6 +2487,22 @@ public abstract class BaseChart<T> extends Widget {
return seriesList.get(seriesIndex).getPlotOptions().getDataLabels().getFormatter().format(new DataLabelsData(nativeData));
}
/**
* Fixing a bug currently in the base Highcharts implementation regarding the placement of the checkbox in the legend.
* Requires the symbol padding (see {@link Legend#setSymbolPadding(Number)}) to be set to <code>20</code>. Invoked
* whenever a series is added / displayed in a rendered chart.<p>
*
* The implementation moves the legend item text 15px to the left, using the space made by setting the symbol
* padding to 20px; the checkbox is moved 18px to the left with the top margin set to 0px.
*/
private static native JavaScriptObject nativeAdjustCheckboxPosition(JavaScriptObject series) /*-{
if (series.legendItem && series.checkbox) {
series.legendItem.translate(-15, 0);
series.checkbox.style.marginLeft = '-18px'
series.checkbox.style.marginTop = '0px'
}
}-*/;
private static native void nativeRedraw(JavaScriptObject chart) /*-{
chart.redraw();
}-*/;
@@ -16,6 +16,8 @@
package org.moxieapps.gwt.highcharts.client;
import org.moxieapps.gwt.highcharts.client.labels.LegendLabelsFormatter;
/**
* A configurable class that can be used to represent custom legend options for the
* chart, which can then be set on the chart (via the {@link Chart#setLegend(Legend)} method.)
@@ -317,7 +319,35 @@ public class Legend extends Configurable<Legend> {
return this.setOption("layout", layout != null ? layout.toString() : null);
}
// TODO: Add label formatter
private LegendLabelsFormatter legendLabelsFormatter;
/**
* Sets a custom formatter for the labels that can be used to control how the text of the
* legend labels will be displayed. See the {@link LegendLabelsFormatter} interface, and
* in particular the {@link LegendLabelsFormatter#format(org.moxieapps.gwt.highcharts.client.labels.LegendLabelsData)}
* method for more details on the capabilities available to custom legend formatters.
*
* @param legendLabelsFormatter The custom formatter to use for the labels (if not given a built-in
* generic formatter is used which simply returns the name of the series
* or, for pie charts, the name of the point).
* @return A reference to this {@link Legend} instance for convenient method chaining.
* @since 1.3.0
*/
public Legend setLabelsFormatter(LegendLabelsFormatter legendLabelsFormatter) {
this.legendLabelsFormatter = legendLabelsFormatter;
return this;
}
/**
* Returns the custom labels formatter that has been applied to the legend, or null if the
* built-in generic formatter is being used instead.
*
* @return The custom data labels formatter that has been applied, or null if it has not been set.
* @since 1.3.0
*/
public LegendLabelsFormatter getLabelsFormatter() {
return this.legendLabelsFormatter;
}
/**
* Convenience method for setting the 'margin' option of the legend. Equivalent to:
@@ -365,7 +365,10 @@ public class Point extends Configurable<Point> {
* animation options. <p/>
* Note that this method is only relevant on Point instance that are obtained from the chart
* after it has been rendered, such as via an event or dynamically retrieving the points of
* a series.
* a series.<p/>
* Also note that when using persistent chart's, you'll normally want to use the
* {@link Series#removePoint(Point)} method instead of this one.
*
*
* @return A reference to this {@link Point} instance for convenient method chaining.
* @since 1.1.0
@@ -379,7 +382,9 @@ public class Point extends Configurable<Point> {
* and/or animated or not. <p/>
* Note that this method is only relevant on Point instance that are obtained from the chart
* after it has been rendered, such as via an event or dynamically retrieving the points of
* a series.
* a series.<p/>
* Also note that when using persistent chart's, you'll normally want to use the
* {@link Series#removePoint(Point, boolean, boolean)} method instead of this one.
*
* @param redraw Whether to redraw the chart after the point is removed. When removing more than one
* point, it is highly recommended that the redraw option be set to false, and instead
@@ -399,7 +404,9 @@ public class Point extends Configurable<Point> {
* and the details of the animation options. <p/>
* Note that this method is only relevant on Point instance that are obtained from the chart
* after it has been rendered, such as via an event or dynamically retrieving the points of
* a series.
* a series.<p/>
* Also note that when using persistent chart's, you'll normally want to use the
* {@link Series#removePoint(Point, boolean, Animation)} method instead of this one.
*
* @param redraw Whether to redraw the chart after the point is removed. When removing more than one
* point, it is highly recommended that the redraw option be set to false, and instead
@@ -677,7 +684,7 @@ public class Point extends Configurable<Point> {
nativeUpdate(this.nativePoint, pointOptions.getY().doubleValue(), redraw, animation != null);
}
} else {
nativeUpdate(this.nativePoint, Series.convertPointToJavaScriptObject(pointOptions), redraw, animation != null);
nativeUpdate(this.nativePoint, convertPointToJavaScriptObject(pointOptions), redraw, animation != null);
}
} else {
if (pointOptions.isSingleValue()) {
@@ -687,7 +694,7 @@ public class Point extends Configurable<Point> {
nativeUpdate(this.nativePoint, pointOptions.getY().doubleValue(), redraw, animation.getOptions().getJavaScriptObject());
}
} else {
nativeUpdate(this.nativePoint, Series.convertPointToJavaScriptObject(pointOptions), redraw, animation.getOptions().getJavaScriptObject());
nativeUpdate(this.nativePoint, convertPointToJavaScriptObject(pointOptions), redraw, animation.getOptions().getJavaScriptObject());
}
}
} else {
@@ -728,6 +735,32 @@ public class Point extends Configurable<Point> {
return options;
}
// Only needed and used when handling removing of points from charts that have been set in "persistent" mode
private String id;
// Internal method purposefully package scope
void setId(String id) {
this.id = id;
}
// Internal method purposefully package scope
String getId() {
if(this.nativePoint != null) {
return nativeGetString(this.nativePoint, "id");
} else {
return this.id;
}
}
private static JavaScriptObject convertPointToJavaScriptObject(Point point) {
final JSONObject options = point.getOptions() != null ? point.getOptions() : new JSONObject();
Chart.addPointScalarValues(point, options);
if(point.hasNativeProperties()) {
Point.addPointNativeProperties(point, options);
}
return options.getJavaScriptObject();
}
private static native boolean nativeContainsKey(JavaScriptObject point, String key) /*-{
return point[key] != undefined;
}-*/;
@@ -27,6 +27,7 @@ import org.moxieapps.gwt.highcharts.client.plotOptions.PlotOptions;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
/**
* Manages a data series (and its options) that can then be added to a {@link Chart}. As an extension
@@ -513,14 +514,14 @@ public class Series extends Configurable<Series> {
if (nativeSeries != null) {
if (animation == null || animation.getOptions() == null) {
final boolean animationFlag = animation != null;
if (point.isSingleValue()) {
if (point.isSingleValue() && !chart.isPersistent() && !point.hasNativeProperties()) {
nativeAddPoint(nativeSeries, point.getY(), redraw, shift, animationFlag);
} else {
nativeAddPoint(nativeSeries, convertPointToJavaScriptObject(point), redraw, shift, animationFlag);
}
} else {
final JavaScriptObject animationOptions = animation.getOptions().getJavaScriptObject();
if (point.isSingleValue()) {
if (point.isSingleValue() && !chart.isPersistent() && !point.hasNativeProperties()) {
nativeAddPoint(nativeSeries, point.getY(), redraw, shift, animationOptions);
} else {
nativeAddPoint(nativeSeries, convertPointToJavaScriptObject(point), redraw, shift, animationOptions);
@@ -531,13 +532,15 @@ public class Series extends Configurable<Series> {
return this;
}
// Purposefully friendly scope so that we can get to this method from the Point class as well
static JavaScriptObject convertPointToJavaScriptObject(Point point) {
private JavaScriptObject convertPointToJavaScriptObject(Point point) {
final JSONObject options = point.getOptions() != null ? point.getOptions() : new JSONObject();
Chart.addPointScalarValues(point, options);
if(point.hasNativeProperties()) {
Point.addPointNativeProperties(point, options);
}
if(chart != null) {
chart.addPointId(point, options);
}
return options.getJavaScriptObject();
}
@@ -696,7 +699,7 @@ public class Series extends Configurable<Series> {
if (nativeSeries != null) {
JSONArray jsonArray = new JSONArray();
for (int i = 0, pointsLength = points.length; i < pointsLength; i++) {
jsonArray.set(i, Chart.convertPointToJSON(points[i]));
jsonArray.set(i, chart.convertPointToJSON(points[i]));
}
nativeSetData(nativeSeries, jsonArray.getJavaScriptObject(), redraw);
}
@@ -730,6 +733,91 @@ public class Series extends Configurable<Series> {
return convertedPoints.toArray(new Point[convertedPoints.size()]);
}
/**
* Remove the point from the series, automatically redrawing the chart using the default
* animation options. <p/>
* Note that this method is only relevant given Point instances that are obtained from the chart
* after it has been rendered, such as via an event or dynamically retrieving the points of
* a series.<p/>
* Also note that this method is primarily intended to ensure compatibility with chart's
* that have been set in persistent mode via the {@link BaseChart#setPersistent(boolean)} method.
* If you're using non-persistent charts, you can instead simply use the
* {@link Point#remove()} method to achieve the same affect.
*
* @param point The point instance (obtained dynamically from the chart) to remove from the series.
*
* @return A reference to this {@link Series} instance for convenient method chaining.
* @since 1.3.0
*/
public Series removePoint(Point point) {
return this.removePoint(point, true, true);
}
/**
* Remove the point from the series, explicitly controlling whether the chart is redrawn
* and/or animated or not. <p/>
* Note that this method is only relevant given Point instances that are obtained from the chart
* after it has been rendered, such as via an event or dynamically retrieving the points of
* a series. <p/>
* Also note that this method is primarily intended to ensure compatibility with chart's
* that have been set in persistent mode via the {@link BaseChart#setPersistent(boolean)} method.
* If you're using non-persistent charts, you can instead simply use the
* {@link Point#remove(boolean, boolean)} method to achieve the same affect.
*
* @param point The point instance (obtained dynamically from the chart) to remove from the series.
* @param redraw Whether to redraw the chart after the point is removed. When removing more than one
* point, it is highly recommended that the redraw option be set to false, and instead
* {@link Chart#redraw()} is explicitly called after the removing of points is finished.
* @param animation Defaults to true. When true, the graph will be animated with default animation options.
* Note, see the {@link #removePoint(Point, boolean, Animation)} method
* for more control over how the animation will run.
* @return A reference to this {@link Series} instance for convenient method chaining.
* @since 1.3.0
*/
public Series removePoint(Point point, boolean redraw, boolean animation) {
return this.removePoint(point, redraw, animation ? new Animation() : null);
}
/**
* Remove the point from the series, explicitly controlling whether the chart is redrawn
* and the details of the animation options. <p/>
* Note that this method is only relevant given Point instances that are obtained from the chart
* after it has been rendered, such as via an event or dynamically retrieving the points of
* a series.<p/>
* Also note that this method is primarily intended to ensure compatibility with chart's
* that have been set in persistent mode via the {@link BaseChart#setPersistent(boolean)} method.
* If you're using non-persistent charts, you can instead simply use the
* {@link Point#remove(boolean, Animation)} method to achieve the same affect.
*
* @param point The point instance (obtained dynamically from the chart) to remove from the series.
* @param redraw Whether to redraw the chart after the point is removed. When removing more than one
* point, it is highly recommended that the redraw option be set to false, and instead
* {@link Chart#redraw()} is explicitly called after the removing of points is finished.
* @param animation The custom animation to use when removing the point from the series.
* @return A reference to this {@link Series} instance for convenient method chaining.
* @since 1.3.0
*/
public Series removePoint(Point point, boolean redraw, Animation animation) {
String id = point.getId();
// First, tell the point to remove itself from the underlying Highcharts instance
point.remove(redraw, animation);
// Second, find the matching point within the series, and remove it.
// Note that this logic is purposefully only functional for chart's that are using the "setPersistent()"
// option. Removing a point from a non-persistent chart can be achieved by simply using
// the "Point.remove()" methods.
if(id != null && points != null) {
for (Iterator<Point> iterator = points.iterator(); iterator.hasNext(); ) {
Point existingPoint = iterator.next();
if(id.equals(existingPoint.getId())) {
iterator.remove();
}
}
}
return this;
}
/**
* Remove this series from the chart it is a part of.
*
@@ -26,6 +26,96 @@ package org.moxieapps.gwt.highcharts.client.labels;
*/
public abstract class BaseDataLabels<T extends BaseDataLabels> extends Labels<T> {
/**
* Convenience method for setting the 'backgroundColor' option for the data labels. Equivalent to:
* <pre><code>
* labels.setOption("backgroundColor", "#CC0000");
* </code></pre>
* The background color or gradient for the data label. Defaults to undefined.
*
* @param backgroundColor The background color or gradient for the data label.
* @return A reference to this {@link BaseDataLabels} instance for convenient method chaining.
* @since 1.3.0
*/
public T setBackgroundColor(String backgroundColor) {
return this.setOption("backgroundColor", backgroundColor);
}
/**
* Convenience method for setting the 'borderColor' option for the data labels. Equivalent to:
* <pre><code>
* labels.setOption("borderColor", "#CC0000");
* </code></pre>
* The border color for the data label. Defaults to undefined.
*
* @param borderColor The border color for the data label.
* @return A reference to this {@link BaseDataLabels} instance for convenient method chaining.
* @since 1.3.0
*/
public T setBorderColor(String borderColor) {
return this.setOption("borderColor", borderColor);
}
/**
* Convenience method for setting the 'borderRadius' option for the data labels. Equivalent to:
* <pre><code>
* labels.setOption("borderRadius", 3);
* </code></pre>
* The border radius in pixels for the data label. Defaults to 0.
*
* @param borderRadius The border radius in pixels for the data label.
* @return A reference to this {@link BaseDataLabels} instance for convenient method chaining.
* @since 1.3.0
*/
public T setBorderRadius(Number borderRadius) {
return this.setOption("borderRadius", borderRadius);
}
/**
* Convenience method for setting the 'borderWidth' option for the data labels. Equivalent to:
* <pre><code>
* labels.setOption("borderWidth", 3);
* </code></pre>
* The border width in pixels for the data label. Defaults to 0.
*
* @param borderWidth The border width in pixels for the data label.
* @return A reference to this {@link BaseDataLabels} instance for convenient method chaining.
* @since 1.3.0
*/
public T setBorderWidth(Number borderWidth) {
return this.setOption("borderWidth", borderWidth);
}
/**
* Convenience method for setting the 'padding' option for the data labels. Equivalent to:
* <pre><code>
* labels.setOption("padding", 3);
* </code></pre>
* When either the borderWidth or the backgroundColor is set, this is the padding within the box. Defaults to 2.
*
* @param padding The padding within the box (only visible when 'borderWidth' is non-zero).
* @return A reference to this {@link BaseDataLabels} instance for convenient method chaining.
* @since 1.3.0
*/
public T setPadding(Number padding) {
return this.setOption("padding", padding);
}
/**
* Convenience method for setting the 'shadow' option for the data labels. Equivalent to:
* <pre><code>
* labels.setOption("shadow", true);
* </code></pre>
* The shadow of the box. Works best with borderWidth or backgroundColor Defaults to false.
*
* @param shadow 'true' to disable a shadow around the box.
* @return A reference to this {@link BaseDataLabels} instance for convenient method chaining.
* @since 1.3.0
*/
public T setShadow(boolean shadow) {
return this.setOption("shadow", shadow);
}
private DataLabelsFormatter dataLabelsFormatter;
/**
@@ -23,7 +23,7 @@ import org.moxieapps.gwt.highcharts.client.Configurable;
* Controls configuration options for the markers within a series. Can be set as a plot option on a series
* via the {@link PlotOptions#setMarker(Marker)} method. Example usage:
* <code><pre>
* chart.setPlotOptions(new PlotOptions()
* chart.setSeriesPlotOptions(new SeriesPlotOptions()
* .setMarker(
* new Marker()
* .setEnabled(true)
@@ -41,6 +41,11 @@ public class Marker extends Configurable<Marker> {
/**
* An enumeration of supported marker symbol types, which can be passed to methods
* like {@link Marker#setSymbol(Marker.Symbol)} method.
* <p/>Note that custom marker images are also supported by simply setting the
* "symbol" option to a URL reference. E.g.
* <pre><code>
* marker.setOption("symbol", "url(/serverpath/image.png)");
* </code></pre>
*/
public enum Symbol {
@@ -246,6 +251,11 @@ public class Marker extends Configurable<Marker> {
* A predefined shape or symbol for the marker. When null, the symbol is pulled from the default
* {@link org.moxieapps.gwt.highcharts.client.Chart#setSymbols(org.moxieapps.gwt.highcharts.client.plotOptions.Marker.Symbol[])}
* options. Defaults to null.
* <p/>
* Note that custom marker images are also supported by simply setting the "symbol" option to a URL reference. E.g.
* <pre><code>
* marker.setOption("symbol", "url(/serverpath/image.png)");
* </code></pre>
*
* @param symbol The shape or symbol for the marker.
* @return A reference to this {@link Marker} instance for convenient method chaining.