Recursive circle packing? - javascript

I have a JSON object that I want to be able to visualize as a hierarchy of circles like this (you can zoom in and out of the hierarchy using mouse clicks).
I'm just trying to figure out how to use the d3.layout.pack to generate the hierarchy for the JSON object below and access the data that sits under Franchise. Any pointers would be much appreciated. Thanks.
{
"Consultant":
[
{
"ConsultantID": 1,
"ConsultantName": "Test Consultant",
"Account":
[
{
"AccountID": 1,
"AccountName": "Test Account",
"Site":
[
{
"SiteID": 1,
"SiteName": "Test Site",
"Franchise":
[
{
"FranchiseID": 1,
"FranchiseName": "Test Franchise",
"Data":
{
// Data goes here
}
}
]
}
]
}
]
}
]
}

For the layout, you can use the built in circle packing layout as you suggest.
For formating the data to use it in this layout, you can use the d3.nest() function. If you want some more insight on how nest works, then I suggest you to have a look at the following question: D3 JSON data conversion

Related

dhtmlxgantt Populate Nested JSON data

I have a dhtmlx gantt chart in my page, normally it would have work perfectly but now when I have a JSON file with nested array all my output would be unrecognized instead. I'm trying to populate the official name.
Can Anyone help me with this? Thank you very much.
JSON
{
"data": [
{
"assign_to": {
"id": 3,
"employee_id": "28141",
"official_name": "Hal Jordan",
},
"task": {
"id": 1,
"name": "Modeling",
"description": "3d modeling work"
},
"start_date": "2017-06-15",
"end_date": "2017-06-19"
},
{
"assign_to": {
"id": 3,
"employee_id": "28144",
"official_name": "Kyle Rayner",
},
"task": {
"id": 8,
"name": "Composting",
"description": null
},
"start_date": "2017-06-01",
"end_date": "2017-06-08"
}
]
}
Javascript
gantt.config.columns = [
{name: "assign_to.official_name", label: "Assign To", align: "left", width: 70},
];
function initializeGantt() {
gantt.init("my_scheduler");
gantt.load("/dashboard/ganttchart_list/5/?format=json");
}
initializeGantt();
HTML
<div id="my_scheduler" style='width:1405px; height:245px;'></div>
dhtmlx gantt doesn't support nested structure, so you'll need to preprocess your items before loading them to gantt.
Since you know which format you have and which format is expected by gantt (https://docs.dhtmlx.com/gantt/desktop__supported_data_formats.html#json ) it shouldn't be a problem.
The most important thing
Make sure data items have 'id' property
when you define column name like this:
{name: "assign_to.official_name", label: "Assign To", align: "left", width: 70},
column name can't be mapped to a property of a nested object, so you'll either have to flatten structure during loading, very roughly, it can be done in following way:
http://snippet.dhtmlx.com/129d2e043
Or define a column template which would take value from nested object:
http://snippet.dhtmlx.com/9e8e65e85
please check the console output for a result dataset

How to Get data in Json using javascripts?

Hi I'm currently creating an application to gather data form a website, and as I've researched you can used Json for that, now I have created a script to gather data, at first i have no problem with it, but when I cam across with a multi tree json i started having trouble.
here is my Json
{
"orders": [
{
"line_items": [
{
"id": 7660469767,
"name": "Personalised design - purple",
"properties": [
{
"name": "personalised text 1",
"value": "2"
},
{
"name": "personalised text 2",
"value": "Nuri &"
},
{
"name": "personalised text 3",
"value": "Samira"
}
],
}
]
}
]
}
I need to get the order.line_items.properties.value.
I tried this code but it says it does not work.
$.getJSON(order.json, function (data) {
$.each(data.orders.line_items.properties, function (index, value) {
$.each(this.value, function () {
console.log(this.text);
});
});
});
Can someone help me?
$.each(data.orders[0].line_items[0].properties, function (index, value) {
console.log(value.value);
});
Both orders and line_items are array, so it should have an access to array index first before accessing other object. And you don't have to use extra each in your code. The value above is an object for each properties. You can retrieve value there.

Multi-Facing Tree Layout and Reformatting JSON

I'm working on a tree layout like this one: http://www.robschmuecker.com/d3-js-drag-and-drop-zoomable-tree/ that is based off mbostock's original design (http://mbostock.github.io/d3/talk/20111018/tree.html).
I'm having 3 issues with it. I'd like to be able to extend the branches both left and right of the root - in other words I'd like to be able to mirror what the sample looks like.
The second issue I'm having is that the flare.json file for this format needs to be in a very specific format - it needs to look exactly like this
{
"children": [
{
"children": [
{},
{}
]
}
]
}
While mine looks approximately like
"head": {
"title": "titleHere",
"ownerName": "nameHere
},
"body": {
"outline": [
{
"outline": [
{
"_text": "A"
},
{
"_text": "B"
},
{
"_text": "C"
},
{
"_text": "D"
},
{
"_text": "E"
}
],
"_text": "Category Header"
},
{
},
}
I basically need to write an algorithm that re-formats what I have into the correct format so I can feed it into my tree layout, if that makes sense.
The final issue I'd like to work on is to be able to edit the text by double-clicking on the tree chart.

Populate AngularJS {{expression}} within ng-repeat using a second array

I'm completely rebuilding my website (originally hacked together with Wordpress) using Laravel and AngularJS. It's been a massive learning experience and I think I'm nearly there but for one problem.
On my site 'schemes' (or courses) are made up of 'units' which are made up of 'lessons'. Retrieving this data is fine, using Eloquent I retrieve valid JSON like this made up example...
[
{
"id": "1", //Scheme Id
"title": "Sports",
"description": "This is a Sports course!",
"units": [
{
"id": "1",
"title": "Tennis",
"lessons": [
{
"id": "6",
"title": "Serving"
},
{
"id": "7",
"title": "Hitting the ball with top-spin"
}
]
},
{
"id": "2",
"title": "Athletics",
"lessons": [
{
"id": "1",
"title": "Long Jump"
},
{
"id": "2",
"title": "Hurdling Technique"
}
]
},
{
"id": "4",
"title": "Golf",
"lessons": [
{
"id": "4",
"title": "Pitching"
},
{
"id": "5",
"title": "Putting"
}
]
}
]
}
....
]
Separately I have a simple array of completed lesson ids for a particular user like this...
[2, 6, 8, 9] ///User has completed lessons with ids of 2,6,8 and 9
In my view I'm using nested ng-repeat loops like so...
...
<div ng-controller="SchemesController">
<div ng-repeat="scheme in schemes">
<h1>{{scheme.title}}</h1>
<div ng-repeat="unit in scheme.units">
<h3>{{unit.title}}</h3>
<div ng-repeat="lesson in unit.lessons">
<div>{{lesson.title}}: {{status}}</div>
</div>
</div>
</div>
</div><!--[end of ng-controller="SchemesController"]-->
....
SchemesController (v simple!) looks like this...
var app = angular.module('schemesApp', []);
app.controller('SchemesController', function($scope){
$scope.schemes=jsonData;
});
The problem is I have no idea how to populate the {{status}} field which I want to state simply 'Complete' or 'Incomplete. I investigated whether I could somehow add this info to my original array like this...
"lessons": [
{
"id": "6",
"title": "Serving",
"status": "Complete" //populated somehow
},
{
"id": "7",
"title": "Hitting the ball with top-spin",
}
]
but I got nowhere slowly. Is there a way to do this (I've played around with underscore.js and felt this could help?).
Or do I populate {{status}} from creating and calling a javascript function?!?
ANY help that anyone could offer would be incredible. I'm a school teacher and for some sadistic reason I find a bit of programming/web design a fun use of my spare time so I apologise if this is a stupid question. THANKS in advance!!!
btw if anyone has a better 'title' for this question then please let me know.
I'm assuming you don't need to persist the status back to the database...
This is where you're having the problem:
<div>{{lesson.title}}: {{status}}</div>
You really don't need to store the status in your data model, because it's just used for presentation purposes.
Let's say your array of completed lessons is defined like this:
$scope.completedLessons = [1, 2, 3, 4, 5] // Or however you'd assign it
You need to create a function in your scope like this:
$scope.isLessonCompleted = function(lessonId) {
return $scope.completedLessons.indexOf(lessonId) > -1;
};
Then you need to change the html from above to this:
<div>{{lesson.title}}: {{isLessonCompleted(lesson.id) && 'Complete' || 'Incomplete'}}</div>
If lessons are also a model and each lesson should have a status, which isn't a column/field in your table but is something you'll add logic to determine, you could add a custom model accessor by adding the following to your models/Lesson.php:
// Append custom accessor attributes
protected $appends = ['status'];
public function getStatusAttribute() {
// Add logic here
return 'Complete';
}
This way, when you use Eloquent to retrieve your data, you'll also see a status attribute as part of the object, so you could then access it as usual $lesson->status (PHP) or lesson.status (JS).
For more information, see the official Laravel documentation on accessors and mutators

JavaScript -- split off one branch of a hierarchical array or JSON object

I have a JSON object that is a nested array that is of the following form:
{
"name": "Math",
"children": [
{
"name": "Trigonometry",
"children": [
{
"name": "Right Triangles and an Introduction to Trigonometry",
"children": [
{
"name": "The Pythagorean Theorem",
"children": [
{
"name": "The Pythagorean Theorem",
"size": 30
},
{
"name": "Pythagorean Triples",
"size": 52
},
{
"name": "Converse of the Pythagorean Theorem",
"size": 13
}
]
}
]
}
]
},
{
"name": "Algebra",
"children": [
{
"name": "Equations and Functions",
"children": [
{
"name": "Variable Expressions",
"children": [
{
"name": "Evaluate Algebraic Expressions",
"size": 26
}
]
}
]
}
]
}
]
}
The full array is actually much larger and can be seen here. I'm using it to build interactive graphs and charts using D3.js (or perhaps other libraries). Because it's so large, I'd like to be able to split the array by branch. In other words, to carve out particular branches of the array.
For instance, is there a way to just pull out the node "Trigonometry" and all its children? Or "Algebra" and all its children? Then "Trigonometry" or "Algebra" would become the new root or parent node.
There is no built-in way to do something like this, although the comment about a JSON query language might give you the right work-around.
Really, the problem is that you have structured your data in a way that makes it very hard to use. If instead of
{
name: "key",
children: [...]
}
you just did
{
"key": [...]
}
then you could simply do myObject["key"] to get the array you want.
For example:
var math = {
"Trigonometry": {
"Right Triangles and an Introduction to Trigonometry": {
"The Pythagorean Theorem": {
"The Pythagorean Theorem": 30,
"Pythagorean Triples": 52,
"Converse of the Pythagorean Theorem": 13
}
}
},
"Algebra": {
"Equations and Functions": {
"Variable Expressions": {
"Evaluate Algebraic Expressions": 26
}
}
}
};
var trigonometry = math["Trigonometry"];
var expressionsAndFunctions = math["Algebra"]["Expressions and Functions"];
As a bonus, that's much shorter!
Array's splice function should do it. What that will do is remove the element at a given index and return it.
If you just want a shortcut to a specific branch, couldn't you also just use
var trig = tree['trigonometry'];
to get there. This wouldn't change the original object, buy will give you a simpler way to access nodes deep inside.

Categories

Resources