Nateo Tutorials -> Bitmaps and Icons

# Nateo Tutorial: Bitmaps and Icons

The set of data items you store within the NtTimeChartControl can contain many objects. If you want to show them as bitmaps (or icons resp.) you can not keep one bitmap per data object in memory because this would overload your memory. There are two aspects that allow to reduce the memory consumption:

- Not all objects are visible at a time. You need to have only those bitmaps in memory that are either visible or can be made visible by scrolling left to right in one sweep.
- Some data objects might share the same bitmap or icon. If certain events are marked by a certain icon and these events take place many times, it is enough to store the icon once and then use it to display all the events of this type. So in general it makes sense not to store the bitmap within the data object but rather store a key in the data object and then pick the bitmap from a dictionary. If several objects then hold the same key, they will be displayed by the same bitmap or icon.

This section describes how the NtTimeChartControl supports these mechanisms. But first we think about the differences between icons and bitmaps. Icons are bitmaps so it is worth explaining wy they are handled differently.

Bitmaps:
In general bitmaps differ in size and are bigger than icons. For this reason it makes sense to keep only those bitmaps in memory that are actually needed.
Icons:
An icon represents a certain value that might occur many times in a data set. And as icons are pretty small, it makes sense to load all of them on application startup and keep them throughout run time. For example if you want to display temperature values by icons you might have only three icons (temperature too low, temperature ok, temperature too high) in order to show a series of many thousand temperature values over time. In such a case it will not make sense to load icons dynamically when they are needed. You will load them at startup and keep them in memory.

How to set up efficient image handling along with the Time Chart?
Whenever the NtTimeChartControl wants to draw an object, it calls your NtApplication interface methods to either get a text, double, or bitmap for that specific object. So let us first look at this interface's definition:

public interface NtApplication
{
bool NtIsHoliday(DateTime dt);
bool NtIsWeekend(DateTime dt);
string NtGetTooltipText(NtDisplayObject tooltipDisplayObject, int ttType);
string NtGetText(NtDataObject ntDo);
double NtGetDouble(NtDataObject ntDo);
Bitmap NtGetIcon(NtDataObject ntDo);
Bitmap NtGetBitmap(NtDataObject ntDo);
}

Suppose, a data type 'Temperature' with dataTypeId 100 shall be drawn as icons (as defined by the according NtDisplayDef object). Three icons shall be used: If the value is above 100, the bitmap 'highTempBitmap' shall be used. Below 50 'lowTempBitmap' and inbetween 'okTempBitmap' shall be used for drawing. As the NtDisplayDef.displayMethod for data type 100 is set to 4 (icon), the NtTimeChartControl will call your implementation of NtApplication.NtGetIcon() for each 'Temperature' value it wants to draw. So your implementation of NtApplication.NtGetIcon() shall look like this:

public Bitmap highTempBitmap;
public Bitmap okTempBitmap; //these Bitmaps are loaded once on startup.
public Bitmap lowTempBitmap;
public Bitmap NtGetIcon(NtDataObject ntDo)
{
if (ntDo.dataTypeId == 100)
{
double temp = (double)ntDo.dataItem;
if (temp > 100) return highTempBitmap;
if (temp < 50) return lowTempBitmap;
return okTempBitmap;
}
return null;
}

Now suppose another data type 'PDF-Documents' with dataTypeId 200 shall be drawn as preview images that are stored in a certain directory. Then the data elements stored in the Time Chart do not hold the preview images them selves but just the file name. In this case the display method 3 (bitmap) makes sense and your implementation of NtApplication.NtGetBitmap() could look like this:

public string bitmapDirectory = ""; //to be initialized to the bitmap directory on startup
public Dictionary bitmapDict = new Dictionary();
public Bitmap NtGetBitmap(NtDataObject ntDo)
{
Bitmap bitmap;
if (bitmapDict.Count > 100) bitmapDict.Clear(); //clear the dictionary when it becomes too big
if (!bitmapDict.TryGetValue((string)ntDo.dataItem, out bitmap)) { bitmap = new Bitmap(bitmapDirectory + (string)ntDo.dataItem); bitmapDict.Add((string)ntDo.dataItem, bitmap); }
return bitmap;
}

This implementation is not really professional but it shows the trick: When bitmaps are being used frequently, they are taken from the dictionary and no slow loading from file is needed. Still the dictionary is protected agains getting too big. And most of all: In contrast to the icons (see above), bitmaps that are never used will never be loaded. The maximum memory consumption can be calculated quite well as long as you know the size of the bitmaps.

Back to Overview

Top Tutorials -> Bitmaps and Icons ?2016 Bassaly