I have my data stored in database in flat structure with out any heirarchical fashion and currently displaying in tabular format using jqgrid. I would like to display it in drill down fashion like the count at the top levels, child levels like this in nested fashion. Is it possible to do using jqgrid...
I think that the best way to make some queries used GROUP BY on the server side to construct the information about the hierarchy of the data. In the way you will be construct the tree structures which you need. The main data will get isLeaf:true, level:4, expanded:false, loaded:true properties and parent property with the id of the parent node "2200". If you would use as ids the values with prefixes like 'e' for 'Event', 'm' for 'Model' and so on you will be easy construct unique ids for every row so you will be able to construct all data for the Tree Grid on the server and then place the data in the server response.
Alternatively you can fill only the top level of the tree grid. You can construct simply query which will produce the resulting set. If the user will opens some tree node the new request will be sent to the server. The request will contains the some additional parameters: nodeid, parentid and n_level. If you good choose the id values of on the root items you will have full information to construct query which will get you the next level on the tree. You should use parentid as to construct the WHERE part of the query. In the way you can also construct the tree and load all noded on-demand.
Related
I want to have something similar to the example here http://demos.telerik.com/kendo-ui/treeview/filter-treeview-in-dialog but with some changes which are
Server side filtering
remote datasource
Load on demand true (when no search)
For example, the expected behaviour is initially the tree will be loaded from remote datasource with load on demand (only first level will be retrieved) and when user enter a search text, the search will be performed on server side and all results will be returned and no lazy loading. last thing when user clear search text, the tree will return to lazy loading again and load on demand would be true.
And here are more details about my case
Tree Structure will be only two levels, let say type and item
root level is fixed, all roots will always shown
first json object structure which will be used in all data retrieval will be
Id
Description
HasChild
Childs
so data will be retrieved from the server as following
first load will be the root level only, has child will be true for all roots, and children will be null
when expand node (with lazy loading), only return the children for the expanded node
when search (will not lazy loading), return all roots with matched children in children property
Any ideas?
as Ross Bush says, it is not a built in functionality, after a lot of tries and research, i found that the issue is two things:
I cannot change the load on demand after initialization (even i use setOptions function)
I cannot change the value of children after datasource intialized !!!
so, the solution (or acutally a workaround) is re-intialize the datasource and the tree when i change the mode from search to view and vise versa !!!. this is how i solved it
Thanks all for your contributing
I have a Tableau dashboard with various visualizations created from 3 data sources (i.e. A,B, C).
Each data source has a relationship (join) with the same secondary data source (i.e. D), and the secondary data sources provides information to create a filter for each data source. In other words, there is the following relationship for my data sources:
A - D
B - D
C - D
I would like to create a global filter on a dashboard I have created. I would like one filter card from "D" to show up and be applied to "A," "B," and "C" at once rather than having a separate filter card show up for each data source.
I tried to create a global filter via a parameter and calculated field, but the parameter requires layers of connections because data sources "A,B, and C" only have "D" in common.
Thoughts?
Its not completely clear from your question, but it sounds like you are using Tableau data blending on your worksheets to include data from multiple data sources, rather than a join to create a data source based on multiple tables. If all your tables are on the same database server or spreadsheet, then traditional joins are usually more efficient than data blending.
The following approach often works well.
Instead of using Tableau's quick filter feature, create a worksheet based solely on D that shows the values you wish to use for filtering. It can be a simple list of names, or a bubble chart or anything you like. Use that worksheet as your filter by creating actions where it is the source and all the other worksheets on your dashboard are the target. Typically, you would want to specify the field names explicitly.
Data blending is useful but can be complex. Depending on details, you may need to make D the primary data source on your other worksheets. Experiment.
The parameter and calculated field you mentioned can be even simpler and faster than using actions, but users are restricted to selecting a single value for a parameter unlike the filter action approach. (Of course, one parameter value can represent multiple values in your target data source field depending entirely on how your calculated field interprets the parameter).
I can't tell why that didn't work for you or what you mean by "layers of connections". You might consider clarifying that part of your question.
What is a good way to map a level of a treestore to a flat store. In my case,
I want to group criteria for a search. All search criteria are inserted into the top level of the treeStore, unless they are grouped, in which case they become children of a top level logical(AND or OR) node. So, within a grid, I want to display the top level nodes (via some toString method I will define in the model). This is the easy part, I just go through the top level of my tree and generate the output for the Store/grid. However, when I want to remove something from the grid/store, it also needs to be removed from the treestore which represents the actual logical structure.
So, How can I keep track of which textual store item corresponds to which top level node in my treeStore?
Load your data onto the store or treegrid (but not both), then collect the records from one object and just add them to the other (using store.add() or treestore.getRootNode().appendChild()). At this point if you have a reference to the record, you can just say store.remove([record]); and then treestore.getRootNode().removeChild(record); to remove it from both.
I have a TreeStore with objects that I view and manipulate through a GtkTreeView/GtkTreeModel setup.
I also have a TreeView showing a TreeModelSort of the TreeStore, which I use for sorting on columns like name and date.
The problem is, that the sort mechanism only sorts the root nodes, even if a underlying child node has e.g. a date that is later/sooner than the roo tnodes' dates.
So, the question is if there is any way to show the objects as a List, not a tree, but keeping the references to the paths in the other TreeView?
I would suggest a TreeModelFilter that filters out any rows that are child rows (ie, depth > 1). You can filter your sorted model, and display just the root nodes.
I am developing a web application that can support threaded comments. I need the ability to rearrange the comments based on the number of votes received. (Identical to how threaded comments work in reddit)
I would love to hear the inputs from the SO community on how to do it.
How should I design the comments table?
Here is the structure I am using now:
Comment
id
parent_post
parent_comment
author
points
What changes should be done to this structure?
How should I get the details from this table to display them in the correct manner?
(Implementation in any language is welcome. I just want to know how to do it in the best possible manner)
What are the stuff I need to take care while implementing this feature so that there is less load on the CPU/Database?
Thanks in advance.
Storing trees in a database is a subject which has many different solutions. It depends on if you want to retrieve a subhierarchy as well (so all children of item X) or if you just want to grab the entire set of hierarchies and build the tree in an O(n) way in memory using a dictionary.
Your table has the advantage that you can fetch all comments on a post in 1 go, by filtering on the parentpost. As you've defined the comment's parent in the textbook/naive way, you have to build the tree in memory (see below). If you want to obtain the tree from the DB, you need a different way to store a tree:
See my description of a pre-calc based approach here:
http://www.llblgen.com/tinyforum/GotoMessage.aspx?MessageID=17746&ThreadID=3208
or by using balanced trees described by CELKO here:
or yet another approach:
http://www.sqlteam.com/article/more-trees-hierarchies-in-sql
If you fetch everything in a hierarchy in memory and build the tree there, it can be more efficient due to the fact that the query is pretty simple: select .. from Comment where ParentPost = #id ORDER BY ParentComment ASC
After that query, you build the tree in memory with just 1 dictionary which keeps track of the tuple CommentID - Comment. You now walk through the resultset and build the tree on the fly: every comment you run into, you can lookup its parentcomment in the dictionary and then store the comment currently processed also in that dictionary.
Couple things to also consider...
1) When you say "sort like reddit" based on rank or date, do you mean the top-level or the whole thing?
2) When you delete a node, what happens to the branches? Do you re-parent them? In my implementation, I'm thinking that the editors will decide--either hide the node and display it as "comment hidden" along with the visible children, hide the comment and it's children, or nuke the whole tree. Re-parenting should be easy (just set the chidren's parent to the deleted's parent), but it anything involving the whole tree seems to be tricky to implement in the database.
I've been looking at the ltree module for PostgreSQL. It should make database operations involving parts of the tree a bit faster. It basically lets you set up a field in the table that looks like:
ltreetest=# select path from test where path <# 'Top.Science';
path
------------------------------------
Top.Science
Top.Science.Astronomy
Top.Science.Astronomy.Astrophysics
Top.Science.Astronomy.Cosmology
However, it doesn't ensure any kind of referential integrity on its own. In other words, you can have a records for "Top.Science.Astronomy" without having a record for "Top.Science" or "Top". But what it does let you do is stuff like:
-- hide the children of Top.Science
UPDATE test SET hide_me=true WHERE path #> 'Top.Science';
or
-- nuke the cosmology branch
DELETE FROM test WHERE path #> 'Top.Science.Cosmology';
If combined with the traditional "comment_id"/"parent_id" approach using stored procedures, I'm thinking you can get the best of both worlds. You can quickly traverse the comment tree in the database using your "path" and still ensure referential integrity via "comment_id"/"parent_id". I'm envisioning something like:
CREATE TABLE comments (
comment_id SERIAL PRIMARY KEY,
parent_comment_id int REFERENCES comments(comment_id) ON UPDATE CASCADE ON DELETE CASCADE,
thread_id int NOT NULL REFERENCES threads(thread_id) ON UPDATE CASCADE ON DELETE CASCADE,
path ltree NOT NULL,
comment_body text NOT NULL,
hide boolean not null default false
);
The path string for a comment look like be
<thread_id>.<parent_id_#1>.<parent_id_#2>.<parent_id_#3>.<my_comment_id>
Thus a root comment of thread "102" with a comment_id of "1" would have a path of:
102.1
And a child whose comment_id is "3" would be:
102.1.3
A some children of "3" having id's of "31" and "54" would be:
102.1.3.31
102.1.3.54
To hide the node "3" and its kids, you'd issue this:
UPDATE comments SET hide=true WHERE path #> '102.1.3';
I dunno though--it might add needless overhead. Plus I don't know how well maintained ltree is.
Your current design is basically fine for small hierarchies (less than thousand items)
If you want to fetch on a certian level or depth, add a 'level' item to your structure and compute it as part of the save
If performance is an issue use a decent cache
I'd add the following new fields to the above tabel:
thread_id: identifier for all comments attached to a specific object
date: the comment date (allows fetching the comments in order)
rank: the comment rank (allows fetching the comment order by ranking)
Using these fields you'll be able to:
fetch all comments in a thread in a single op
order comments in a thread either by date or rank
Unfortunately if you want to preserve your queries DB close to SQL standard you'll have to recreate the tree in memory. Some DBs are offering special queries for hierarchical data (f.e. Oracle)
./alex