Draw tree structure in HTML - javascript

I'm doing a school assignment to visualize in-depth search algorithm and i'd like to visualize the tree javascript creates. I've written the javascript to implement in-depth search but i'm in trouble visualizing the tree.Currently i've created an object for a node which has attributes:
function createNode(parent,name,suur,vaike){
var Node = new Object();
Node["name"]= name;
Node["children"] = [];
Node["parent"] = parent;
return Node;
}
In general it wouldn't be really difficult to draw a tree in HTML but i would like to get my head around it before i start writing any code for visualizing. The main issues i've stated is that the length of branches have to dynamically change - if new children are added to the tree then the tree will expand so different elements wouldn't collapse.
This is an image from Wikipedia and i'd love to get something like this as a result.
What my question is that i'd like to get some pointers how to dynamically expand the branch lengths so that different children wouldn't collapse.

For this particular task i used Treant.js. Really simple to use and drew nicely fitted tree. Had about 60 elements in the tree and no collision.
Here's a little snip from the result (it's scrollable, couldn't fit all on one page)

I would recommend using a VS Code for all extensions that rainbow color the HTML code structure and others, besides all unique CSS Selectors
I have dropped all #rainbow extensions I use. I hope that would help.
enter image description here

Related

Pivottable like HTML constructor without aggregation to show grouped elements

