Package com.sencha.gxt.chart.client.chart.series

Source Code of com.sencha.gxt.chart.client.chart.series.GaugeSeries

/**
* Sencha GXT 3.0.0 - Sencha for GWT
* Copyright(c) 2007-2012, Sencha, Inc.
* licensing@sencha.com
*
* http://www.sencha.com/products/gxt/license/
*/
package com.sencha.gxt.chart.client.chart.series;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.user.client.Event;
import com.sencha.gxt.chart.client.chart.axis.GaugeAxis;
import com.sencha.gxt.chart.client.draw.Color;
import com.sencha.gxt.chart.client.draw.path.EllipticalArc;
import com.sencha.gxt.chart.client.draw.path.LineTo;
import com.sencha.gxt.chart.client.draw.path.MoveTo;
import com.sencha.gxt.chart.client.draw.path.PathCommand;
import com.sencha.gxt.chart.client.draw.path.PathSprite;
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 com.sencha.gxt.fx.client.animation.Animator;

/**
* Creates a Gauge Chart. Gauge Charts are used to show progress in a certain
* variable.
*
* @param <M> the data type used by this series
*/
public class GaugeSeries<M> extends AbstractPieSeries<M> {

  private boolean needle = false;
  private PathSprite needleSprite;
  private Slice needleSlice;
  private double value = Double.NaN;

  /**
   * Creates a gauge {@link Series}.
   */
  public GaugeSeries() {
  }

  @Override
  public void drawSeries() {

    ListStore<M> store = chart.getCurrentStore();

    if (store == null || store.size() == 0) {
      return;
    }

    PreciseRectangle chartBBox = chart.getBBox();
    @SuppressWarnings("unchecked")
    GaugeAxis<M> axis = (GaugeAxis<M>) chart.getAxis(null);
    ArrayList<Slice> oldSlices = slices;
    slices = new ArrayList<Slice>();
    double minimum = axis.getMinimum();
    double maximum = axis.getMaximum();

    center.setX(chartBBox.getX() + (chartBBox.getWidth() / 2.0));
    center.setY(chartBBox.getY() + chartBBox.getHeight());
    radius = Math.min(center.getX() - chartBBox.getX(), center.getY() - chartBBox.getY());

    M record = store.get(0);
    value = angleField.getValue(record).doubleValue();

    double splitAngle = -180.0 * (1.0 - (value - minimum) / (maximum - minimum));
    if (needle) {
      Slice sliceA = new Slice(value, -179.99999, 0.00001, radius);
      slices.add(sliceA);
    } else {
      Slice sliceB = new Slice(value, -179.99999, splitAngle, radius);
      slices.add(sliceB);
      Slice sliceC = new Slice(maximum - value, splitAngle, 0.00001, radius);
      slices.add(sliceC);
    }

    // do pie slices after.
    for (int i = 0; i < slices.size(); i++) {
      Slice slice = slices.get(i);
      final PathSprite sprite;

      if (i < sprites.size()) {
        sprite = (PathSprite) sprites.get(i);
      } else {
        sprite = new PathSprite();
        chart.addSprite(sprite);
        sprites.add(sprite);
      }

      // set pie slice properties
      sprite.setHidden(false);
      if (i == 0) {
        sprite.setFill(colors.get(0));
      } else {
        sprite.setFill(colors.get(1));
      }
      slice.setMargin(margin);
      slice.setStartRho(slice.getRho() * donut / 100.0);
      slice.setEndRho(slice.getRho());
      if (stroke != null) {
        sprite.setStroke(stroke);
      }
      if (!Double.isNaN(strokeWidth)) {
        sprite.setStrokeWidth(strokeWidth);
      }
      if (chart.isAnimated() && oldSlices.size() == slices.size()) {
        createSegmentAnimator(sprite, oldSlices.get(i), slice).run(chart.getAnimationDuration(),
            chart.getAnimationEasing());
      } else {
        List<PathCommand> commands = calculateSegment(slice);
        sprite.setCommands(commands);
        sprite.redraw();
      }
      if (renderer != null) {
        renderer.spriteRenderer(sprite, i, chart.getCurrentStore());
      }
    }

    if (needle) {
      splitAngle = splitAngle * Math.PI / 180;

      if (needleSprite == null) {
        needleSprite = new PathSprite();
        needleSprite.setStrokeWidth(4);
        needleSprite.setStroke(new Color("#222"));
        chart.addSprite(needleSprite);
      }

      if (chart.isAnimated() && needleSlice != null) {
        Slice old = needleSlice;
        needleSlice = new Slice(value, -180, splitAngle * 180 / Math.PI, radius);
        needleSlice.setMargin(margin);
        needleSlice.setStartRho(needleSlice.getRho() * donut / 100.0);
        needleSlice.setEndRho(needleSlice.getRho());
        createNeedleAnimator(needleSprite, old, needleSlice).run(chart.getAnimationDuration(),
            chart.getAnimationEasing());
      } else {
        // store the slice representing the needle
        needleSlice = new Slice(value, -180, splitAngle * 180 / Math.PI, radius);
        needleSlice.setMargin(margin);
        needleSlice.setStartRho(needleSlice.getRho() * donut / 100.0);
        needleSlice.setEndRho(needleSlice.getRho());
        ArrayList<PathCommand> needleCommands = new ArrayList<PathCommand>();
        needleCommands.add(new MoveTo(center.getX() + (radius * donut / 100.0) * Math.cos(splitAngle), center.getY()
            + -Math.abs((radius * donut / 100.0)) * Math.sin(splitAngle)));
        needleCommands.add(new LineTo(center.getX() + radius * Math.cos(splitAngle), center.getY()
            + -Math.abs(radius * Math.sin(splitAngle))));
        needleSprite.setCommands(needleCommands);
        needleSprite.redraw();
      }
    }
  }

