Adding x values and y values as separate series 1.0.13
Adding x values and y values as separate series 1.0.13
Is it possible to create a series with only 1 parameter, as in one list of numbers for use in either xy series or time series. Right now to plot a series I add data to to a xy series with .add(x, y) where x and y are the x and y values to be plotted. I would like to know if you can create a series with just 1 parameter, and create say series A series B with an add function with just 1 value like .add(value) so that when you choose to create the graph you can select which series you would like to plot as the x (say series A) values against another (say series B) as the y values. I've looked at the api and in xy series and time series you can create you can only add data points with two values. However I am asking if anyone knows any way around this. The reason why I am asking this is that when I read in the data for the time series/xy series graphs I do not know which values will be the x and y values because the user should be able to select which tracks of data to plot as the x and y values. Now, I can read in the data first, storing it into my own data structures ( which takes approximately 5 - 10 seconds depending on the size of the data ) and then when the user selects which tracks to plot, add the data from my own data structure into the series object in jfreechart in a big for loop. However, adding the values into the series objects take just about as much time as it takes to load the data in originally, which is why I would like to store the data into the series objects as soon as I read the data instead of into my own data structure, and then when the user wants a graph the graphing will almost be instant, that way the user only ever has to wait while loading a file. However, since the add function in series only accepts two values, one of which I do not know which one of the data tracks to load into yet, this is not possible for me. That is why I would like series with only 1 value (or a solution like this), so I can quickly plot the graphs after I get the data and only wait once for the data to load. If anything is unclear feel free to say so and I will explain. I did not post any pictures or example code because neither are relevant to my question.
-
- JFreeChart Project Leader
- Posts: 11734
- Joined: Fri Mar 14, 2003 10:29 am
- antibot: No, of course not.
- Contact:
Re: Adding x values and y values as separate series 1.0.13
Stick with your own data structure, but wrap it in your own class that implements the XYDataset interface. Your class should have a flag that determines whether the first or second series is used as the x-values (and then obviously the other series is used for the y-values).
David Gilbert
JFreeChart Project Leader
Read my blog
Support JFree via the Github sponsorship program
JFreeChart Project Leader


