Package com.sencha.gxt.chart.client.chart.axis

Source Code of com.sencha.gxt.chart.client.chart.axis.RadialAxis

/**
* 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.axis;

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

import com.sencha.gxt.chart.client.chart.Chart.Position;
import com.sencha.gxt.chart.client.chart.RoundNumberProvider;
import com.sencha.gxt.chart.client.chart.series.RadarSeries;
import com.sencha.gxt.chart.client.chart.series.Series;
import com.sencha.gxt.chart.client.draw.Color;
import com.sencha.gxt.chart.client.draw.RGB;
import com.sencha.gxt.chart.client.draw.path.ClosePath;
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.PathSprite;
import com.sencha.gxt.chart.client.draw.sprite.CircleSprite;
import com.sencha.gxt.chart.client.draw.sprite.SpriteList;
import com.sencha.gxt.chart.client.draw.sprite.TextSprite;
import com.sencha.gxt.chart.client.draw.sprite.TextSprite.TextAnchor;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.core.client.util.PreciseRectangle;
import com.sencha.gxt.data.shared.LabelProvider;
import com.sencha.gxt.data.shared.ListStore;

/**
* {@link Axis} to be used with {@link RadarSeries}.
*
* @param <M> the data type of the axis
* @param <V> the variable type of axis
*/
public class RadialAxis<M, V> extends Axis<M, V> {

  /**
   * Enumeration of the display style of the radial axis.
   */
  public enum Display {
    /**
     * Display both the category axis and the scale axis.
     */
    BOTH,
    /**
     * Display the categories around the axis.
     */
    CATEGORIES,
    /**
     * Displays the numerical scale in the center of the axis.
     */
    SCALE
  }

  private CircleSprite circleConfig;

  private SpriteList<CircleSprite> circles = new SpriteList<CircleSprite>();

  protected List<ValueProvider<? super M, ? extends Number>> fields = new ArrayList<ValueProvider<? super M, ? extends Number>>();
  private SpriteList<TextSprite> scales = new SpriteList<TextSprite>();
  private TextSprite scaleConfig = new TextSprite();
  private LabelProvider<Number> scaleLabelProvider = new RoundNumberProvider<Number>();
  protected ValueProvider<? super M, V> categoryField;
  private Display display = Display.BOTH;
  private int radialSteps = 10;

  /**
   * Creates a radial {@link Axis}.
   */
  public RadialAxis() {
    circleConfig = new CircleSprite();
    circleConfig.setStroke(new RGB("#ccc"));
    circleConfig.setFill(Color.NONE);
    axisConfig.setStroke(new RGB("#ccc"));
  }

  @Override
  public void clear() {
    super.clear();
    while (circles.size() > 0) {
      CircleSprite sprite = circles.remove(circles.size() - 1);
      if (sprite != null) {
        sprite.remove();
      }
    }
    while (scales.size() > 0) {
      TextSprite sprite = scales.remove(scales.size() - 1);
      if (sprite != null) {
        sprite.remove();
      }
    }
  }

  @Override
  public void drawAxis(boolean init) {
    PreciseRectangle bbox = chart.getBBox();
    ListStore<M> store = chart.getCurrentStore();
    double length = store.size();
    double pi2 = Math.PI * 2;
    double centerX = bbox.getX() + (bbox.getWidth() / 2);
    double centerY = bbox.getY() + (bbox.getHeight() / 2);
    double rho = Math.min(bbox.getWidth(), bbox.getHeight()) / 2;

    for (int i = 0; i < radialSteps; i++) {
      final CircleSprite circle;
      if (i < circles.size()) {
        circle = circles.get(i);
      } else {
        circle = circleConfig.copy();
        chart.addSprite(circle);
        circles.add(circle);
      }
      circle.setCenterX(centerX);
      circle.setCenterY(centerY);
      circle.setRadius(Math.max(rho * (i + 1) / radialSteps, 0));
      circle.redraw();
    }

    for (int j = (int) length; j < lines.size(); j++) {
      lines.get(j).setHidden(true);
    }
    for (double i = 0; i < length; i++) {
      final PathSprite line;
      if (i < lines.size()) {
        line = lines.get((int) i);
        line.setHidden(false);
      } else {
        line = axisConfig.copy();
        chart.addSprite(line);
        lines.add(line);
      }
      line.clearCommands();
      line.addCommand(new MoveTo(centerX, centerY));
      line.addCommand(new LineTo(centerX + rho * Math.cos(i / length * pi2), centerY + rho * Math.sin(i / length * pi2)));
      line.addCommand(new ClosePath());
      line.redraw();
    }
    drawLabels();
  }