  @Override
  public void hide(int yFieldIndex) {
  }

  @Override
  public void highlight(int yFieldIndex) {
    if (highlighter != null) {
      highlighter.highlight(sprites.get(0));
    }
  }

  @Override
  public void highlightAll(int index) {
  }

  /**
   * Returns whether or not the series uses a needle in place of a wedge.
   *
   * @return true if needle
   */
  public boolean isNeedle() {
    return needle;
  }

  @Override
  public int onMouseMove(PrecisePoint point, Event event) {
    return -1;
  }

  @Override
  public void onMouseOut(PrecisePoint point, Event event) {
  }

  /**
   * Sets whether or not the series uses a needle in place of a wedge.
   *
   * @param needle true if needle
   */
  public void setNeedle(boolean needle) {
    this.needle = needle;
    if (!needle) {
      needleSlice = null;
      if (needleSprite != null) {
        chart.remove(needleSprite);
        needleSprite = null;
      }
    } else if (sprites.size() > 1) {
      chart.remove(sprites.remove(1));
    }
  }

  @Override
  public void show(int yFieldIndex) {
  }

  @Override
  public void unHighlight(int yFieldIndex) {
    if (highlighter != null) {
      highlighter.unHighlight(sprites.get(0));
    }
  }

  @Override
  public void unHighlightAll(int index) {
  }

  @Override
  public boolean visibleInLegend(int index) {
    return false;
  }

  @Override
  protected int getIndex(PrecisePoint point) {
    return 0;
  }

  @Override
  protected ValueProvider<M, ? extends Number> getValueProvider(int index) {
    return null;
  }

  /**
   * Creates an animator that animates for the starting {@link Slice} to the
   * ending slice on the given sprite.
   *
   * @param sprite the sprite to be animated
   * @param start the starting slice
   * @param end the ending slice
   * @return the animation to be run
   */
  private Animator createNeedleAnimator(final PathSprite sprite, final Slice start, final Slice end) {
    // find the delta
    final Slice delta = new Slice(0, start.getStartAngle() - end.getStartAngle(), start.getEndAngle()
        - end.getEndAngle(), start.getRho() - end.getRho());
    delta.setMargin(start.getMargin() - end.getMargin());
    delta.setStartRho(start.getStartRho() - end.getStartRho());
    delta.setEndRho(start.getEndRho() - end.getEndRho());
    final Slice origin = new Slice(start);
    return new Animator() {
      @Override
      protected void onUpdate(double progress) {
        origin.setStartAngle(start.getStartAngle() - (delta.getStartAngle() * progress));
        origin.setEndAngle(start.getEndAngle() - (delta.getEndAngle() * progress));
        origin.setRho(start.getRho() - (delta.getRho() * progress));
        origin.setMargin(start.getMargin() - (delta.getMargin() * progress));
        origin.setStartRho(start.getStartRho() - (delta.getStartRho() * progress));
        origin.setEndRho(start.getEndRho() - (delta.getEndRho() * progress));
        List<PathCommand> commands = calculateSegment(origin);
        if (commands.get(0) instanceof MoveTo) {
          sprite.setCommand(0, commands.get(0));
        }
        if (commands.get(2) instanceof EllipticalArc) {
          EllipticalArc arc = (EllipticalArc) commands.get(2);
          sprite.setCommand(1, new LineTo(arc.getX(), arc.getY()));
        }
        sprite.redraw();
      }
    };
  }
}
TOP

Related Classes of com.sencha.gxt.chart.client.chart.series.GaugeSeries

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.