/* DialModelScale.java Purpose: Description: History: Jun 24, 2009 5:21:08 PM, Created by henrichen Copyright (C) 2009 Potix Corporation. All Rights Reserved. {{IS_RIGHT This program is distributed under LGPL Version 2.0 in the hope that it will be useful, but WITHOUT ANY WARRANTY. }}IS_RIGHT */ package org.zkoss.zul; import java.awt.Font; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.zkoss.lang.Objects; import org.zkoss.zul.event.ChartDataEvent; import org.zkoss.zul.event.DialChartDataEvent; /** * A set of information of a scale in a Dial chart. You cannot new a DialModelScale * directly; instead, use {@link DialModel#newScale()} to start setting the scale. * @author henrichen * */ public class DialModelScale implements Serializable { private DialModel _model; //data private double _value; //text annotation private String _text; private Font _textFont; //14, 10 private double _textRadius = 0.7; //0.7, 0.5 //value indicator private Font _valueFont; //10, 10 private double _valueRadius = 0.6; //0.6, 0.6 private double _valueAngle = -90; //-103.0, -77.0 //tick private Font _tickFont; //14, 10 private double _tickRadius = 0.88; //0.88, 0.50 private String _tickColor; //tick, 0xFF0000 private int[] _tickRGB; //tick, red, green, blue (0 ~ 255, 0 ~ 255, 0 ~ 255) private double _tickLabelOffset = 0.20; //offset between tick and tick label //scale double _lowerBound; double _upperBound; double _startAngle; double _extent; double _majorTickInterval; int _minorTickCount; //ranges private List<DialModelRange> _ranges = new ArrayList<DialModelRange>(4); //needle private String _needleType = "pointer"; //"pointer", "pin" private String _needleColor; //needle, 0xFF0000 private int[] _needleRGB; //needle, red, green, blue (0 ~ 255, 0 ~ 255, 0 ~ 255) private double _needleRadius = 0.9; //0.9, 0.55 /*package*/ DialModelScale(DialModel model) { _model = model; } public int getIndex() { return _model.indexOf(this); } /** Get the value */ public double getValue() { return _value; } public void setValue(double val) { if (Double.compare(_value, val) != 0) { _value = val; fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.SCALE_VALUE, val); } } /** * Returns the text annotation of this scale. */ public String getText() { return _text; } /** * Sets the text annotation of this scale; e.g. "Temperature" for a temperature dial meter. * @param text text annotation(subtitle) of this scale. */ public void setText(String text) { if (!Objects.equals(text, _text)) { _text = text; fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.SCALE_TEXT, text); } } /** * Returns the text annotation font. * @return the text annotation font. */ public Font getTextFont() { return _textFont; } /** * Sets the text annotation font. * @param font the text annotation font. */ public void setTextFont(Font font) { if (!Objects.equals(font, _textFont)) { _textFont = font; fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.SCALE_FONT, font); } } /** * Return the radius percentage(0 ~ 1) to place the text annotation. * @return the radius percentage(0 ~ 1) to place the text annotation. */ public double getTextRadius() { return _textRadius; } /** * Sets the radius percentage(0 ~ 1) to place the text annotation. * @param radius radius percentage(0 ~ 1) to place the text annotation. */ public void setTextRadius(double radius) { if (Double.compare(_textRadius, radius) != 0) { _textRadius = radius; fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.TEXT_RADIUS, radius); } } /** * Returns the value font. * @return the value font. */ public Font getValueFont() { return _valueFont; } /** * Sets the value font. * @param font the value font. */ public void setValueFont(Font font) { if (!Objects.equals(font, _valueFont)) { _valueFont = font; fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.VALUE_FONT, font); } } /** * Return the radius percentage(0 ~ 1) to place the value. * @return the radius percentage(0 ~ 1) to place the value. */ public double getValueRadius() { return _valueRadius; } /** * Sets the radius percentage(0 ~ 1) to place the value. * @param radius radius percentage(0 ~ 1) to place the value. */ public void setValueRadius(double radius) { if (Double.compare(_valueRadius, radius) != 0) { _valueRadius = radius; fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.VALUE_RADIUS, radius); } } /** * Return the angle to place the value (counter clockwise is positive). * @return the angle to place the value (counter clockwise is positive). */ public double getValueAngle() { return _valueAngle; } /** * Sets the angle in degree to place the value (counter clockwise is positive). * @param angle angle in degree to place the value (counter clockwise is positive). */ public void setValueAngle(double angle) { if (Double.compare(_valueAngle, angle) != 0) { _valueAngle = angle; fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.VALUE_ANGLE, angle); } } /** * Sets the scale information of this DialModelScale. * @param lowerBound lower bound of this scale. * @param upperBound upper bound of this scale. * @param startAngle starting angle in degree associated to the sclae's lower bound(0 degree point to east, counter-clockwise is positive). * @param extent angles in degree extended from the starting angle (counter clockwise is positive). * @param majorTickInterval the interval between major tick (in lower bound and upper bound). * @param minorTickCount the number of minor ticks between major tick. */ public void setScale(double lowerBound, double upperBound, double startAngle, double extent, double majorTickInterval, int minorTickCount) { if (Double.compare(lowerBound, _lowerBound) != 0 || Double.compare(upperBound, _upperBound) != 0 || Double.compare(startAngle, _startAngle) != 0 || Double.compare(extent, _extent) != 0 || Double.compare(majorTickInterval, _majorTickInterval) != 0 || Double.compare(minorTickCount, _minorTickCount) != 0) { _lowerBound = lowerBound; _upperBound = upperBound; _startAngle = startAngle; _extent = extent; _majorTickInterval = majorTickInterval; _minorTickCount = minorTickCount; fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.SCALE, this); } } /** * Returns the scale's lower bound. * @return the scale's lower bound. */ public double getScaleLowerBound() { return _lowerBound; } /** * Returns the scale's upper bound. * @return the scale's upper bound. */ public double getScaleUpperBound() { return _upperBound; } /** * Returns starting angle in degree associated to the sclae's lower bound * (0 degree point to east, counter-clockwise is positive). * @return starting angle in degree associated to the sclae's lower bound * (0 degree point to east, counter-clockwise is positive). */ public double getScaleStartAngle() { return _startAngle; } /** * Returns angles in degree extended from the starting angle (counter clockwise is positive). * @return angles in degree extended from the starting angle (counter clockwise is positive). */ public double getScaleExtent() { return _extent; } /** * Returns the interval between major tick (in lower bound and upper bound). * @return the interval between major tick (in lower bound and upper bound). */ public double getMajorTickInterval() { return _majorTickInterval; } /** * returns the number of minor ticks between major tick. * @return the number of minor ticks between major tick. */ public int getMinorTickCount() { return _minorTickCount; } /** * Returns the tick label font. * @return the tick label font. */ public Font getTickFont() { return _tickFont; } /** * Sets the tick label font. * @param font the tick label font. */ public void setTickFont(Font font) { if (!Objects.equals(font, _tickFont)) { _tickFont = font; fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.TICK_FONT, font); } } /** * Return the radius percentage(0 ~ 1) to place the tick label. * @return the radius percentage(0 ~ 1) to place the tick label. */ public double getTickRadius() { return _tickRadius; } /** * Sets the radius percentage(0 ~ 1) to place the tick label. * @param radius radius percentage(0 ~ 1) to place the tick label. */ public void setTickRadius(double radius) { if (Double.compare(_tickRadius, radius) != 0) { _tickRadius = radius; fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.TICK_RADIUS, radius); } } /** * Returns the radius offset in percentage(0 ~ 1) between the tick and tick label. * @return the radius offset in percentage(0 ~ 1) between the tick and tick label. */ public double getTickLabelOffset() { return _tickLabelOffset; } /** * Sets the radius offset in percentage(0 ~ 1) between the tick and tick label. * @param tickLabelOffset the radius offset in percentage(0 ~ 1) between the tick and tick label. */ public void setTickLabelOffset(double tickLabelOffset) { if (Double.compare(_tickLabelOffset, tickLabelOffset) != 0) { _tickLabelOffset = tickLabelOffset; fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.TICK_LABEL_OFFSET, tickLabelOffset); } } /** * Set the tick color. * @param color in #RRGGBB format (hexadecimal). */ public void setTickColor(String color) { if (Objects.equals(color, _tickColor)) { return; } _tickColor = color; if (_tickColor == null) { _tickRGB = null; } else { _tickRGB = new int[3]; Chart.decode(_tickColor, _tickRGB); } fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.TICK_COLOR, color); } /** * Get the tick color of this scale(in string as #RRGGBB). * null means default. */ public String getTickColor() { return _tickColor; } /** * Get the tick color of this scale in int array (0: red, 1: green, 2:blue). * null means default. */ public int[] getTickRGB() { return _tickRGB; } /** * Setup the DailModel range. * @param lower the lower bound in the scale. * @param upper the upper bound in the scale. * @param color the color in #RRGGBB format (hexadecimal); default to blue. * @param innerRadius the inner radius percentage(0 ~ 1) of the range; default to 0.7. * @param outerRadius the outer radius percentage(0 ~ 1) of the range; default to 0.8; */ public DialModelRange newRange(double lower, double upper, String color, double innerRadius, double outerRadius) { final DialModelRange range = new DialModelRange(this); range.setRange(lower, upper, color, innerRadius, outerRadius); _ranges.add(range); fireEvent(ChartDataEvent.ADDED, DialChartDataEvent.RANGE, range); return range; } /** Returns the number of ranges associated with this scale. * * @return the number of ranges associated with this scale. */ public int rangeSize() { return _ranges.size(); } /** Returns the color range of the specified index. * * @param index the specified index. * @return the color range of the specified index. */ public DialModelRange getRange(int index) { return _ranges.get(index); } /** * Removes the specified range from this scale. * @param range the range to be removed. */ public void removeRange(DialModelRange range) { int index = _ranges.indexOf(range); _ranges.remove(range); fireEvent(ChartDataEvent.REMOVED, DialChartDataEvent.RANGE, index); } /** * Returns the needle type of this scale ("pointer" or "pin") * @return the needle type of this scale ("pointer" or "pin") */ public String getNeedleType() { return _needleType; } /** * Sets the needle type of this scale ("pointer" or "pin") * @param type the needle type of this scale ("pointer" or "pin") */ public void setNeedleType(String type) { if (!Objects.equals(_needleType, type)) { _needleType = type; fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.NEEDLE_TYPE, type); } } /** * Set the needle color. * @param color in #RRGGBB format (hexadecimal). */ public void setNeedleColor(String color) { if (Objects.equals(color, _needleColor)) { return; } _needleColor = color; if (_needleColor == null) { _needleRGB = null; } else { _needleRGB = new int[3]; Chart.decode(_needleColor, _needleRGB); } fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.NEEDLE_COLOR, color); } /** * Get the needle color of this scale(in string as #RRGGBB). * null means default. */ public String getNeedleColor() { return _needleColor; } /** * Get the needle color of this scale in int array (0: red, 1: green, 2:blue). * null means default. */ public int[] getNeedleRGB() { return _needleRGB; } /** * Sets the radius percentage(0 ~ 1) of the scale's needle; default to 0.9. * @param radius the radius percentage(0 ~ 1) of the scale's needle; default to 0.9. */ public void setNeedleRadius(double radius) { if (Double.compare(_needleRadius, radius) != 0) { _needleRadius = radius; fireEvent(ChartDataEvent.CHANGED, DialChartDataEvent.NEEDLE_RADIUS, radius); } } /** * Return the radius percentage(0 ~ 1) of the scale's needle; default to 0.9. * @return the radius percentage(0 ~ 1) of the scale's needle; default to 0.9. */ public double getNeedleRadius() { return _needleRadius; } /** * Utility method to delegate event to {@link DialModel} * @param evt the {@link ChartDataEvent}. */ /*package*/ void fireEvent(int evt, String propertyKey, Object data) { if (_model != null) _model.fireEvent(evt, propertyKey, data); } }