D3 zoomable treemap - loading new levels async? - javascript

In this Treemap example, the whole JSON tree exists from the start:
http://jsfiddle.net/6p1gayrp/
As I have a very big dataset, I would like to load each level on click:
Clicking "International relations" in the example should instead load the children array from a remote datasource and then layout the rectangles.
So starting out with one level:
var json = {
"name": "Sitemap",
"children": [{
"name": "International Relations",
"value" : 700
}]
}
And then adding more data to the tree before recalculating layout:
var json = {
"name": "Sitemap",
"children": [{
"name": "International Relations",
"children": [{
"name": "Systemic Theory",
"children": [{
"name": "Great Powers",
"value": 400,
}, {
"name": "Systemic Politics",
"value": 300,
}]
}]
}]
}
How can I load data async while keeping the rest of the functionality intact?
(Ideally this would also work in the other direction: For example if a user navigates straight to a particular level of the treemap and then starts going up the hierarchy.)

Related

Disable FancyTree's lazy load

My application passes the entire tree hierarchy from PHP to Javascript via JSON. There are no AJAX calls, no lazy loading. However, what I'm finding is that I cannot actually disable the lazy load aspect of the list expanding method.
For example:
If this is the json passed from my PHP script:
[{
"title": "Southeast",
"key": 28,
"children": [{
"key": 2,
"title": "North Carolina",
"children": [{
"key": 68,
"title": "Charlotte"
}, {
"key": 69,
"title": "Raleigh"
}]
}, {
"key": 1,
"title": "South Carolina",
"children": [{
"key": 1,
"title": "Columbia"
}, {
"key": 2,
"title": "Baldwin County"
}, {
"key": 3,
"title": "Barbour County"
}, {
"key": 4,
"title": "Bibb County"
}]
}]
},
{
"title": "Northeast",
"key": 32,
"children": [{
"key": 3121,
"title": "Albany County",
"children": [{
"key": 3121,
"title": "Albany County"
}, {
"key": 3122,
"title": "Big Horn County"
}]
}, {
"key": 3122,
"title": "Big Horn County"
}]
},
{
"title": "Midwest",
"key": 167
},
{
"title": "Mid-Atlantic",
"key": 31
},
{
"title": "Southwest",
"key": 166
}]
And I create the fancytree:
$('#tree').fancytree({
source: 'php_script.php'
extensions: ['edit']
});
I can't see the second or third level tiers even in the DOM until I actually click the expander next to the respective parent tiers (Southeast, Northeast, etc.) What I'd like to be able to do, is "see" the tiers in the DOM (inspector/console) BEFORE a click on the expanders. Any idea how to do this? I assume this has to do with lazy loading, however, I've tried the following:
$('#tree').fancytree({
...
lazyLoad: function(event, data) {
return false; // I understand this is likely hack-ish, but it still didn't work
},
Or set the lazy property directly on each node with no luck:
[{
"title": "Southeast",
"key": 28,
"lazy":false,
"children": [{
"key": 2,
"lazy":false,
"title": "North Carolina",
"children": [{
"key": 68,
"lazy":false,
"title": "Charlotte"
}, {
"key": 69,
"lazy":false,
"title": "Raleigh"
}]
}
...
I've checked the nodes to ensure they're actually not lazy:
$('#tree').fancytree({
'beforeExpand': function(event, data){
console.log(data.node.isLazy());
},
'expand': function(event, data) {
console.log(data.node.isLoaded());
},
...
and in the console, I receive what I expected:
false
true
I understand that if the number of nodes begins becomes quite large, then NOT lazy loading them will begin to slow the page down. I also understand that I can force all of the nodes to load by triggering an expand on all nodes through this:
if(all) {
$('#tree').fancytree('getTree').visit(function(node){
node.setExpanded(expand);
});
}
But it feels like there should be an easier way to do this. I want the entire DOM loaded, but immediately on fancytree instantiation. Any thoughts?
Lazy loading would issue an Ajax request to load child nodes on first expand (if the parent is marked lazy).
What you describe is lazy rendering: The complete model is already loaded, but Fancytree generates DOM elements on demand. In most cases this leads to much better user experience, because browsers tend to slow down when the number of DOM elements grows too large.
See also here for concepts.
However, if you want to render all nodes after load, have a look at the node.render() method:
$("#tree").fancytree({
source: "php_script.php",
extensions: ["edit"]
init: function(event, data) {
data.tree.getRootNode().render(true, true);
},
...
});

React / Redux - how to render/update deeply nested sate

I'll get from the API a deeply nested state - e.g.:
[{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": []
}]
}]
}]
}]
(Please ignore duplicate ids etc)
Now here are the requirements:
I need to properly render this
e.g.
<div>
text
<div>
text
</div>
</div>
I need to be able to update the nested state within redux store
This list can be huge - like at least 3k items (which theoretically works fine)
What I tried:
Having everything unnested:
Rendering is very complicated (with parentId)
Maintaining the structure is difficult (need to flatten and unflatten it) -> this costs a lot of performance
Having everything nested:
Updating the store is impossible without "cheating" in react -> manipulating the state directly
What can be a solution to this? What should be the architecture
Something like immutability-helper will probably be of use to you here.
const state = [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": []
}]
}]
}]
}];
const newState = update(state, {
0: {
children: {
0: {
children {
0 : {
children: {
0: {
"id": { $set: 2}
}
}
}
}
}
}
};
return newState;
[{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 2,
"text": "test",
"children": []
}]
}]
}]
}];
The 0s here could be replaced with some indexes in your payload; I just used 0 here as the example arrays all have only 1 element in them. This is quite deeply nested though so as the comments pointed out, any flattening you can do will make the updates easier.

