Skip to content

Instantly share code, notes, and snippets.

@branflake2267
Last active August 29, 2015 14:14
Show Gist options
  • Save branflake2267/4881f5327714a097d005 to your computer and use it in GitHub Desktop.
Save branflake2267/4881f5327714a097d005 to your computer and use it in GitHub Desktop.
GXT Dashboard custom Candlestick series (prototype)
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.sencha.gxt.chart.client.chart.Chart.Position;
import com.sencha.gxt.chart.client.chart.Legend;
import com.sencha.gxt.chart.client.chart.axis.Axis;
import com.sencha.gxt.chart.client.chart.axis.NumericAxis;
import com.sencha.gxt.chart.client.chart.series.BarHighlighter;
import com.sencha.gxt.chart.client.chart.series.MultipleColorSeries;
import com.sencha.gxt.chart.client.chart.series.SeriesRenderer;
import com.sencha.gxt.chart.client.draw.Color;
import com.sencha.gxt.chart.client.draw.DrawFx;
import com.sencha.gxt.chart.client.draw.RGB;
import com.sencha.gxt.chart.client.draw.path.PathSprite;
import com.sencha.gxt.chart.client.draw.sprite.RectangleSprite;
import com.sencha.gxt.chart.client.draw.sprite.Sprite;
import com.sencha.gxt.chart.client.draw.sprite.SpriteList;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.core.client.util.PrecisePoint;
import com.sencha.gxt.core.client.util.PreciseRectangle;
import com.sencha.gxt.data.shared.ListStore;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
*/
public class CandleStickSeries<M> extends MultipleColorSeries<M> {
private boolean column = true;
private boolean stacked = false;
// The gutter space between single bars, as a percentage of the bar width
private double gutter = 38.2;
// The gutter space between groups of bars, as a percentage of the bar width
private double groupGutter = 38.2;
// Padding between the left/right axes and the bars
protected int xPadding = 10;
// Padding between the top/bottom axes and the bars
protected int yPadding = 0;
private Axis<M, ?> axis;
private double minY = 0;
private double maxY = 0;
private double groupBarWidth = 0;
private int groupBarsLength = 0;
private int storeSize = 0;
private double scale = 0;
private double zero = 0;
private Set<Integer> exclude = new HashSet<Integer>();
// the bar attributes
private Map<Integer, RectangleSprite> rects = new HashMap<Integer, RectangleSprite>();
private Map<Integer, Double> totalPositiveDimensions = new HashMap<Integer, Double>();
private Map<Integer, Double> totalNegativeDimensions = new HashMap<Integer, Double>();
protected List<ValueProvider<? super M, ? extends Number>> yFields = new ArrayList<ValueProvider<? super M, ? extends Number>>();
private Position yAxisPosition;
private Position xAxisPosition;
/**
* Creates a bar {@link com.sencha.gxt.chart.client.chart.series.Series}.
*/
public CandleStickSeries() {
// setup shadow attributes
Sprite config = new PathSprite();
config.setStrokeWidth(6);
config.setStrokeOpacity(0.05);
config.setStroke(new RGB(200, 200, 200));
config.setTranslation(1.2, 1.2);
config.setFill(Color.NONE);
config.setZIndex(9);
shadowAttributes.add(config);
config = new PathSprite();
config.setStrokeWidth(4);
config.setStrokeOpacity(0.1);
config.setStroke(new RGB(150, 150, 150));
config.setTranslation(0.9, 0.9);
config.setFill(Color.NONE);
config.setZIndex(9);
shadowAttributes.add(config);
config = new PathSprite();
config.setStrokeWidth(2);
config.setStrokeOpacity(0.15);
config.setStroke(new RGB(100, 100, 100));
config.setTranslation(0.6, 0.6);
config.setFill(Color.NONE);
config.setZIndex(9);
shadowAttributes.add(config);
// initialize shadow groups
if (shadowGroups.size() == 0) {
for (int i = 0; i < shadowAttributes.size(); i++) {
shadowGroups.add(new SpriteList<Sprite>());
}
}
setHighlighter(new BarHighlighter());
}
/**
* Adds a data field for the y axis of the series.
*
* @param index the index to have the yField inserted
* @param yField the value provider for the data on the y axis
*/
public void addYField(int index, ValueProvider<? super M, ? extends Number> yField) {
this.yFields.add(index, yField);
}
/**
* Adds a data field for the y axis of the series.
*
* @param yField the value provider for the data on the y axis
*/
public void addYField(ValueProvider<? super M, ? extends Number> yField) {
this.yFields.add(yField);
}
@Override
public void drawSeries() {
ListStore<M> store = chart.getCurrentStore();
if (store == null || store.size() == 0) {
this.clear();
return;
}
if (store.size() != storeSize) {
rects.clear();
}
storeSize = store.size();
calculatePaths();
// Create new or reuse sprites and animate/display
for (int i = 0; i < rects.size(); i++) {
if (rects.get(i) == null) {
continue;
}
if (chart.hasShadows()) {
renderShadows(i);
}
final RectangleSprite bar;
RectangleSprite rect = rects.get(i);
if (i < sprites.size()) {
bar = (RectangleSprite) sprites.get(i);
bar.setHidden(false);
} else {
// Create a new bar if needed (no height)
bar = new RectangleSprite();
if (column) {
bar.setX(rect.getX());
bar.setY(rect.getY() + rect.getHeight());
bar.setWidth(rect.getWidth());
bar.setHeight(0);
} else {
bar.setX(rect.getX());
bar.setY(rect.getY());
bar.setWidth(0);
bar.setHeight(rect.getHeight());
}
sprites.add(bar);
chart.addSprite(bar);
}
if (chart.isAnimated() && chart.isResizing()) {
if (column) {
bar.setX(rect.getX());
bar.setY(rect.getY() + rect.getHeight());
bar.setWidth(rect.getWidth());
bar.setHeight(0);
} else {
bar.setX(rect.getX());
bar.setY(rect.getY());
bar.setWidth(0);
bar.setHeight(rect.getHeight());
}
}
bar.setFill(rect.getFill());
if (stroke != null) {
bar.setStroke(stroke);
}
if (!Double.isNaN(strokeWidth)) {
bar.setStrokeWidth(strokeWidth);
}
if (chart.isAnimated() && !Double.isNaN(bar.getX())) {
DrawFx.createRectangleAnimator(bar, rect.toRectangle()).run(chart.getAnimationDuration(),
chart.getAnimationEasing());
} else {
bar.setX(rect.getX());
bar.setY(rect.getY());
bar.setWidth(rect.getWidth());
bar.setHeight(rect.getHeight());
bar.redraw();
}
if (renderer != null) {
renderer.spriteRenderer(bar, i, store);
}
}
for (int j = rects.size(); j < sprites.size(); j++) {
Sprite unusedSprite = sprites.get(j);
unusedSprite.setHidden(true);
unusedSprite.redraw();
}
for (int j = rects.size(); j < labels.size(); j++) {
Sprite unusedSprite = labels.get(j);
unusedSprite.setHidden(true);
unusedSprite.redraw();
}
if (!chart.hasShadows()) {
hideShadows();
} else {
for (int k = 0; k < shadowGroups.size(); k++) {
SpriteList<Sprite> shadows = shadowGroups.get(k);
for (int j = rects.size(); j < shadows.size(); j++) {
Sprite unusedSprite = shadows.get(j);
unusedSprite.setHidden(true);
unusedSprite.redraw();
}
}
}
drawLabels();
}
/**
* Calculates the girth of bars in the series.
*
* @return the girth of bars in the series
*/
public double getBarGirth() {
int ln = chart.getCurrentStore().size();
double gutter = this.gutter / 100;
double chartGirth = column ? chart.getBBox().getWidth() : chart.getBBox().getHeight();
double numerator = (column ? xPadding : yPadding) * 2;
double denominator = (ln * (gutter + 1) - gutter);
return (chartGirth - numerator) / denominator;
}
/**
* Returns the fields that have been hidden from the series using
* {@link #hide(int)}.
*
* @return the fields that have been hidden from the series
*/
public Set<Integer> getExcluded() {
if (yFields.size() > 1) {
return exclude;
} else {
return null;
}
}
/**
* Returns the gutter between group bars.
*
* @return the gutter between group bars
*/
public double getGroupGutter() {
return groupGutter;
}
/**
* Returns the gutter between bars.
*
* @return the gutter between bars
*/
public double getGutter() {
return gutter;
}
@Override
public double[] getGutters() {
double gutter = Math.ceil((column ? xPadding : yPadding) + getBarGirth() / 2);
double[] gutters = {0, 0};
gutters[column ? 0 : 1] = gutter;
return gutters;
}
@Override
public ArrayList<String> getLegendTitles() {
ArrayList<String> titles = new ArrayList<String>();
for (int j = 0; j < getYFields().size(); j++) {
if (legendTitles.size() > j) {
titles.add(legendTitles.get(j));
} else {
titles.add(getValueProviderName(getYField(j), j + 1));
}
}
return titles;
}
/**
* Returns the x axis position of the series.
*
* @return the x axis position of the series
*/
public Position getXAxisPosition() {
return xAxisPosition;
}
/**
* Returns the y axis position of the series.
*
* @return the y axis position of the series
*/
public Position getYAxisPosition() {
return yAxisPosition;
}
/**
* Returns the value provider for the y-axis of the series at the given index.
*
* @param index the index of the value provider
* @return the value provider for the y-axis of the series at the given index
*/
public ValueProvider<? super M, ? extends Number> getYField(int index) {
return yFields.get(index);
}
/**
* Returns the list of value providers for the y-axis of the series.
*
* @return the list of value providers for the y-axis of the series
*/
public List<ValueProvider<? super M, ? extends Number>> getYFields() {
return yFields;
}
@Override
public void hide(int yFieldIndex) {
if (yFields.size() > 1) {
for (int i = 0; i < sprites.size() / yFields.size(); i++) {
sprites.get(yFieldIndex + i * yFields.size()).setHidden(true);
sprites.get(yFieldIndex + i * yFields.size()).redraw();
if (labels.size() == sprites.size()) {
labels.get(yFieldIndex + i * yFields.size()).setHidden(true);
labels.get(yFieldIndex + i * yFields.size()).redraw();
}
if (chart.hasShadows()) {
for (int j = 0; j < shadowGroups.size(); j++) {
SpriteList<Sprite> shadows = shadowGroups.get(j);
if (shadows.size() > yFieldIndex + i * yFields.size()) {
shadows.get(yFieldIndex + i * yFields.size()).setHidden(true);
shadows.get(yFieldIndex + i * yFields.size()).redraw();
}
}
}
}
exclude.add(yFieldIndex);
chart.redrawChartForced();
} else {
toggle(true);
exclude.add(0);
}
// update axes
chart.getAxis(yAxisPosition);
}
@Override
public void highlight(int yFieldIndex) {
RectangleSprite bar = (RectangleSprite) sprites.get(yFieldIndex);
highlighter.highlight(bar);
}
@Override
public void highlightAll(int index) {
if (yFields.size() > 1) {
for (int i = 0; i < sprites.size() / yFields.size(); i++) {
highlighter.highlight(sprites.get(index + i * yFields.size()));
}
} else {
for (int i = 0; i < sprites.size(); i++) {
highlighter.highlight(sprites.get(i));
}
}
}
/**
* Removes a data field for the y axis of the series.
*
* @param index the index to have the yField inserted
* @return the removed field
*/
public ValueProvider<? super M, ? extends Number> removeYField(int index) {
return this.yFields.remove(index);
}
/**
* Removes a data field for the y axis of the series.
*
* @param yField the value provider for the data on the y axis
* @return whether or not the field was successfully removed
*/
public boolean removeYField(ValueProvider<? super M, ? extends Number> yField) {
return this.yFields.remove(yField);
}
/**
* Sets the gutter between group bars.
*
* @param groupGutter
*/
public void setGroupGutter(double groupGutter) {
this.groupGutter = groupGutter;
}
/**
* Sets the gutter between bars.
*
* @param gutter the gutter between bars
*/
public void setGutter(double gutter) {
this.gutter = gutter;
}
/**
* Sets the series title used in the legend.
*
* @param title the series title used in the legend
*/
public void setLegendTitle(String title) {
legendTitles.clear();
legendTitles.add(title);
if (chart != null) {
Legend<M> legend = chart.getLegend();
if (legend != null) {
legend.create();
legend.updatePosition();
}
}
}
/**
* Sets the list of labels used by the legend.
*
* @param legendTitles the list of labels
*/
public void setLegendTitles(List<String> legendTitles) {
this.legendTitles = legendTitles;
if (chart != null) {
Legend<M> legend = chart.getLegend();
if (legend != null) {
legend.create();
legend.updatePosition();
}
}
}
/**
* Sets whether or not the series is stacked.
*
* @param stacked whether or not the series is stacked
*/
public void setStacked(boolean stacked) {
this.stacked = stacked;
}
/**
* Sets the position of the x axis on the chart to be used by the series.
*
* @param xAxisPosition the position of the x axis on the chart to be used by
* the series
*/
public void setXAxisPosition(Position xAxisPosition) {
this.xAxisPosition = xAxisPosition;
}
/**
* Sets the position of the y axis on the chart to be used by the series.
*
* @param yAxisPosition the position of the y axis on the chart to be used by
* the series
*/
public void setYAxisPosition(Position yAxisPosition) {
this.yAxisPosition = yAxisPosition;
}
@Override
public void show(int yFieldIndex) {
if (yFields.size() > 1) {
for (int i = 0; i < sprites.size() / yFields.size(); i++) {
sprites.get(yFieldIndex + i * yFields.size()).setHidden(false);
sprites.get(yFieldIndex + i * yFields.size()).redraw();
if (labels.size() == sprites.size()) {
labels.get(yFieldIndex + i * yFields.size()).setHidden(false);
labels.get(yFieldIndex + i * yFields.size()).redraw();
}
if (chart.hasShadows()) {
for (int j = 0; j < shadowGroups.size(); j++) {
SpriteList<Sprite> shadows = shadowGroups.get(j);
if (shadows.size() == sprites.size()) {
shadows.get(yFieldIndex + i * yFields.size()).setHidden(false);
shadows.get(yFieldIndex + i * yFields.size()).redraw();
}
}
}
}
exclude.remove(yFieldIndex);
calculateBBox(false);
chart.redrawChartForced();
} else {
toggle(false);
exclude.remove(0);
}
}
@Override
public void unHighlight(int yFieldIndex) {
RectangleSprite bar = (RectangleSprite) sprites.get(yFieldIndex);
highlighter.unHighlight(bar);
}
@Override
public void unHighlightAll(int index) {
if (yFields.size() > 1) {
for (int i = 0; i < sprites.size() / yFields.size(); i++) {
highlighter.unHighlight(sprites.get(index + i * yFields.size()));
}
} else {
for (int i = 0; i < sprites.size(); i++) {
highlighter.unHighlight(sprites.get(i));
}
}
}
@Override
public boolean visibleInLegend(int index) {
if (yFields.size() > 1) {
if (exclude.contains(index)) {
return false;
}
return true;
} else {
if (sprites.size() == 0) {
return true;
} else {
return !sprites.get(0).isHidden();
}
}
}
@Override
protected int getIndex(PrecisePoint point) {
for (int i = 0; i < sprites.size(); i++) {
if (((RectangleSprite) sprites.get(i)).toRectangle().contains(point) && !sprites.get(i).isHidden()) {
return i;
}
}
return -1;
}
@Override
protected int getStoreIndex(int index) {
return (int) Math.floor(index / yFields.size());
}
@Override
protected ValueProvider<? super M, ? extends Number> getValueProvider(int index) {
ValueProvider<? super M, ? extends Number> value = null;
int storeIndex = getStoreIndex(index);
int yFieldIndex = index - (yFields.size() * storeIndex);
if (yFields.size() > 1) {
value = yFields.get(yFieldIndex);
} else if (yFields.size() == 1) {
value = yFields.get(yFieldIndex);
}
return value;
}
/**
* Calculates the bounds of the series.
*/
private void calculateBounds() {
ListStore<M> store = chart.getCurrentStore();
double barWidth = getBarGirth();
double groupGutter = this.groupGutter / 100;
groupBarsLength = yFields.size();
PreciseRectangle chartBBox = chart.getBBox();
calculateBBox(false);
// skip excluded series
groupBarsLength -= exclude.size();
axis = chart.getAxis(yAxisPosition);
if (axis != null) {
minY = axis.getFrom();
maxY = axis.getTo();
} else if (yFields.size() > 0) {
NumericAxis<M> numAxis = new NumericAxis<M>();
numAxis.setChart(chart);
for (int i = 0; i < yFields.size(); i++) {
numAxis.addField(yFields.get(i));
}
numAxis.calcEnds();
minY = numAxis.getFrom();
maxY = numAxis.getTo();
}
axis = chart.getAxis(xAxisPosition);
if (axis != null) {
minY = axis.getFrom();
maxY = axis.getTo();
}
scale = (column ? chartBBox.getHeight() - yPadding * 2 : chartBBox.getWidth() - xPadding * 2)
/ (Math.abs(maxY - minY));
groupBarWidth = barWidth;//barWidth / ((stacked ? 1 : groupBarsLength) * (groupGutter + 1) - groupGutter);
zero = column ? chartBBox.getY() + chartBBox.getHeight() - yPadding : chartBBox.getX() + xPadding;
List<Double> totalPositive = new ArrayList<Double>();
List<Double> totalNegative = new ArrayList<Double>();
if (stacked) {
for (int i = 0; i < store.size(); i++) {
M model = store.get(i);
totalPositive.add(0.0);
totalNegative.add(0.0);
for (int j = 0; j < yFields.size(); j++) {
if (exclude.contains(j)) {
continue;
}
double value = yFields.get(j).getValue(model).doubleValue();
if (value > 0) {
totalPositive.set(i, totalPositive.get(i) + value);
} else {
totalNegative.set(i, totalNegative.get(i) + Math.abs(value));
}
}
}
if (maxY > 0) {
totalPositive.add(maxY);
} else {
totalNegative.add(Math.abs(maxY));
}
if (minY > 0) {
totalPositive.add(minY);
} else {
totalNegative.add(Math.abs(minY));
}
double minus = 0;
double plus = 0;
for (int i = 0; i < totalNegative.size(); i++) {
minus = Math.max(minus, totalNegative.get(i));
}
for (int i = 0; i < totalPositive.size(); i++) {
plus = Math.max(plus, totalPositive.get(i));
}
scale = (column ? bbox.getHeight() - yPadding * 2 : bbox.getWidth() - xPadding * 2) / (plus + minus);
zero = zero + minus * scale * (column ? -1 : 1);
} else if (minY * maxY < 0) { // mix of positive and negative
if (column) {
zero -= -minY * scale;
} else {
zero += -minY * scale;
}
} else if (minY < 0) { // all negative
if (column) {
zero = chartBBox.getY();
} else {
zero = chartBBox.getX() + chartBBox.getWidth();
}
}
}
/**
* Build an array of paths for the chart.
*/
private void calculatePaths() {
ListStore<M> store = chart.getCurrentStore();
double gutter = this.gutter / 100;
calculateBounds();
for (int i = 0; i < store.size(); i++) {
RectangleSprite lowHighRect = new RectangleSprite();
RectangleSprite openCloseRect = new RectangleSprite();
rects.put(i * 2, lowHighRect);
rects.put(i * 2 + 1, openCloseRect);
double open = getYField(0).getValue(store.get(i)).doubleValue();
double close = getYField(1).getValue(store.get(i)).doubleValue();
double low = getYField(2).getValue(store.get(i)).doubleValue();
double high = getYField(3).getValue(store.get(i)).doubleValue();
low = Math.min(low, Math.min(open, close));
high = Math.max(high, Math.max(open, close));
double x = bbox.getX() + xPadding + i * getBarGirth() * (1 + gutter) + (groupBarWidth / 2);
{
double mainHeight = (high - low) * scale;
lowHighRect.setFill(colors.get(close > open ? 1 : 0));
lowHighRect.setWidth(1);//Math.max(groupBarWidth, 0));
lowHighRect.setX(x);
double mainY = bbox.getY() + scale * (maxY - high);
lowHighRect.setY(mainY);
lowHighRect.setHeight(mainHeight);
}
{
double height = scale * Math.abs(close - open);
double y = bbox.getY() + scale * (maxY - Math.max(open, close));
openCloseRect.setX(x - 4);
openCloseRect.setY(y);
openCloseRect.setWidth(9);
openCloseRect.setHeight(height);
openCloseRect.setFill(colors.get(close > open ? 1 : 0));
}
}
}
/**
* Draws the labels on the series.
*/
private void drawLabels() {
if (labelConfig != null) {
LabelPosition labelPosition = labelConfig.getLabelPosition();
for (int j = 0; j < rects.size(); j++) {
if (rects.get(j) == null) {
continue;
}
final Sprite sprite;
RectangleSprite bar = rects.get(j);
if (labels.get(j) != null) {
sprite = labels.get(j);
sprite.setHidden(false);
} else {
sprite = labelConfig.getSpriteConfig().copy();
if (column) {
sprite.setTranslation(bar.getX(), bar.getY() + bar.getHeight());
} else {
sprite.setTranslation(bar.getX(), bar.getY());
}
labels.put(j, sprite);
chart.addSprite(sprite);
}
if (chart.isAnimated() && chart.isResizing()) {
if (column) {
sprite.setTranslation(bar.getX(), bar.getY() + bar.getHeight());
} else {
sprite.setTranslation(bar.getX(), bar.getY());
}
}
setLabelText(sprite, j);
sprite.redraw();
PreciseRectangle box = sprite.getBBox();
double x = 0;
double y = 0;
if (column) {
x = bar.getX() + bar.getWidth() / 2.0;
if (labelPosition == LabelPosition.START) {
y = bar.getY() + bar.getHeight() - box.getHeight();
} else if (labelPosition == LabelPosition.END) {
if (bar.getHeight() > box.getHeight()) {
y = bar.getY();
} else {
y = bar.getY() - box.getHeight();
}
} else if (labelPosition == LabelPosition.OUTSIDE) {
y = bar.getY() - box.getHeight();
}
} else {
y = bar.getY() + bar.getHeight() / 2.0 - box.getHeight() / 2.0;
if (labelPosition == LabelPosition.START) {
x = bar.getX();
} else if (labelPosition == LabelPosition.END) {
if (bar.getWidth() > box.getWidth()) {
x = bar.getX() + bar.getWidth() - box.getWidth();
} else {
x = bar.getX() + bar.getWidth();
}
} else if (labelPosition == LabelPosition.OUTSIDE) {
x = bar.getX() + bar.getWidth();
}
}
if (labelConfig.isLabelContrast()) {
final Sprite back = sprites.get(j);
if (chart.isAnimated()) {
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
setLabelContrast(sprite, labelConfig, back);
}
});
} else {
setLabelContrast(sprite, labelConfig, back);
}
}
if (chart.isAnimated() && sprite.getTranslation() != null) {
DrawFx.createTranslationAnimator(sprite, x, y).run(chart.getAnimationDuration(), chart.getAnimationEasing());
} else {
sprite.setTranslation(x, y);
}
SeriesRenderer<M> labelRenderer = labelConfig.getSpriteRenderer();
if (labelRenderer != null) {
labelRenderer.spriteRenderer(sprite, j, chart.getCurrentStore());
}
sprite.redraw();
}
}
}
/**
* Renders the shadows for the bar at the given index.
*
* @param index the index of the shadows
*/
private void renderShadows(int index) {
if (groupBarsLength == 0) {
return;
}
// create shadows
for (int shindex = 0; shindex < shadowGroups.size(); shindex++) {
Sprite shadowBarAttr = shadowAttributes.get(shindex);
SpriteList<Sprite> shadows = shadowGroups.get(shindex);
final RectangleSprite shadowSprite;
RectangleSprite rect = rects.get(index);
if (index < shadows.size()) {
shadowSprite = (RectangleSprite) shadows.get(index);
shadowSprite.setHidden(false);
} else {
shadowSprite = new RectangleSprite();
if (column) {
shadowSprite.setX(rect.getX());
shadowSprite.setY(rect.getY() + rect.getHeight());
shadowSprite.setWidth(rect.getWidth());
shadowSprite.setHeight(0);
} else {
shadowSprite.setX(rect.getX());
shadowSprite.setY(rect.getY());
shadowSprite.setWidth(0);
shadowSprite.setHeight(rect.getHeight());
}
shadowSprite.update(shadowBarAttr);
shadows.add(shadowSprite);
chart.addSprite(shadowSprite);
}
if (chart.isAnimated() && chart.isResizing()) {
if (column) {
shadowSprite.setX(rect.getX());
shadowSprite.setY(rect.getY() + rect.getHeight());
shadowSprite.setWidth(rect.getWidth());
shadowSprite.setHeight(0);
} else {
shadowSprite.setX(rect.getX());
shadowSprite.setY(rect.getY());
shadowSprite.setWidth(0);
shadowSprite.setHeight(rect.getHeight());
}
}
if (chart.isAnimated() && !Double.isNaN(shadowSprite.getHeight()) && !Double.isNaN(shadowSprite.getWidth())) {
DrawFx.createRectangleAnimator(shadowSprite, rect.toRectangle()).run(chart.getAnimationDuration(),
chart.getAnimationEasing());
} else {
shadowSprite.setX(rect.getX());
shadowSprite.setY(rect.getY());
shadowSprite.setWidth(rect.getWidth());
shadowSprite.setHeight(rect.getHeight());
shadowSprite.redraw();
}
if (shadowRenderer != null) {
shadowRenderer.spriteRenderer(shadowSprite, index, chart.getCurrentStore());
}
}
shadowed = true;
}
/**
* Toggles all the sprites in the series to be hidden or shown.
*
* @param hide if true hides
*/
private void toggle(boolean hide) {
calculateBBox(false);
if (sprites.size() > 0) {
for (int i = 0; i < sprites.size(); i++) {
sprites.get(i).setHidden(hide);
sprites.get(i).redraw();
}
}
if (labelConfig != null) {
for (Sprite s : labels.values()) {
s.setHidden(hide);
s.redraw();
}
}
for (int i = 0; i < shadowGroups.size(); i++) {
SpriteList<Sprite> shadows = shadowGroups.get(i);
for (int j = 0; j < shadows.size(); j++) {
shadows.get(j).setHidden(hide);
shadows.get(j).redraw();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment