Nateo Tutorial: Huge Data Sets


 

In the recent tutorials we created our small amounts of demo data during runtime. And also the display definitions like colors, display modes and row assignments were hard coded.
In a professional application you will load the data from files or from a data base. And the definition of the display will also be stored in kind of a configuration file or database so it can be modified by administrators rather than programmers.
 
In this tutorial we will now load a huge amount of data from a file into a Time Chart that has been set up from configuration files. Once the Time Chart and aligning controls are created, the startup is done in three phases:
 

  1. Create the Display Definitions (stored in NtDisplayDef objects) and the Row Headers (stored in NtRowHeaders).
  2. Define the row set and categories by setting up a NtPerspective.
  3. Load the data from the data source into NtDataObjects and put them into the NtTimeChartControl.


1. Create a Windows Form Application and add the Controls
 
For this tutorial we need a Time Chart with two Flank Controls as shown in the tutorial Row Headers and Flank Controls. So please create a Form like done there (but without the horizontal scroll bars for the Flank Controls). It will look like this:
 

 


2. Add a NtApplication interface implementation as a seperate class to your solution
 
Next step is to implement the NtApplication interface. It makes sense to create a new class in a seperate file 'MyNtApplication.cs':
 

public class MyNtApplication : NtApplication
{
public string bitmapDirectory = "";
public SortedDictionary iconDict = new SortedDictionary();
public Dictionary bitmapDict = new Dictionary();

public string NtGetText(NtDataObject ntDo) { return (string)ntDo.dataItem; }
public double NtGetDouble(NtDataObject ntDo)
{
if (ntDo.dataItem is double) return (double)ntDo.dataItem;
double d;
if (double.TryParse(ntDo.dataItem.ToString(), out d)) return d;
return 0;
}
public Bitmap NtGetIcon(NtDataObject ntDo) { Bitmap b; iconDict.TryGetValue((string)ntDo.dataItem, out b); return b; }
public Bitmap NtGetBitmap(NtDataObject ntDo)
{
Bitmap bitmap;
if (!bitmapDict.TryGetValue((string)ntDo.dataItem, out bitmap)) { bitmap = new Bitmap(bitmapDirectory + (string)ntDo.dataItem); bitmapDict.Add((string)ntDo.dataItem, bitmap); }
return bitmap;
}
public bool NtIsHoliday(DateTime dt) { return false; }
public bool NtIsWeekend(DateTime dt) { return false; }
public string NtGetTooltipText(NtDisplayObject tooltipDisplayObject, int ttType) { return tooltipDisplayObject.DataObject.dataItem.ToString(); }
}


3. Add member fields to the Form class
 
To your form please add the following private members:
 

List<NtDisplayDef> displayDefs;
List<NtDataObject> dataObjects;
NtPerspective perspective;
MyNtApplication myNtApplication = new MyNtApplication();


4. Initialize the Time Chart in your Load() method
 
Please let the Load() member function for initialization look like this (please note that in the ScrollToDt() call we jump to a certain point of time in November 2016, because there is a time phase with lots of data):
 

private void Form1_Load(object sender, EventArgs e)
{
ntTimeChartControl.SetNtApplication(myNtApplication);
ntTimeChartControl.Init(10 * 24, 90, TimeDisplayMode.hours);
ntTimeChartControl.SetScrollBars(ntTimeChartControlHScrollBar, ntTimeChartControlVScrollBar);
 
ntHeaderControl.Init(ntTimeChartControl, Font, Font, false);
ntLeftFlankControl.Init(ntTimeChartControl, null, ntLeftFlankControl.ClientSize.Width);
ntRightFlankControl.Init(ntTimeChartControl, null, ntLeftFlankControl.ClientSize.Width);
 
ntBackPanel.SetPadding(2, 2, 2, 2);
ntBackPanel.Repos(ntLeftFlankControl, ntTimeChartControl, ntTimeChartControlHScrollBar, ntTimeChartControlVScrollBar);
 
ntTimeChartControl.ScrollToDt(new DateTime(2016,11,15,12,0,0).ToUniversalTime(), ntTimeChartControl.ClientSize.Width / 2, 0);
ntTimeChartControl.Focus();
}


5. Add a class for reading the data and configuration files
 
The code of this tutorial can be found in the 'Tutorials' folder of this tutorial package. There you will find the file 'TutorialData.cs' that contains the class for reading the demo data files provided for this tutorial. The class simply reads those files and creates Lists of NtDisplayDefs or Lists of NtDataObjects from tabular files and can also read NtPerspective Objects from tabular files. Please simply include this class to your project and take a look into the code. It is pretty straight forward.


6. Load Display Definitions, Perspective and Data from files
 
We will now call the member functions of the TutorialData class to perform the following tasks:
 

So at the end of your Form1_Load() method, please append:
 

//Load SampleData
Graphics g = CreateGraphics();
string workingDirectory = "..\\..\\..\\..\\..\\DemoData\\"; //adapt this accordingly to the path where the 'data' directory is located
myNtApplication.bitmapDirectory = workingDirectory + "images\\";

TutorialData.LoadIconsFromDir(myNtApplication.iconDict, workingDirectory + "icons\\", g);
if (myNtApplication.iconDict.Count == 0) MessageBox.Show("Error: No icons found!");
displayDefs = TutorialData.LoadDisplayDefsFromFile(workingDirectory + "displayDefs.txt");
perspective = TutorialData.LoadPerspectiveFromFile(workingDirectory + "perspective_05.txt");
dataObjects = TutorialData.LoadDataObjectsFromFile(workingDirectory + "dataObjects.txt");


 
7. Set up the Time Chart and add the Data
 
In this final step we will apply the configuration data we loaded to the NtTimeChartControl and then insert the data. To the end of your Form1_Load() method, please append:
 

//Put Display Definitions and Row Headers to Time Chart
for (int i = 0; i < displayDefs.Count; ++i)
{
NtDisplayDef dd = displayDefs[i];
ntTimeChartControl.SetDisplayDef(dd);
NtRowHeader rh = new NtRowHeader();
rh.InitRowHeaderText(dd.rowHeaderStr, Font, dd.textBrush, dd.bkBrush, g);
ntTimeChartControl.SetRowHeader(dd.dataTypeId, rh);
}

//Put the data to the Time Chart and set the current Perspective
ntTimeChartControl.SetNtPerspective(perspective);
ntTimeChartControl.SetData(dataObjects);


 
Testing
 
Starting the application you should see the following:
 

 
Again please note that the tutorial data has some time areas with lots of data (always in November in the years 2007 to 2017), so we jump to November 2016 after launch.
 
So these are the conclusions from this tutorial:

  1. Configuration of how certain data types shall look like, and what the names and settings of the Row Headers are, should not be hard coded. They should be taken from configuration data bases or files.
  2. A common mechanism for loading data makes sense for all kind of data, no matter how it will then be displayed. Storage always takes place in NtDataObject instances or subclasses.
  3. The NtDisplayDefs define how a certain data type looks like. The NtPerspective defines the assignment of data types to rows. For example you will find a few rows that have two data types assigned and thereby have a Row Header placed in the right Flank Control.


 
Outlook
 
When taking a look into the 'displayDefs.txt' file (directory 'data') you will find a simple table with several columns:
 
DataTypeId, DisplayMode, RowHeight, IconWidth, BackgroundColor, ForegroundColor, TextColor, LineMaxSeconds, LineType, RowHeaderString
 
This information does not cover all fields of a NtDisplayDef. E.g. there is no info on the CrosshairType, TooltipType and others. Further more you might want to store other information for your own purposes that come along with the various data types. In these cases it makes sense to use another format for the table and most of all it might be reasonable to create your own subclass of NtDisplayDef in order to store the information you need for your purposes.



Back to Overview