Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1529

VB6 compact Charting-Class (using an InMemory-DB as the DataStorage for x,y-Plots)

$
0
0
This Demo is making use of the Cairo-Drawing-, as well as the InMemory-DB-features of vbRichClient5.

Background:
Although the contained cChart-Class is able to render any x,y-ValuePairs - often one has to
handle and store "timestamp-based Data", as e.g. from a "Stock-Exchange-Ticker" (when the
y-Values are Prices) - or from a "Data-Logger" of a measurement-device (where y-Data comes
in as more "physically related units"...

Though in both cases we have some kind of time-values in the x-Members of the x,y-Pairs -
and the amount of data can get quite large "over time".

So, a DB-based storage is not only useful to "archive and persist" such x,y-Pairs (on Disk) -
it is also useful, to make use of "time-range-queries".

These are usually queries which start from the most recent TimeStamp-Value in the DB-Table,
then covering a certain range "to the left of this RightMost-x,y-Pair".

E.g. "Show me a Chart for all the Values in the last hour" (or the last day, or the last week, etc.)

Now one might say: "Yeah - a DB and SQL-queries would be nicer to use - but for my small project
I don't want to introduce a DB-Engine, just for more comfortable Charting..."

Well, and this is the scenario where an InMemory-DB makes sense - offering all of the benefits
of a full DB-Engine, at basically no cost - later on (in case persisting of the Data on Disk becomes
a topic) - the App would be upgradable to a filebased-DB just by changing the DB-Creation-Line.

What's nice with DB-Engines in general, is that they offer a robust and convenient way, to
perform "grouping aggregations" - which is useful for Charting, in case one wants to visualize
trends, averages, Min- and Max-Values etc.

With SQL one can handle such tasks quite nicely and efficient in one single statement,
as e.g. this one here, which I used in the Demo, to do Grouping on the x.y-Pairs
with regards to Average, Min- and Max-Values - and the time-range (starting from
a MaxDate, then reaching parts - or multiples - of HoursBack into the DataStorage.

Code:

Private Function GetData(ByVal MaxDate#, Optional ByVal HoursBack# = 1, Optional ByVal GroupingSeconds& = 60) As cRecordset
  With New_c.StringBuilder
    .AppendNL "Select Avg(TS) AvgT, Avg(Price) AvgP, Min(Price) MinP, Max(Price) MaxP From Ch1"
    .AppendNL "Where TS Between " & Str(MaxDate - HoursBack / 24) & "+1e-6 And " & Str(MaxDate)
    .AppendNL "Group By CLng(0.500001 + TS*24*60/" & Str(GroupingSeconds / 60) & ") Order By TS"

    Set GetData = MemDB.GetRs(.ToString)
  End With
End Function

Important for InMemory-Usage of DB-Engines is, that they can be filled with Data fast (being
roughly at "Dictionary-Level") - and with SQLite that is a given, as the following ScreenShot
shows ... second-based values of two full days (2*86400) were transferred into the DB in
about 370msec, included in this case also the time, to create an index on the TimeStamp-column.



The above ScreenShot shows also, how the Min- Max- and Avg-Values are rendered finally -
due to the index we build at the time of data-import, we can then perform fast
querying and rendering in typically 10-30msec per complete Chart...

Below is another Picture, which shows the timing, needed for both (querying and rendering),
and at this occasion also how the same Data will be rendered with cChart, when certain
Options are changed (no BSpline, no Min-Values, no Max-Values - note the automatic
scaling of the Y-Axis, which now covers a different value-range):



Here's the Demo-Zip:
SimpleCharting.zip

So, yeah - and as is normal for RichClient-based code, the whole thing is quite compact -
cChart.cls, as well as the second Code-Module (fMain.frm) contain both less than 100 lines of code...
have fun adapting it to your needs.


Olaf
Attached Files

Viewing all articles
Browse latest Browse all 1529

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>