package com.positive.charts.data.general;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import com.positive.charts.common.SortOrder;
import com.positive.charts.common.UnknownKeyException;
import com.positive.charts.data.DefaultKeyedValues;
import com.positive.charts.data.KeyedValues;
import com.positive.charts.event.DatasetChangeEvent;
/**
* A default implementation of the {@link PieDataset} interface.
*/
public class DefaultPieDataset extends AbstractDataset implements PieDataset,
Serializable {
/** For serialization. */
private static final long serialVersionUID = 2904745139106540618L;
/** Storage for the data. */
private DefaultKeyedValues data;
/**
* Constructs a new dataset, initially empty.
*/
public DefaultPieDataset() {
this.data = new DefaultKeyedValues();
}
/**
* Creates a new dataset by copying data from a {@link KeyedValues}
* instance.
*
* @param data
* the data (<code>null</code> not permitted).
*/
public DefaultPieDataset(final KeyedValues data) {
if (data == null) {
throw new IllegalArgumentException("Null 'data' argument.");
}
this.data = new DefaultKeyedValues();
for (int i = 0; i < data.getItemCount(); i++) {
this.data.addValue(data.getKey(i), data.getValue(i));
}
}
/**
* Clears all data from this dataset and sends a {@link DatasetChangeEvent}
* to all registered listeners (unless the dataset was already empty).
*
* @since 1.0.2
*/
public void clear() {
if (this.getItemCount() > 0) {
this.data.clear();
this.fireDatasetChanged();
}
}
/**
* Returns a clone of the dataset.
*
* @return A clone.
*
* @throws CloneNotSupportedException
* This class will not throw this exception, but subclasses (if
* any) might.
*/
public Object clone() throws CloneNotSupportedException {
final DefaultPieDataset clone = (DefaultPieDataset) super.clone();
clone.data = (DefaultKeyedValues) this.data.clone();
return clone;
}
/**
* Tests if this object is equal to another.
*
* @param obj
* the other object.
*
* @return A boolean.
*/
public boolean equals(final Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof PieDataset)) {
return false;
}
final PieDataset that = (PieDataset) obj;
final int count = this.getItemCount();
if (that.getItemCount() != count) {
return false;
}
for (int i = 0; i < count; i++) {
final Comparable k1 = this.getKey(i);
final Comparable k2 = that.getKey(i);
if (!k1.equals(k2)) {
return false;
}
final Number v1 = this.getValue(i);
final Number v2 = that.getValue(i);
if (v1 == null) {
if (v2 != null) {
return false;
}
} else {
if (!v1.equals(v2)) {
return false;
}
}
}
return true;
}
/**
* Returns the index for a key, or -1 if the key is not recognised.
*
* @param key
* the key (<code>null</code> not permitted).
*
* @return The index, or <code>-1</code> if the key is unrecognised.
*
* @throws IllegalArgumentException
* if <code>key</code> is <code>null</code>.
*/
public int getIndex(final Comparable key) {
return this.data.getIndex(key);
}
/**
* Returns the number of items in the dataset.
*
* @return The item count.
*/
public int getItemCount() {
return this.data.getItemCount();
}
/**
* Returns the key for the specified item, or <code>null</code>.
*
* @param item
* the item index (in the range <code>0</code> to
* <code>getItemCount() - 1</code>).
*
* @return The key, or <code>null</code>.
*
* @throws IndexOutOfBoundsException
* if <code>item</code> is not in the specified range.
*/
public Comparable getKey(final int item) {
return this.data.getKey(item);
}
/**
* Returns the categories in the dataset. The returned list is unmodifiable.
*
* @return The categories in the dataset.
*/
public List getKeys() {
return Collections.unmodifiableList(this.data.getKeys());
}
/**
* Returns the data value associated with a key.
*
* @param key
* the key (<code>null</code> not permitted).
*
* @return The value (possibly <code>null</code>).
*
* @throws UnknownKeyException
* if the key is not recognised.
*/
public Number getValue(final Comparable key) {
if (key == null) {
throw new IllegalArgumentException("Null 'key' argument.");
}
return this.data.getValue(key);
}
/**
* Returns a value.
*
* @param item
* the value index.
*
* @return The value (possibly <code>null</code>).
*/
public Number getValue(final int item) {
Number result = null;
if (this.getItemCount() > item) {
result = this.data.getValue(item);
}
return result;
}
/**
* Returns a hash code.
*
* @return A hash code.
*/
public int hashCode() {
return this.data.hashCode();
}
/**
* Removes an item from the dataset and sends a {@link DatasetChangeEvent}
* to all registered listeners.
*
* @param key
* the key (<code>null</code> not permitted).
*
* @throws IllegalArgumentException
* if <code>key</code> is <code>null</code>.
*/
public void remove(final Comparable key) {
this.data.removeValue(key);
this.fireDatasetChanged();
}
/**
* Sets the data value for a key and sends a {@link DatasetChangeEvent} to
* all registered listeners.
*
* @param key
* the key (<code>null</code> not permitted).
* @param value
* the value.
*
* @throws IllegalArgumentException
* if <code>key</code> is <code>null</code>.
*/
public void setValue(final Comparable key, final double value) {
this.setValue(key, new Double(value));
}
/**
* Sets the data value for a key and sends a {@link DatasetChangeEvent} to
* all registered listeners.
*
* @param key
* the key (<code>null</code> not permitted).
* @param value
* the value.
*
* @throws IllegalArgumentException
* if <code>key</code> is <code>null</code>.
*/
public void setValue(final Comparable key, final Number value) {
this.data.setValue(key, value);
this.fireDatasetChanged();
}
/**
* Sorts the dataset's items by key and sends a {@link DatasetChangeEvent}
* to all registered listeners.
*
* @param order
* the sort order (<code>null</code> not permitted).
*
* @since 1.0.3
*/
public void sortByKeys(final SortOrder order) {
this.data.sortByKeys(order);
this.fireDatasetChanged();
}
/**
* Sorts the dataset's items by value and sends a {@link DatasetChangeEvent}
* to all registered listeners.
*
* @param order
* the sort order (<code>null</code> not permitted).
*
* @since 1.0.3
*/
public void sortByValues(final SortOrder order) {
this.data.sortByValues(order);
this.fireDatasetChanged();
}
}