|
The Basics
Property arrays are properties and/or data items like PeData.Y, PeString.SubsetLabels, PeColor.PointColors, and many others that have multiple values defined by one or two indices. These property arrays are dynamic in that they grow as you increase the indices used to set items. Some property arrays have default elements defined and others are empty by default.
Some examples of property arrays with default elements are PePlot.SubsetLineTypes, PePlot.SubsetPointTypes, and PeColor.SubsetColors.
Some examples of property arrays empty by default are PeData.SubsetsToShow, PeLegend.SubsetsToLegend, and PeGrid.MultiAxesSubsets.
It is important to realize that a property array has a size and this size is often used to control image construction. If you are continuously manipulating property arrays. If they grow dynamically, you also need a way to shrink or empty the property array. This can be accomplished using the Clear method. For example, RandomSubsetsToGraph is a common property array that needs to be emptied or resized. The following code shows how to empty this property array.
|
Pego1.PeData.SubsetsToShow.Clear()
|
Also note that PeFunction.Reset() will empty the control of all property settings and revert the object to its default state. This is easier and the recommended approach when you need to reset the state of the object due to repeatedly changing the object.
Regarding Jagged Data or PeData.JaggedData set to True. We recommend only setting JaggedData = True if necessary. Note that Direct3D does not currently support ComputeShader use for JaggedData.
Use PeData.GetJaggedPointsX and similar functions to get the size (number of data Points) of jagged array.
Use PeData.SetJaggedPointsX and similar functions to set the size of jagged array.
It is not necessary to set the size of an array as the array will grow automatically, but setting the size may help with memory reallocations if spoon-setting large amounts of data.
Complete Methods Reference
The following tables list all methods available on the data property array indexer classes. Method signatures shown uses float as the element type; substitute double for the "ii" variants or Color/peColor32 for PointColors as shown in the type mapping above.
Size and Information
|
Signature
|
Description
|
|
int Length()
|
Gets the total number of elements within this array.
|
|
int GetLength(int dimension)
|
Gets the total number of elements per dimension for two dimensional arrays.
Possible dimension settings are:
– 0, gets size of first dimension (Subsets).
– 1, gets size of the second dimension (Points).
|
Initialize and Clear
|
Signature
|
Description
|
|
Clear()
|
Empties all elements within this array.
|
|
Clear(int newSize)
|
Reduces size of the array to a new size. Elements at end of array are lost.
|
|
bool Initialize(float dataValue)
|
Fills all subsets with the provided data value. Useful to initialize array with a user defined null data value. Works with JaggedData = True or False. If needed, the size of array should first be set by simply setting the last element in the array.
|
|
bool InitializeJagged(int nSubset, float dataValue)
|
Fills one subset with the provided data value. Useful to initialize a specific subset with a user defined null data value. Works with JaggedData = True or False.
|
Block Copy In – Non-Jagged Data
These methods copy data from your application arrays into the chart. FastCopyFrom methods call ProEssentials.Api.PEvset / PEvsetW which block copies the source bytes directly into the chart using memcpy – the fastest approach. CopyFrom performs a managed element-by-element copy. Many of our .Net examples use FastCopyFrom so search our demo projects to find specific use examples.
|
Signature
|
Description
|
|
bool FastCopyFrom(float[,] source)
|
Copy from a 2D array. The size of the dimensions must be Data.Subsets by Data.Points. Calls PEvset internally.
|
|
bool FastCopyFrom(float[] source)
|
Copy from a 1D flat array. The size must be Data.Subsets × Data.Points. Layout is defined by SubsetByPoint. Calls PEvset internally.
|
|
bool FastCopyFrom(float[] source, int nAmount)
|
Copy nAmount elements from a source array. Source must be at least nAmount elements. Calls PEvset internally. Useful when your source array is larger than the chart's data area.
|
|
bool FastCopyFrom(float[] source, int nSubset, int nAmount)
|
Copy nAmount elements into this array starting at subset nSubset. For non-jagged data. Calls ProEssentials.Api.PEvsetEx which block copies the source into a partial portion of this array.
|
|
bool CopyFrom(float[,] source)
|
Managed copy from a 2D source array. The size of the dimensions must be Data.Subsets by Data.Points. Slower than FastCopyFrom but does not require matching memory layout.
|
Copy In – Jagged Data
These methods are used when JaggedData = True. Each method operates on a single subset, allowing subsets to have different numbers of points.
|
Signature
|
Description
|
|
bool FastCopyFromJagged(float[] source, int nSubset)
|
Copies elements from source array into subset nSubset and sets the size of this subset. Only use for X, Xii, Y, Yii, Z, Zii, and PointColors property arrays when JaggedData = True.
|
|
bool CopyFromJagged(float[] source, int nSubset, int nElements)
|
Managed copy from source array into subset nSubset, setting the size of this subset. If nElements is 0, the entire source array is used. Only for JaggedData = True.
|
|
bool CopyFromJaggedTo(float[] source, int nSubset, int nInsertIndex)
|
Copies source array elements into subset nSubset at the nInsertIndex location, possibly increasing the size of the subset. Only for JaggedData = True.
|
Copy Out
|
Signature
|
Description
|
|
float[,] Copy()
|
Copies this array to a new 2D array. The dimensions will be Data.Subsets by Data.Points.
|
|
float[] CopyJagged(int nSubset)
|
For when JaggedData = True, copies the array for subset nSubset to a new 1D array. Only use for X, Xii, Y, Yii, Z, Zii, and PointColors property arrays when JaggedData = True.
|
Real-Time Append
These methods support real-time data updating. Existing data shifts to make room for new data unless CircularBuffers is True, in which case a circular buffer eliminates the shifting overhead. After calling AppendData on a Graph Object (Pego), the chart auto-regenerates. For other objects, call ReinitializeResetImage after appending.
|
Signature
|
Description
|
|
bool AppendData(float[] data, int amountPerSubset)
|
Appends multiple data points (amountPerSubset) per subset, shifting existing data to make room. The array size must be a multiple of PeData.Subsets. For non-jagged data and real-time. Returns false if error. (TwoDimensionalFloatArrayEx / TwoDimensionalDoubleArray only.)
|
|
bool AppendSubset(float[] fNewData, int nAmountPerPoint)
|
Appends multiple data items (nAmountPerPoint) per point, shifting existing data to make room. The array size must be a multiple of PeData.Points unless DuplicateData is being used. Similar to AppendData but shifts chart top-to-bottom (by changing Y) rather than left-to-right (by changing X). For non-jagged data and real-time. Returns false if error. (TwoDimensionalFloatArrayEx / TwoDimensionalDoubleArray only.)
|
|
bool AppendFromJagged(float[] source, int nSubset)
|
For when JaggedData = True. Shifts current data within subset nSubset and then appends the newly supplied data. Does not change size of array. Only use for X, Xii, Y, Yii, Z, Zii, and PointColors property arrays.
|
Zero-Copy Pointer Reference
Instead of copying data to the chart, these methods tell ProEssentials where your data already exists in memory. The chart reads directly from your arrays – no copy overhead. This is the most efficient approach for large datasets and for sharing the same data across multiple chart objects. Arrays must remain in scope and be pinned for the lifetime of the chart. The GigaPrime3D demo demonstrates data reuse between 3 charts using this approach. Call PeFunction.Reset() or the no-argument overload to clear the pointer reference.
|
Signature
|
Description
|
|
bool UseDataAtLocation(float[] source, int nBufferSize)
|
Provides the native PEGRP64H.DLL / PEGRP32H.DLL the location of your local .NET array. Carefully assign nBufferSize to match your allocated array size (Data.Subsets × Data.Points). Works with one block of memory for all subsets and points in format defined by SubsetByPoint. For non-jagged data. Set Data.Subsets and Data.Points before calling.
|
|
bool UseDataAtLocation()
|
Resets the data location so no location is defined. The chart reverts to using its internal copy of the data.
|
|
bool UseJaggedDataAtLocation(float[] source, int nSubset)
|
Provides the native DLL the location of your local .NET array for subset nSubset. This overload works with one block of memory for one subset. For JaggedData = True. The given array will represent all data for the subset.
|
|
bool UseJaggedDataAtLocation()
|
Resets the data location so no location is defined.
|
Data Binding
|
Signature
|
Description
|
|
int BindData(IEnumerable source,
int startingSubsetIndex,
int startingPointIndex)
|
Loads data from a DataReader or DataView source. We recommend compiling arrays and using FastCopyFrom instead for best performance, but this method is convenient for ADO.NET workflows. This method does not clear existing data or alter Data.Subsets and Data.Points. Data is loaded at indices starting with startingSubsetIndex and startingPointIndex. Multiple subsets of data are read in and allocated by their sequence in column. The return value is the number of records set.
|
Choosing a Data Passing Strategy
ProEssentials is a native C/C++ component that renders directly via Direct2D, Direct3D, and GDI+ to a Windows device context. This low-level architecture means data handling follows classic C/C++ and C# basic array patterns: simple contiguous blocks of memory. Gigasoft strongly recommends that you maintain your data in standard arrays within your application before passing (or passing by reference) to ProEssentials.
|
Method
|
.NET Interface
|
C++ DLL
|
Speed
|
Best Use Case
|
|
Indexer
|
PeData.Y[s,p] = val
|
PEvsetcellEx
|
Good
|
<100K points, prototyping, sparse values
|
|
Block Copy
|
FastCopyFrom()
|
PEvset
|
Fastest
|
100K–500K points, production applications
|
|
Partial Copy
|
FastCopyFromJagged()
|
PEvsetEx
|
Fast
|
Jagged data, per-subset updates
|
|
Zero-Copy
|
UseDataAtLocation()
|
PEP_faYDATAPTR
|
No Copy
|
>500K points, shared data across charts
|
|
Zero-Copy Jagged
|
UseJaggedDataAtLocation()
|
PEP_faYDATAPTR
|
No Copy
|
>500K jagged, shared subset arrays
|
|
Real-Time Append
|
AppendData()
|
PEP_faAPPENDYDATA
|
Fast
|
Live streaming data, monitoring
|
.NET Wrapper Transparency
The .NET interfaces (Gigasoft.ProEssentials.dll) are thin wrappers around the native PEGRP64H.DLL (64-bit) or PEGRP32H.DLL (32-bit). Understanding this helps you optimize. When using the C++ DLL API directly, the same data-handling capabilities are accessed through the corresponding DLL functions:
|
.NET Method
|
Wraps DLL Function
|
Internal Behavior
|
|
FastCopyFrom()
|
PEvsetW / PEvset
|
memcpy of entire array
|
|
FastCopyFrom(source, nSubset, nAmount)
|
PEvsetEx
|
memcpy of partial range into specific subset
|
|
FastCopyFromJagged()
|
PEvsetEx
|
memcpy of per-subset range
|
|
PeData.Y[s,p] = val
|
PEvsetcellEx
|
Single value assignment
|
|
UseDataAtLocation()
|
PEP_faYDATAPTR
|
Sets pointer, no data copy
|
|
UseJaggedDataAtLocation()
|
PEP_faYDATAPTR
|
Sets per-subset pointer, no data copy
|
|
AppendData()
|
PEP_faAPPENDYDATA
|
Shift + memcpy (or circular buffer)
|
Quick Reference Guidelines
1. For Non-Jagged mode, set Subsets and Points before passing data.
2. For <100K points, simple indexers (PeData.Y[s,p] = val) are fine.
3. For 100K–500K points, use FastCopyFrom() – simple and fast.
4. For >500K points or shared data, consider UseDataAtLocation() for zero-copy efficiency.
5. Keep your data in application arrays – maintain clear separation from the chart.
6. Use JaggedData only when subsets genuinely have different point counts.
7. Call ReinitializeResetImage() after setting or changing data (Graph Objects auto-regenerate after AppendData).
Related Demo Examples
Explore these examples in the PeDemo application (default install: C:\ProEssentials10\Demo) for working implementations:
|
Example
|
Description
|
|
018
|
Graph showing use of FastCopyFrom / PEvset
|
|
142
|
JaggedData simple – 4 subsets with varying points (spoon fed)
|
|
143
|
JaggedData with FastCopyFromJagged C# arrays (block passed)
|
|
144
|
JaggedData with UseJaggedDataAtLocation (zero-copy reference)
|
|
145
|
2D Real-Time with ComputeShader and CircularBuffers
|
|
146
|
2D Real-Time using UseDataAtLocation with CircularBuffers
|
|
GigaPrime3D
|
Data reuse between 3 charts with ComputeShader GPU rendering – demonstrates UseDataAtLocation sharing the same memory across multiple chart objects
|
Note on PointColors
PeColor.PointColors uses the same method patterns as the data properties above, but accepts Color or peColor32 types instead of float/double. When using FastCopyFrom with int[] arrays for PointColors, note that int colors should be formatted as BGR instead of RGB when passing to the native DLL in bulk. The static helper method ColorArrayToPeColor32() on TwoDimensionalColorArray can convert System.Drawing.Color arrays to peColor32 arrays for use with FastCopyFrom methods.
Deep Dive Property Array Indexer Classes
The technology behind property arrays is known as Indexers. These are special .NET classes to facilitate working with dynamic lists using common array nomenclature.
ProEssentials defines several Indexer classes to work with different types of property arrays. You will never allocate these classes yourself, but inherently use them as embedded features. You may see mention of these classes when working with ProEssentials. Just note they are internal mechanisms to facilitate working with arrays.
The base classes provide core array operations (Clear, Initialize, Copy, GetLength, etc.) used by all property arrays:
|
One Dimensional
|
Two Dimensional
|
|
OneDimensionalFloatArray
|
TwoDimensionalFloatArray
|
|
OneDimensionalDoubleArray
|
TwoDimensionalDoubleArray
|
|
OneDimensionalIntegerArray
|
TwoDimensionalColorArray
|
|
OneDimensionalStringArray
|
TwoDimensionalStringArray
|
The primary data property arrays (X, Y, Z, W) use an extended class that inherits everything from TwoDimensionalFloatArray and adds real-time append and additional block-copy overloads:
|
Extended Class
|
Inherits From
|
|
TwoDimensionalFloatArrayEx
|
TwoDimensionalFloatArray
|
TwoDimensionalFloatArrayEx adds AppendData (append new points per subset for real-time) and AppendSubset (append new subset items per point for real-time) to the base class methods. TwoDimensionalDoubleArray and TwoDimensionalColorArray include these methods directly.
Data Property Type Mapping
All data property arrays share the same set of methods. The only difference is the element type used in method signatures. When reading the methods table below, substitute the appropriate type for your property:
Use the double-precision "ii" variants (Yii, Xii, etc.) when you need greater precision. Set the corresponding UsingYDataII property to True and pass data through PeData.Yii instead of PeData.Y.
|