Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-write Dataset and Series Storage Architecture #6

Open
iwbnwif opened this issue Apr 12, 2017 · 4 comments
Open

Re-write Dataset and Series Storage Architecture #6

iwbnwif opened this issue Apr 12, 2017 · 4 comments
Assignees
Milestone

Comments

@iwbnwif
Copy link
Owner

iwbnwif commented Apr 12, 2017

Bring wxFreeChart up to date to allow datasets to be generated from (and essentially be based on) wxList and wxVector classes.

There is already a VectorDataset, but this does not seem to offer much functionality over and above a normal XYDataset.

@iwbnwif iwbnwif added this to the 2.0 milestone Apr 18, 2017
@iwbnwif iwbnwif self-assigned this Apr 18, 2017
@iwbnwif
Copy link
Owner Author

iwbnwif commented May 5, 2017

This comment is a placeholder for ideas.

The current structure of Plots, Datasets and Series is very intuitive and should be kept.

The Plot should determine the overall presentation of the chart, e.g. one of:

  • Bar (vertical or horizontal)
  • Bubble
  • Gantt
  • Scatter (XY)
  • Stock (OHLC)
  • Pie

The Dataset is a container for the Series. Certain plots can only accept certain types of Dataset, and certain Datasets can only contain certain types of Series.

The capability of the Plot, Dataset and Series is identified by a wxStringList. There has to be a match between the capabilty and the contained item content for it to be accepted.

@iwbnwif
Copy link
Owner Author

iwbnwif commented May 6, 2017

Some more thoughts on this.

class DataPoint; // Base class
HasData, SetHasData
GetComment, SetComment
bool HasData m_hasData;
wxString m_comment;

class UniDataPoint : public DataPoint
// Hide data with getters and setters?
// Is it okay to implement directly at this level or follow the current schema 
// of an abstract class followed by a 'simple' implementation?
wxAny point;

class BiDataPoint : public DataPoint
wxAny first;
wxAny second;

class NaryDataPoint : public DataPoint
wxVector<wxAny>point;

class DataSeries; // Base class
wxString name;
wxStringList capability;

class UniDataSeries : public DataSeries
wxVector<UniDataPoint> data;

class BiDataSeries : public DataSeries
wxVector<BiDataPoint> data;

class NaryDataSeries : public DataSeries
wxVector<nAryDataPoint> data;

class Dataset;

class UniDataset : public Dataset
UniDataSeries m_categories;
wxVector<UniDataSeries> m_series;

class BiDataset : public Dataset
wxVector<BiDataSeries> m_series;

class NaryDataset : public Dataset
wxVector<NaryDataSeries> m_series;




@iwbnwif
Copy link
Owner Author

iwbnwif commented May 8, 2017

Further quick notes:

  1. Essentially this architecture uses wxAny to implement the templates. It could also be done directly using templates
  2. Add some generic data access method(s) in the base class, e.g. const wxAny& GetDimensionValue(dimension)
  3. wxAny is used at 2 levels. Firstly as the data store for the actual data points. This allows data points to contain dates, numbers, text etc. Secondly it is used to provide the templating for data series.
  4. Have direct / generic access via the base DataSet class.
  5. The specialised xDataSet classes are convenience wrappers to provide some readily understandable methods. Ultimately, the same can be achieved in a less intuitive way by the generic access methods.

@iwbnwif iwbnwif changed the title Allow datasets to be populated by wxLists and wxVectors Re-write Dataset and Series Storage Architecture May 8, 2017
@iwbnwif
Copy link
Owner Author

iwbnwif commented May 18, 2017

Further quick notes:

  1. All data is now stored as wxAny
  2. A new 'interpretation' layer has been introduced to provide abstraction between the stored data and how it is plotted (see further details below).

Notes on Interpretation Layer

Data is stored in data points, data series and data sets. A data point contains a number of dimensions (which could be considered as X, Y, Z etc. but not necessarily).

Interpretation does 2 things:

  1. It allows conversion between the user data format and some generic C++ / wxWidgets data types. For example, user data may be stored as Julian Date Numbers, a real number represented by a double. However, a date axis requires wxDateTime objects, so the interpretation layer interprets the double as a wxDateTime
  2. It allows any wxAny data object to be interpreted as a double value for plotting on a 2-dimensional screen. Plotting needs ordinal information for some charts (i.e. bar categories) and rational information for others (i.e. X-Y plots). For example, a wxDateTime object consists of hours, minutes, seconds etc. but can be interpreted as rational 'ticks' for plotting.

This interpretation layer works well, but it appears to be slow for a large number of points within a data set. I think this is because of the wxAny conversion which takes place multiple times for each data point on each plot refresh (i.e. establishing bounds, drawing axis, plotting the actual data).

The solution is to cache the interpreted values as they are stored rather than on the fly. This means the interpretation penalty is incurred once during storage rather than potentially tens (or millions in the case of dynamic data) of times during plotting. Although this causes a modest increase in storage requirements, it should not have any noticeable impact on a modern system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant