TVirtualStringTree - variable row height optimization - delphi

In our application I'm moving from a TStringGrid to TVirtualStringTree component. A lot of data is being displayed (max. 50000 lines and 5 columns). One column contains on or more lines of text. I managed to implement multiline functionality using 'DrawCell' in the stringgrid with optimal performance: instant redraw of all lines (on resize) and scrolling without hitches (I have a list of row heights in memory, which will be updated when redraw is needed).
Transferring this multiline functionality to the VirtualStringTree is not as performant as the stringgrid alternative. I tried numerous implementations but have not yet succeeded. This is easily reproducable in the Demo application of the VirtualStringTree installation package:
In the 'MultilineDemo' form, set the 'rootNodeCount' of the VirtualStringTree to 10.000.
When running the demo, select 'Automatically adjust node height to node text.'
Initial redraw/repaint will take a while using lots of CPU. Ater each resize, jumping to top/bottom causes the same phenomenon, or even causing a 'stack overflow' exception (but that's another issue ...). The 'OnMeasureItem' method is called way too much, the way I see it (even on 'MouseMove' events).
Has anyone had this problem and managed to find a solution?

This is easily reproducable in the Demo application of the
VirtualStringTree installation package
At least this performance issue is easily solved by wrapping the call to ReinitNode() in a BeginUpdate() and EndUpdate():
MLTree.BeginUpdate();
try
MLTree.ReinitNode(nil, True);
finally
MLTree.EndUpdate();
end;
I slightly reworked the sample project and the Virtual Treeview today, the sample project works much smoother now. Just try the latest source code from GitHub.

Related

How to always show Sirius Label in foreground

For the context, I'm working with Capella, an Eclipse RCP application based on Sirius (hence, EMF, GMF and draw2d). This application is used for MBSE, that basically means diagram representations for industrial systems.
I'm developping an add-on (viewpoint) to display custom labels next to diagram elements. These diagram elements are, to put it simply, boxes inside boxes. My problem is that usually the label text is larger than the space between a box and its container, so the label gets hidden. What I need is these labels to always be in foreground. As I'm more used to web development, what I'm looking for would be the equivalent of the z-index CSS property.
Currently I have no idea of how to achieve this, I'm using a custom .odesign that allows me to control some rendering options, like labels text, the color of some elements or to add decoration, but I dont think its the way to go for my problem. Maybe I should use a custom EditPart or a custom StyleConfiguration (I already used these components for other projects) but I have no clue where to start for this issue.
Any leads will be greatly appreciated.
We recently did this kind of changes to keep some labels in Sirius Sequence diagrams always on top: the combined fragments are placed behind the lifelines (z order) but we wanted to keep the labels of the CombinedFragments visible event their bounds intersects Lifelines, Executions or States).
This has been handled in Bug 564239 for Sirius 6.3.2 (used in Capella 1.4.1).
You could find some hints the bugzilla (Gerrits and commits can be retrieved from the See also section).
In Sirius Sequence diagram , we use org.eclipse.sirius.diagram.sequence.ui.tool.internal.layout.SequenceZOrderingRefresher to control the z-order of CombinedFragments : all the figures that composes them comes from some expressions in the odesign, and synchronization with the Capella model for exemple.
But in your case you want to control only the label, so it must not be dealt on the edit par level, but on the figure one. The "overlay" layer and figure lead might be a good one.
Do not forget another thing: in GMF/GEF, the labels of an element is displayed/shown/rendered/visible if it fits to the visible area of the parent container: in the case of a node in a container with scrollbar, the visible are will impact the visibility of the sub nodes (extended to their border nodes, edges, labels, ...)
Regards
Maxime

How to Simulate TListView(vsIcon mode) with Virtual TreeView