  @Override
  public void drawLabels() {
    labelNames.clear();
    fields.clear();
    PreciseRectangle bbox = chart.getBBox();
    ListStore<M> store = chart.getCurrentStore();
    double pi2 = Math.PI * 2;
    double centerX = bbox.getX() + (bbox.getWidth() / 2);
    double centerY = bbox.getY() + (bbox.getHeight() / 2);
    double rho = Math.min(bbox.getWidth(), bbox.getHeight()) / 2;
    double maxValue = 0;
    double margin = 10;

    // get all rendered fields
    for (Series<M> series : chart.getSeries()) {
      if (series instanceof RadarSeries) {
        final RadarSeries<M> radar = (RadarSeries<M>) series;
        fields.add(radar.getYField());
      }
    }
    // get maxValue to interpolate
    for (int index = 0; index < store.size(); index++) {
      for (int i = 0; i < fields.size(); i++) {
        maxValue = Math.max(fields.get(i).getValue(store.get(index)).doubleValue(), maxValue);
      }
      if (categoryField != null) {
        labelNames.add(categoryField.getValue(store.get(index)));
      }
    }

    // draw scale
    if (display != Display.CATEGORIES) {
      for (int i = 0; i < radialSteps; i++) {
        final TextSprite scale;
        if (i < scales.size()) {
          scale = scales.get(i);
        } else {
          scale = scaleConfig.copy();
          chart.addSprite(scale);
          scales.add(scale);
        }
        scale.setText(scaleLabelProvider.getLabel((Math.round((i + 1) / (double) radialSteps * maxValue))));
        scale.setX(centerX);
        scale.setY(centerY - rho * (i + 1) / radialSteps);
        scale.redraw();
      }
    }

    for (int j = labelNames.size(); j < labels.size(); j++) {
      labels.get(j).setHidden(true);
    }
    // draw text
    if (display != Display.SCALE && labelNames.size() > 0) {
      double size = labelNames.size();
      for (int i = 0; i < size; i++) {
        final TextSprite label;
        if (i < labels.size()) {
          label = labels.get(i);
          label.setHidden(false);
        } else {
          label = labelConfig.copy();
          chart.addSprite(label);
          labels.add(label);
        }
        double dx = Math.cos(i / size * pi2) * (rho + margin);
        double dy = Math.sin(i / size * pi2) * (rho + margin);
        label.setText(labelProvider.getLabel((labelNames.get(i))));
        label.redraw();
        label.setX(centerX + dx);
        label.setY(centerY + dy - (label.getBBox().getHeight() / 2.0));
        if (dx * dx <= 0.001) {
          label.setTextAnchor(TextAnchor.MIDDLE);
        } else {
          if (dx < 0) {
            label.setTextAnchor(TextAnchor.END);
          } else {
            label.setTextAnchor(TextAnchor.START);
          }
        }
        label.redraw();
      }
    }
  }

  /**
   * Returns the {@link ValueProvider} used for labels around the axis.
   *
   * @return the value provider used for labels around the axis
   */
  public ValueProvider<? super M, V> getCategoryField() {
    return categoryField;
  }

  /**
   * Returns the configuration for the circles on the axis.
   *
   * @return the configuration for the circles on the axis
   */
  public CircleSprite getCircleConfig() {
    return circleConfig;
  }

  /**
   * Returns the {@link Display} style of the axis.
   *
   * @return the display style of the axis
   */
  public Display getDisplay() {
    return display;
  }

  @Override
  public Position getPosition() {
    return null;
  }

  /**
   * Returns the configuration for labels on the numeric scale.
   *
   * @return the configuration for labels on the numeric scale
   */
  public TextSprite getScaleConfig() {
    return scaleConfig;
  }

  /**
   * Returns the {@link LabelProvider} used to display labels on the scale.
   *
   * @return the label provider used to display labels on the scale
   */
  public LabelProvider<Number> getScaleLabelProvider() {
    return scaleLabelProvider;
  }

  /**
   * Returns the steps of the axis.
   *
   * @return the steps of the axis
   */
  public int getSteps() {
    return radialSteps;
  }

  /**
   * Sets the {@link ValueProvider} used to get the values for the category
   * labels.
   *
   * @param categoryField the value provider used to get the values for the
   *          category labels
   */
  public void setCategoryField(ValueProvider<? super M, V> categoryField) {
    this.categoryField = categoryField;
  }

  /**
   * Sets the configuration for the circles on the axis.
   *
   * @param circleConfig the configuration for the circles on the axis
   */
  public void setCircleConfig(CircleSprite circleConfig) {
    if (this.circleConfig != circleConfig) {
      this.circleConfig = circleConfig;
      circles.clear();
    }
  }

  /**
   * Sets the {@link Display} style of the axis.
   *
   * @param display the display style of the axis
   */
  public void setDisplay(Display display) {
    this.display = display;
  }

  /**
   * Sets the configuration for labels on the numeric scale.
   *
   * @param scaleConfig the configuration for labels on the numeric scale
   */
  public void setScaleConfig(TextSprite scaleConfig) {
    if (this.scaleConfig != scaleConfig) {
      this.scaleConfig = scaleConfig;
      scales.clear();
    }
  }

  /**
   * Sets the {@link LabelProvider} used to display labels on the scale.
   *
   * @param scaleLabelProvider the label provider used to display labels on the
   *          scale
   */
  public void setScaleLabelProvider(LabelProvider<Number> scaleLabelProvider) {
    this.scaleLabelProvider = scaleLabelProvider;
  }

  /**
   * Sets the number of steps on the axis.
   *
   * @param steps the number of steps on the axis
   */
  public void setSteps(int steps) {
    radialSteps = steps;
  }

}
TOP

Related Classes of com.sencha.gxt.chart.client.chart.axis.RadialAxis

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.