How to only display a TreeView expand sign [+] if children exist - sql

I've developed an application that populates a treeview from hierachical data in a database.
I've designed it to use lazy-loading so it only gets the child nodes when a node is expanded.
My problem is that obviously I don't know if a node has children unless I make a call to the database and look. Currently I have implemented a dummy child node, so that the [+] icon appears for all nodes, I then remove this dummy node and get the real child nodes in the BeforeExpand event.
This means I get a [+] icon for nodes that don't have child nodes, so the user clicks the expand icon and there's nothing show which looks a bit shoddy.
What is the preffrred method for handling child nodes in a lazy-load treeview? If I make a call to the database to see if there are child nodes then I might as well just load the child nodes and forget about lazy loading right?
One thought I had was to store a 'HasChildren' flag in the database, so I can selectively create my dummy child node only for the nodes that actually do have child nodes.
Sorry for rambling on, I'm very interested to see what other people think...

When you make a call, check for children along with the node data:
SELECT tp.*,
(
SELECT 1
FROM table tc
WHERE tc.parent = tp.id
LIMIT 1
) AS has_children
FROM table tp
You don't have to count, it may be long.
Just check that at least one child exists.

change your initial query to return all the same data, but also a count of children. when the children count is not zero show the [+]. post your schema and query for help getting the count

My preferred solution to this problem is to implement pre-ordered tree traversal on your set of hierarchical data. See http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/ for an example implementation.
The point is that if you maintain a left and right value for each node, then if the left value and right value differ by more than one, that node has children.
The only notable downside of this approach is that you have to actively maintain those left and right values when altering the structure of the nodes.

Related

Count showing (visible) rows of a QTreeView

I found this question and this question.
I've also searched elsewhere.
The situation is that (starting with all root item children collapsed) my code iterates through the tree expanding the parents of those items whose data matches a certain criterion.
I just want to find the total number of showing rows displayed in the QTreeView at the end of that process. NB I use the word "showing" rather than "visible" as this is not a question about viewports: I want the total number showing assuming a viewport large enough not to have to create a vertical scrollbar.
Is there really no simple way to achieve this? Counting the total children displayed by, for example, counting all children of all parents which are expanded in this manner, as they get expanded, would be quite complex: sometimes, for example, two siblings meet the criterion, so the first expands its parent, but the second obviously doesn't. Not only that, but a node located deep in the tree expands not only its own parent, but (if necessary) its grandparent, great-grandparent, etc.
In view of the complexity of the foregoing, another possibility would be to iterate through the tree again, after expanding, in order to count the rows displayed. This seems a ludicrous effort just to get such a simple piece of information.
Please note that I'm talking about QTreeViews, not QTableViews. With the latter it appears that it possible to use table_view.verticalHeader().count(). But a QTreeView doesn't have the method verticalHeader.
QTreeView provides the indexAbove() and indexBelow() functions, and the latter:
Returns the model index of the item below index.
def count_showing_rows(self):
count = 0
index = self.model().index(0, 0)
while index.isValid():
count += 1
index = self.indexBelow(index)
return count

Filter by dimension member only without sub-nodes

I need to query a cube by a ragged dimension (parent-child). The filter can be multiple nodes at any level.
This works in that it restricts the results to just the 2 supply chains I want...
SELECT [Measures].[Total Revenue] ON COLUMNS
, [Product].[Products].Members ON ROWS
FROM myCube
WHERE
(
{
[Supply Chain].[SupplyChains].&[{c0c62bda-0369-4591-be85-3a7078bc3352}]
, [Supply Chain].[SupplyChains].&[{aca836e9-22ac-4952-8809-3f50aeda6891}]
}
)
I know, guid keys, not my design! The problem is that data that isn't assigned to a specific supply chain is assigned to the top node. If I add the top node to the list, then all data will be returned (since all data is subordinate to it).
Is there a way to return values with a specific member and ignore its children? I'd like to say "return all data assigned exactly to the top node or to the listed supply chains and their children).
Thanks FrankPI, your comment pointed me in the right direction.
I ended up replicating the query in Excel and then examining the generated MDX using the OLAP PivotTable Extensions. Excel allows you to set filters on sub-nodes like what I was trying to do.
What it does is create a set of all nodes that don't have filtered sub-nodes to get everything else. Then for the parents of the nodes with filtered sub-nodes (and all its parents up to the root) it adds to the set those nodes but with the .DataMember function so that only the node value is included (but not its sub nodes). So basically instead of saying what NOT to get, it explicitly says what TO get, listing all other nodes which can be a bit cumbersome but works.

Displaying deeper levels programmatically in a Oracle APEX tree hierarchy

I have a situation where I am going to have a fairly large dataset that I need to represent as a tree hierarchy within Oracle APEX v4.2.2. The dataset might be up to 6000 records with a depth of 5 levels.
Based on another thread, what I am looking at doing and this being the reason of this question, is initially within my tree query, I will only display up to 2 levels, i.e.:
WHERE level <= 2
My question is, while displaying my tree hierarchy of level <= 2, I want to then allow the user to click on a level 2 node, which would be fed somehow back into my tree hierarchy query and then basically display from a level 2 node down the tree to say the next 2 levels - now displaying from level 2 to level 4 and then continue in the same fashion.
Obviously I will also need a means of getting back to the top level of my tree from any lower levels being displayed at the time - say from level 4.
I am interested in how to best tackle this - I was also thinking whether I display a popup window of the next set of tree hierarchy data.
I think 6k records is still manageable by Javascript, so probably the easiest way would be to load the entire tree and collapse it onLoad with a Javascript/JQuery dynamic action.
Otherwise you can also try storing the desired level/key on a Hidden Page Item, build the tree hierarchy query using the value from this page item and just refresh the area with a dynamic action onClick.

NHibernate - Sequence numbers for child objects

In my business domain I need to do something with n-th child object which is inserted for a given parent object. So for examples some business actions should be invoked after inserting 100th, 200th and 300th child.
For now I have an idea to add a number field for children so the first child (for a given parent object) gets 1, the second gets 2, ... and so on. How may it be achieved using NHibernate? Or maybe there are better ways to achieve my goals.
Thank you in advance for answers and ideas.
Best regards
Lukasz
You can map your collection as a <list>... so the index of the children is stored.
Then you can use an AddChild method to add elements, so you can execute custom logic when you reach the n-th child.

CONNECT_BY_ISLEAF with Conditions

I have a hierarchical set-up going on a table using the whole START WITH and CONNECT BY clauses, which I am using to set-up a vertical-aligned menu system that can expand out to the right, depending on if a menu option has children and the total number of Levels. Also, as part of the menu option, if a parent has children, I also display a '>' symbol to specify this.
My question is, I am using CONNECT_BY_ISLEAF to determine whether a menu option is a leaf or not but I also have a column in my hierarchical table that specifies whether the menu option is active or not.
So when I have a case of a parent/child set-up in my menu, so that the ISLEAF value for Parent is 0 and Child is 1, but I have actually made the Child menu option inactive, my '>' symbol still displays at the parent level, even though the child record for this parent is inactive.
Any idea how I can check this alongside with the CONNECT_BY_ISLEAF value, to prevent the '>' symbol appearing even though this parent menu option has an inactive child record?
Basically want something that, if a child record exists based on ISLEAF value but child record is inactive, then ignore this leaf record and pretend it doesn't actually exist.
SELECT *
FROM table
CONNECT BY
parent = PRIOR id
AND active = 1
This will select a child only if it's active, if that's what you want.
Note that this query will return CONNECT_BY_ISLEAF = 1 for the items that do not have active children, and they will probably be treated as endpoints in your design.