I am using Delphi XE3. Now I try to simulate TListView(vsIcon mode) with Virtual TreeView. Is that possible? Basically this is:
(1) A tree with only root nodes. That is easy to implement. Just use the following codeline is OK:
VirtualTreeView1.RootNodeCount := 5;
(2) Hide the tree lines. That is also easy to do, just set toShowRoot option to False can hide all the tree lines for the root nodes.
(3) Each root nodes is displayed with only icon instead of text. That can be implemented with OnGetImageIndex vent together with an image list assigned to the tree view.
(4) There is only one column. That is also easy. By default there is only one column.
(5) The nodes should be tiled from left to right, horizontally, instead of vertically.
The (5) point is the one that I cannot figure out how to implement. I try to do the following researches:
I try to check the TreeOptions and other properties, but cannot find one that support that feature.
I try to search online, and find the following articles:
How to display an icon or image in a column of TVirtualStringTree? (This use multi-column)
Icon position in Virtual Treeview (This does not discuss tiling of nodes horizontally.
Delphi - ListView or similar with owner draw button ( THis also tile the nodes vertically)
I then try to search keyword horizontally in the help document of Virtual TreeView, but what I get are all about how to scroll horizontally, not tile node horizontally.
I think I have tried my best to find a solution but failed. That is the reason why I ask on stackoverflow.
I don't think this is possible, at least Virtual TreeView was never designed to do this. It is a tree control that supports columns.

TeeChart 2017: FastLine AddRealTime auto scales bottom axis despite settings

The TeeChart component has a chart series called IFastLineSeries.
It allows drawing simple "line type" charts.
Its interface provides a method called AddRealTime which is a faster way to add data to the chart than the more generic AddXY method.
But AddRealTime has a few undocumented side effects:
It scrolls the chart to the left when the data almost "overflows" the view (to make room for new data)
It can adjust the bottom axis (X-axis range) to fit all data when doing so
The first feature is reasonable behavior in a lot of cases: for instance you want to keep showing the most recent process measurements as they are coming in.
However, in my case the automatic scaling for the bottom (X-axis) has been turned off. IMO it shouldn't touch the scaling settings then! But it does.
The second feature is worse: after auto scrolling, the control ensures that all the information is in view. This can slow down the application, because you may have accumulated lots of data in the fast line series which all has to be rendered then... Defeats the "is faster" philosophy behind the method...
I'm okay with the scrolling, but not with the automatic 'zoom out X' action.
Has anyone managed to get AddRealTime working without that, or is there no other choice than to fall back to the slower AddXY function?
I know I have to adjust the bottom axis myself then to achieve a similar scrolling effect, but at least it would not zoom out unexpectedly.
Remarks:
Steema software seems to know about this problem, ticket TA05011024.
Their support forums list similar if not the same problems:
How to disable autoscale with fastline series
FastLine AddRealTime ignores axis limits
You can control the behaviour you describe in the following way:
You could use Series.AddXY to avoid any of the AddRealtime's automatic behaviour; but you can anyway too, continue to use AddRealtime and modify the behaviour using your own SetMinMax of the Axis to scroll data off to the left, that way maintaining the same number of display points in the chart.
The demo here does just that and addresses your question.
Github VB TeeChart Add Realtime demo project

Teechart marks on Stacked Chart

Is there any way we can make data more readable when we perform Stacked operation on series.
There is Series.Marks.AutoPosition property for that. It's going to be deprecated soon and replaced by Series.Marks.Automatic.Move.
This property has been implemented for the TeeChart VCL/FMX version so far, the version from which TeeChart ActiveX is derived as a COM wrapper. Also note this property is not yet handled by all series styles. So far it is used by Map and World series.
The intention of “Automatic” is to perform several attempts to avoid series marks overlap other marks or other parts of the chart. It is True by default in all sub-properties.
In the meantime you can implement anti-overlapping similar to what was suggested here. This is a TeeChart for .NET thread but same principles apply to all versions.

Firemonkey and large amounts of data

I just had a look at Firemonkey's grid implementation and it turns out that it is a very simple implementation (only 1800 lines which seems not much for a grid implementation). It does almost no custom painting but does instead aggregate a lot of other controls - which seems to be the Firemonkey style of doing things.
For example, each column keeps an array of controls - one for each cell. For a normal text column with 1,000,000 rows, the grid would keep 1,000,000 edit controls in memory - which seems a little crazy to me. (EDIT: not so sure now if that assumption is right. It seems to take the visibility of cells into account, which could mean it does provide something like a virtual mode, but I'm not quite sure...)
My question: Without any doubt, this component-aggregating design of Firemonkey seems simple and elegant but does it really scale well with the amount of data that has to be displayed in the grid? I cannot imagine that it does perform well with a large number of rows. What is the Firemonkey way of handling large amounts of data?
Thanks for any input.
The FireMonkey grid only has controls for the number of visible lines.
So if you have a grid with 10 visible rows and 3 columns, it will create 30 cell controls.
Filling the grid with 10.000 records is no problem: when you scroll the 30 cell controls are reused and mapped to the new visible rows.
And yes: I did some tests with this because we have TMS grids with 100.000 records :-).
If you use OnGetCellText (so not TStringgrid, which is very slow with lots of records, especially TMS grid (based in VCL stringgrid)) it is very fast (OnGetCellText only retrieves data of visible cells). We use this technique in combination with our data objects (these are already loaded, so no need to fill each cell of the grid with the string value again...) and both TMS and FMX grids are very fast with 100.000 records or more!

Resources