Re: Adding x values and y values as separate series 1.0.13
This sounds like a sound solution, I will try to use this method. Thanks for the fast reply!
Re: Adding x values and y values as separate series 1.0.13
For those interested I'll post what I have so far:
The implemented XYDataset:
My data structure used:
I also have concerns about real-time large-dataset: I have tried using large datasets and real-time, the real-time seems to work fine with version 1.0.13, large data sets still load slow when first loading data but plots almost instantly after all the data is loaded, even when adding data the refresh is almost instant (I guess you guys have incorporated a lot of the fast classes discussed in the mentioned thread, also I saw references to fast classes in the 1.0.13 api). My concern is If I use my own version of an implemented XYDataset will this affect the real-time large-dataset abilities of JFreeChart? Is it okay to keep notifyAll() in my method which adds new data to the dataset? Thanks for reading, comments welcome.
The implemented XYDataset:
Code: Select all
import java.util.Vector;
import org.jfree.data.DomainOrder;
import org.jfree.data.general.DatasetChangeListener;
import org.jfree.data.general.DatasetGroup;
import org.jfree.data.xy.XYDataset;
/**
* Holds all of the information read from a raw file and interfaced with JFreeChart.
* Implements methods from XYDataset interface, which specify how to get x and y-values and the
* size of such collections. Holds all of the data read from a raw file in the "data" field
* and the y-values to be plotted in the "yValues" vector and the x-values in the "xValues" field.
* Changing or adding values should change the graph through observer pattern.
* @author
* @since June 24, 2009
*/
public class MyDataset implements XYDataset{
/**
* The total set of data.
* Not for giving JFreeChart for plotting but just for storing.
*/
private Vector<DataTrack> data;
/**
* The list of DataTrack objects to be plotted as y-values.
* To be given to JFreeChart to be plotted.
*/
private Vector<DataTrack> yValues;
/**
* The DataTrack representing the list of numbers to be plotted as
* the x values.
*/
private DataTrack xValues;
/**
* Constructor.
*/
public MyDataset(){
data = new Vector<DataTrack>();
yValues = new Vector<DataTrack>();
xValues = null;
}
/**
* Adds a new data track with given name.
* @param name The name of the track to be added.
*/
public void addTrack(String name){
data.add(new DataTrack(name));
}
/**
* Returns the domain order.
* @return The order.
*/
public DomainOrder getDomainOrder() {
// TODO Auto-generated method stub
return null;
}
/**
* Returns the item count for a selected series.
* @param series The series selected.
* @return The item count for a series. Returns 0 if the series index is wrong.
*/
public int getItemCount(int series) {
if(series < 0 || series > yValues.size()) return 0;
return yValues.get(series).getSize();
}
/**
* Adds a data value to selected parameter track.
* Example: add(2, 10.54) adds the value 10.54 to the 2nd data track.
* @param index The index.
* @param value The value to be added.
* @return True if successfully added.
* False, if the index given was out of bounds.
*/
public boolean add(int index, Float value){
if(index < 0 || index > data.size()){
return false;
}
data.get(index).add(value);
notifyAll();
return true;
}
/**
* Returns the name of a data track.
* @param index The index.
* @return The name of the data track.
* Null if the index doesn't exist.
*/
public String getName(int index){
if(index < 0 || index > data.size()){
System.err.println("DataBuffer.getName(int index): index out of bounds.");
return null;
}
return data.get(index).getName();
}
/**
* Returns the size of the parameter data track selected.
* @param index The index of the vector of DataTrack objects.
* @return The size of the DataTrack.
* Returns -1 if the index does not exist.
*/
public int getSize(int index){
if(index < 0 || index > data.size()) return -1;
return data.get(index).getSize();
}
/**
* Sets which of the data tracks to plot as the x-values.
* @param index The index.
* @return True if successfully set a track as the x-values.
* False if index does not exist.
*/
public boolean setXValues(int index){
if(index < 0 || index > data.size()) return false;
xValues = data.get(index);
notifyAll();
return true;
}
/**
* Sets which data tracks to plot as the y-values.
* @param index The index.
* @return True if successfully set a track to plot.
* False if index does not exist.
*/
public boolean setToPlot(int index){
if(index < 0 || index > data.size()) return false;
yValues.add(data.get(index));
notifyAll();
return true;
}
/**
* Returns the number of data tracks.
* @return Number of data tracks.
*/
public int getSize(){
return data.size();
}
/**
* Returns the x-value.
* @param series Not used since the y-values will be the same for all tracks.
* @param index I'm assuming this index means the index through the list of x-values.
* JFreeChart documentation calls this "item".
* @return The x-value. Returns 0 if there is nothing to return yet.
*/
public Number getX(int series, int index) {
if(xValues == null) return null;
return xValues.get(index);
}
/**
* Returns the y-value as a double primitive.
* @param series I assume this is the index of one of the multiple series a XYDataset can hold.
* @param index I assume this is the index for the list of y-values for a series in XYDataset.
* JFreeChart documentation calls this "item".
* @return The y-value. Return 0 if the index is incorrect.
*/
public double getXValue(int series, int index) {
if(xValues == null) return 0;
return xValues.get(index);
}
/**
* Returns the y-value.
* @param series I assume this is the index of one of the multiple series a XYDataset can hold.
* @param index I assume this is the index for the list of y-values for a series in XYDataset.
* JFreeChart documentation calls this "item".
* @return The y-value. Return 0 if the index is incorrect.
*/
public Number getY(int series, int index) {
if(index < 0 || index > yValues.size()) return 0;
return yValues.get(series).get(index);
}
/**
* Returns the y-value as a double primitive.
* @param series I assume this is the index of one of the multiple series a XYDataset can hold.
* @param index I assume this is the index for the list of y-values for a series in XYDataset.
* JFreeChart documentation calls this "item".
* @return The y-value. Return 0 if the index is incorrect.
*/
public double getYValue(int series, int index) {
if(index < 0 || index > yValues.size()) return 0;
return yValues.get(series).get(index);
}
/**
* Returns the number of series in the dataset or in this case the
* number of data tracks that are set to be plotted.
*/
public int getSeriesCount() {
return yValues.size();
}
public Comparable getSeriesKey(int arg0) {
// TODO Auto-generated method stub
return null;
}
public int indexOf(Comparable arg0) {
// TODO Auto-generated method stub
return 0;
}
public void addChangeListener(DatasetChangeListener arg0) {
// TODO Auto-generated method stub
}
public DatasetGroup getGroup() {
// TODO Auto-generated method stub
return null;
}
public void removeChangeListener(DatasetChangeListener arg0) {
// TODO Auto-generated method stub
}
public void setGroup(DatasetGroup arg0) {
// TODO Auto-generated method stub
}
}
Code: Select all
import java.util.Vector;
/**
* A data track. Which is essentially a list of numbers with a name label so I know what these
* numbers represent.
* @autho
* @since June 24, 2009
*/
public class DataTrack {
/**
* The list of values the data track has. (example: 10.24, 23.09, 7.89 ...).
*/
private Vector<Float> values;
/**
* The name of the data track (example: "SysTime")
*/
private String name;
/**
* Constructor specifying the name of the data track.
* @param name The name of this track.
*/
public DataTrack(String name){
this.name = name;
values = new Vector<Float>();
}
/**
* Add a value to the track.
* @param value The value to add.
*/
public void add(Float value){
values.add(value);
}
/**
* Returns a value.
* @param index The index.
* @return The value.
*/
public Float get(int index){
return values.get(index);
}
/**
* Returns the size of the list of values.
* @return Number of values in the list.
*/
public int getSize(){
return values.size();
}
/**
* Returns the name.
* @return The name of this list of values.
*/
public String getName(){
return name;
}
}