Kendo stacked column chart not displaying data correctly

Based on this or similar examples I tried using kendo stacked chart.
To my suprise the chart gets displayed incorrectly.
$("#chart").kendoChart({
dataSource: new kendo.data.DataSource({
data: data,
group: {
field: "Serie"
}
}),
series:
[{
type: "column",
stack: true,
field: "Value"
},
],
categoryAxis: {
field: "Category"
}
});
I tried defining also the model as in attached plunker or various other variations, but the data is still incorrect e.g. 2016-07 should just show 2 activities, while it shows 5.
var data =
[{ "Category": "2016-07", "Serie": "Physiotherapy", "Value": 35.00 },
{ "Category": "2016-07", "Serie": "Flex Class", "Value": 28.00 },
{ "Category": "2016-08", "Serie": "Flex Class", "Value": 27.00 },
{ "Category": "2016-08", "Serie": "Manual Therapy", "Value": 48.00 }
// rest in plunker
];
Ok, I got it. In order for this to show properly, all combinations of Category-Serie need to be served in dataSource and filled with zeros where the Serie is missing e.g. like that that
{ "Category": "2016-07", "Serie": "Manual Therapy", "Value": 0 }

Check for Parent Child node in JSON using angular JS

I am looking for JSON parsing reference, from where I can jump to question and check for Child question based on Yes section. I didn't find anything related to check for child node check in JSON. Angular is my base framework.
some use cases :
on load show Root question,
On selection show next questions which is child of root then go one
jump to number of questions from tree.
treeObj={
"Root_Element": {
"id": "myTree",
"dt": {
"choice": {
"id": '0',
"title": "Which color",
"description": "Choose color ?",
"choice": [
{
"id": 1,
"title": "Yellow",
"description": "Yellow ? ,
"choice": [
{
"id": 5,
"title": "Dark Yellow",
"description": "Dark Yellow ?
},
{
"id": 4,
"title": "Light Yellow",
"description": "Light Yellow ?
}
]
},
{
"id": 2,
"title": "Red",
"description": "Red ?"
},
{
"id": 3,
"title": "Green",
"description": "Green ?
}
]
}
}
}
}
If the number of levels in the JSON object is fixed and if it does not grow dynamically, you can use the ES6 destructuring to read the data from the nested JSON. Below is an example
var metadata = {
title: "Scratchpad",
translations: [
{
locale: "de",
localization_tags: [ ],
last_edit: "2014-04-14T08:43:37",
url: "/de/docs/Tools/Scratchpad",
title: "JavaScript-Umgebung"
}
],
url: "/en-US/docs/Tools/Scratchpad"
};
var { title: englishTitle, translations: [{ title: localeTitle }] } = metadata;
console.log(englishTitle); // "Scratchpad"
console.log(localeTitle); // "JavaScript-Umgebung"

How to get a value of specific element in json file? (Amazon API)

I am using amazon product api, I'm searching for an item using ASIN number:
amazon = require('amazon-product-api');
var client = amazon.createClient({
awsId: "*",
awsSecret: "*",
awsTag: "Tag"
});
client.itemLookup({
idType: 'ASIN',
itemId: 'B00WA6ZL8S',
responseGroup :'Variations'
}).then(function(results) {
console.log(JSON.stringify(results));
}).catch(function(err) {
console.log(err);
});
The result is a long JSON file with more than 40000 line of code, here is some of it :
[{
"ASIN": ["B00WA6ZL8S"],
"ParentASIN": ["B00WA6ZL8S"],
"VariationSummary": [{
"LowestPrice": [{
"Amount": ["9200"],"CurrencyCode": ["USD"], "FormattedPrice": ["$92.00"]
}],
"HighestPrice": [{
"Amount": ["13995"],
"CurrencyCode": ["USD"],
"FormattedPrice": ["$139.95"]
}]
}],
"Variations": [{
"TotalVariations": ["48"],
"TotalVariationPages": ["1"],
"VariationDimensions": [{
"VariationDimension": ["Size", "Color"]
}],
"Item": [{
"ASIN": ["B00RHLICFA"],
"ParentASIN": ["B00WA6ZL8S"],
"SmallImage": [{
"URL": ["http://ecx.images-amazon.com/images/I/41z-SPDeICL._SL75_.jpg"],
"Height": [{
"_": "35",
"$": {
"Units": "pixels"
}
}],
"Width": [{
"_": "75",
"$": {
"Units": "pixels"
}
}]
}],
How do I get the value of Height or Width ... etc ? And what is the point of the square brackets in "VariationSummary": [{ or "Variations": [{ ?? I mean they are not arrays of objects! .
results[0].Variations[0].Item[0].SmallImage[0].Height[0]._
Sometimes objects are better organized inside an array. You can use array functions like push or pop to organize a large group of objects easier.
Edit, I forgot SmallImage[0] and item[0], corrected answer.

Categories

Resources