I'm trying to build an HTML component that will provide a pivottable-like view on my data, but with custom html elements inside the pivotarea rather than a sum or count; in the example below I'll just use a string of text, but I'd like it to be any HTML element (img, div, text etc.).
I'm finding it difficult to choose a direction, writing my own code to generate it (with jQuery) or using a library like Pivottable. I've tried the latter, but couldn't even find the proper direction w.r.t. customizing the aggregator function.
I could see myself re-using the html generated by js pivottable (with a simple count) and appending items afterwards in jQuery, but this seems like a rather hacky solution, along with a lack of customization options. Pros of this approach include the fact that at some point I'd like to include filtering/customization of the colums in the web-ui.
What am I looking for? Given a JSON array with multiple rows having attributes [Columngroup1, Columngroup2], and [Rowgroup 1, rowgroup2, rowgroup3], I'd like to layout it according as following (built in Tableau):
In the example above, [Businessline, Type, Product] are the Row-groups and [Active_or_roadmap, Roadmap Quarter] are the column groups. The granularity of the dataset is one level deeper, each 'Product' can consist of multiple subproducts, which should be placed either in the 'active' column (period header) or one of the roadmap quarter columns. This can be seen by subproducts 15.03 and 15.01 being grouped in the same 'row' visually.
What difficulties am I facing?
Do I use an HTML table for this, should I go with divs with classes indicating the rows/column, or a combination of both? Added complexity: at some point I'd like the non-header columns to be 'scrollable' horizontally (if too wide).
In a situation where I'd like to filter out some rows, should I regenerate the entire table or (mis)use visibility:hidden? In the latter case: how would I deal with a Product group being partially filtered (i.e. subproduct 15.01 should not be visible, subproduct 15.03 does need to be visible)
How would I 'embed' the object details in the DOM element? i.e., in the case of a hover/clickevent, how would I know which row in the JSON object corresponds to the name that was clicked?
Note that I'm not necessarily looking for an answer that fully does what I'm saying above, I'm primarily looking for a direction w.r.t. the code to go from the JSON to the above table in a structurally decent and flexible manner.
Any help is greatly appreciated, I have a codepen that contains some sample data and a rather poor attempt.
function load_data(callback){
$.getJSON('https://s3-us-west-2.amazonaws.com/s.cdpn.io/997352/data_portfolioroadmap.json', function(data){
callback(data)
});
}
I'm thinking something like this
{[
{productTitle:"Product 01.01",state:"Active","quarter":"2017Q1"},
{productTitle:"Product 01.02",state:"Roadmap","quarter":"none"}
]}
With this you should be able to loop over the array and place each element. I would use custom divs. First loop over the quarters and build those out. The loop over the state and filter grabbing the ones you need. Put the filtered results in a new var and sort it. The place each item in the proper column position as you are building out your rows. Then repeat with the next state.
Hope this make sense.
I think that managing that complex structure could force you to think of this table as a embeded components. Thinking of that maybe React (https://facebook.github.io/react/) could be appropriate solution for that.
Thinking about extending existing library is crucial for making this cost-effective, so please see https://react.rocks/example/orb (http://github.com/nnajm/orb) that maybe could be easier to extend using component matter of React that was used there.

Rearrange divs randomly using Javascript or Jquery

I've got a 3x3 grid layout using divs which upon clicking a button I need the divs to rearrange randomly. The following link illustrates an idea of what I need to create.
I don't need help with the HTML layout nor CSS design of the assignment per-se, but rather how to create the onclick function using native Javascript or jQuery in order for the "shuffle" and "sort" buttons to work. If possible, preferably Jquery, as I am more comfortable with its syntax.
I thank all in advance for help and support. Any useful links for me to do my own research is highly appreciated.
I am not looking for others to per say do my work for me, although solutions are highly appreciated, but perhaps guide me in a pseudo-code sort of way.
There are a number of different algorithms that you can use to "shuffle" a list of items. However, one of my favorite methods is the following because it is very concise.
General Shuffle Algorithm:
Find a list of items to rearrange.
Remove a random element from the items to rearrange
Insert the element into a new list
Repeat steps 1-3 until there are no more items left in the original list
Code Example
Here is a function that should do the trick:
$container = $("#container");
$divList = $("div");
$("#shuffle").on("click", function(){
//copy and remove all divs
$divCopy = $divList.clone(true);
$("div").remove();
while($divCopy.length > 0){
//chose random index of div array
var randomIndex = Math.floor(Math.random() * $divList.length);
$container.append($divCopy.splice(randomIndex, 1));
}
});
There is a full working version at https://jsfiddle.net/oruq1qou/
If you are interested in looking for other methods of solving this problem, I would recommend doing some reading on the different types of shuffle algorithms around.

jQuery 2.1 | Better quicker solution for looping between separate dependant elements

I currently use the each formula to get around with looping between separate dependant elements such as below:
// #UL-container is on the html index (main) page
$('#UL-container').find('.UL').each(function(){
var ulrel = $(this).attr('rel');
var numChilds = $(this).find('li').length;
// #CAT-container is on an ajax-loaded same origin page
$('#CAT-container').find('.catlink[rel='+ulrel+']').each(function(){
$(this).parent().find('.catcontent-length').append(numChilds);
});
});
This works great: catcontent-length classes simply display image lengths from a static list of related image titles located in #UL-container, but am wondering if the above stacked each jQuery solution is as quick processing-wise -- regardless of amount of elements affected -- as any other possible jQuery / javascript leaner solution out there. Any better quicker solution bearing in mind the scenario above?

Tree diagram: multiple on one page

I am attempting to put 2 d3.js tree diagrams, as seen here http://bl.ocks.org/1249394
on one page. Both trees will be loaded with different data from Javascript objects. The first one will appear in:
<div id="chart"></div>
and the second tree will be loaded in:
<div id="chart2"></div>
Both #chart and #chart2 are on the same page, with the first tree (#chart) appearing at the top of the page, and the 2nd (#chart2) right under it as that is how the chart divs are arranged. To do this I have applied the same code from http://bl.ocks.org/1249394 twice. One for each div with the only difference between the 2 pieces of code being the location of the tree that is tree 1:#chart and tree 2:#chart2.
Tree 1:
var vis = d3.select("#chart").append("svg:svg")
Tree 2:
var vis = d3.select("#chart2").append("svg:svg")
Everything else remains the same including variable and function names.
This works great and both diagrams show up as they should, except for the click function (last function in the code: ) Only the second tree is able to collapse and expand on click of tree nodes, the first tree is no longer able to do this, the first is no longer interactive.
How do I fix this?
You are overwriting the vis variable when you draw the second tree which the interaction depends on. If you are going to create multiple charts, you need to create a closure so that each tree is in its own scope. This way they won't interfere with each other.
Mike wrote up a nice post about creating reusable charts at http://bost.ocks.org/mike/chart/. He walks through creating a closure and surfacing properties.

Raphael JS: bring set to front

I was hoping someone could tell me how to bring an entire set of elements toFront in Raphael JS.
I am working with some dynamically generated sets of raphael elements, each of which is stored in an array making it easier to interact with and target individual sets. When a user interacts with the various sets I would like to be able to bring the full set to the front of the application.
I have tried using .toFront() as outlined here: http://raphaeljs.com/reference.html#Element.toFront
However this hasn't worked properly. Each set contains either a circle or a circle sector, a text element and either an additional circle or an additional sector.
Any ideas? At any one point a user may have up to 40/50 of these sets so bringing sets to front is going to be a necessity regardless.
i've had similar issues with the toFront() function ...
well i'd say there are two ways to do it ...
The first one (not quite recommended) apply a loop on all the elements of the set to bring them to front but still they'd be ordered according to the sequence in the set .... not good approach ...
set.forEach(el){
e.toFront();}
The second one is really sexy :) my fav :) beautifully explained by mister phrogz here
I recommend using the 'g' tag ... simple javascript . let all your sets be enclosed in a g tag
var mySet = document.createElementNS("http://www.w3.org/2000/svg", "g");
mySet.setAttribute('id','myset');
//should look something like this
//use jQuery append or javaScript appendChild to add your set elements to this group
<g id = 'myset'>
<rect>
<circle>
//etc etc
</g>
now
mySet.parentNode.appendChild(mySet); //the key line
this would simply take it to the bottom of the svg container, hence being drawn last and shown at the top according to the painters model also mentioned by mister phrogz in the link .... you could use javascript to manipulate your own z-index if required...

Categories

Resources