I took this code off the web and it works correctly. I need to load the data from a json instead of the data being coded into the page. Being new to this, I decide to first simply take the original data and put it in a json file and call the file. I can't seem to get it to work. I get a blank section where the graph would go and all I get from debugger is "mutating the prototype of an object will cause you code to run slowly", which I get with the original code so that's not it.
Here is the section of the original code
function loadImage(){
if(LoadData){
root = {
"name": "Daniel Vinod", "imageURL":"images/root.png","id":"1",
"children": [
{"name": "Abraham Aaron", "imageURL":"images/user1.png","id":"2",
"children":[{"name": "Joseph Titus", "imageURL":"images/user3.png","id":"3"},
{"name": "Herold Enoch", "imageURL":"images/user4.png","id":"4"}]},
{"name": "Samuel Goliatf", "imageURL":"images/user7.png","id":"5",
"children":[{"name": "Enoch Titus", "imageURL":"images/user2.png","id":"6"},
{"name": "Quintus Titus", "imageURL":"images/user5.png","id":"7"}]},
{"name": "Absalom Dauid", "imageURL":"images/user2.png","id":"8" ,
"children":[{"name": "Abraham Shalom", "imageURL":"images/user4.png","id":"9"},
{"name": "Elisha Titus", "imageURL":"images/user6.png","id":"10"}]},
{"name": "Daniel Goliatf", "imageURL":"images/user3.png","id":"12",
"children":[{"name": "Quintus Titus", "imageURL":"images/user5.png","id":"13"},
{"name": "Enoch Titus", "imageURL":"images/user1.png","id":"14"},
{"name": "Elisha Titus", "imageURL":"images/user6.png","id":"15",
"children":[ {"name": "Enoch Absalom", "imageURL":"images/user1.png","id":"11"}]}]},
{"name": "Enoch Shalom", "imageURL":"images/user5.png","id":"16",
"children":[{"name": "Absalom Joseph", "imageURL":"images/user7.png","id":"17"},
{"name": "Shalom Joseph", "imageURL":"images/user4.png","id":"18"},
{"name": "Quintus Titus", "imageURL":"images/user5.png","id":"7"}]}
]
};
force = d3.layout.force()
.on("tick", tick)
.size([w, h]);
vis = d3.select("#chart").append("svg:svg")
.attr("width", w)
.attr("height", h);
update();
LoadData = false;
}
}
I swapped the data for this
function loadImage(){
if(LoadData){
root = d3.json("data2.json", function(error, graph) {
if (error) throw error;
force = d3.layout.force()
.on("tick", tick)
.size([w, h]);
vis = d3.select("#chart").append("svg:svg")
.attr("width", w)
.attr("height", h);
update();
LoadData = false;
});
}
}
And created a data2.json file:
{
"name": "Daniel Vinod", "imageURL":"images/root.png","id":"1",
"children": [
{"name": "Abraham Aaron", "imageURL":"images/user1.png","id":"2",
"children":[{"name": "Joseph Titus", "imageURL":"images/user3.png","id":"3"},
{"name": "Herold Enoch", "imageURL":"images/user4.png","id":"4"}]},
{"name": "Samuel Goliatf", "imageURL":"images/user7.png","id":"5",
"children":[{"name": "Enoch Titus", "imageURL":"images/user2.png","id":"6"},
{"name": "Quintus Titus", "imageURL":"images/user5.png","id":"7"}]},
{"name": "Absalom Dauid", "imageURL":"images/user2.png","id":"8" ,
"children":[{"name": "Abraham Shalom", "imageURL":"images/user4.png","id":"9"},
{"name": "Elisha Titus", "imageURL":"images/user6.png","id":"10"}]},
{"name": "Daniel Goliatf", "imageURL":"images/user3.png","id":"12",
"children":[{"name": "Quintus Titus", "imageURL":"images/user5.png","id":"13"},
{"name": "Enoch Titus", "imageURL":"images/user1.png","id":"14"},
{"name": "Elisha Titus", "imageURL":"images/user6.png","id":"15",
"children":[ {"name": "Enoch Absalom", "imageURL":"images/user1.png","id":"11"}]}]},
{"name": "Enoch Shalom", "imageURL":"images/user5.png","id":"16",
"children":[{"name": "Absalom Joseph", "imageURL":"images/user7.png","id":"17"},
{"name": "Shalom Joseph", "imageURL":"images/user4.png","id":"18"},
{"name": "Quintus Titus", "imageURL":"images/user5.png","id":"7"}]}
]
}
Note, no brackets, so it's not a true json but it doesn't work with the brackets either. Again, no error, just a white space where the graph should be. Thanks for the help in advance.
root is a variable in the original which points to the json object, which I suspect gets picked up and used in the update() function. In your 2nd example, you've defined root so it points to the json loading function, whereas graph is the pointer to the loaded json object. Rename root as jsonFunc and set root = graph; within the json loading function in your 2nd example, see if that works. If not, it's make a jsfiddle time.
Related
Got a question regarding AngularJS and a carousel menu. I've made an array and I have trouble inserting the data in my View.
Controller:
gameApp.controller('homeController', function($scope) {
// Gamemodelist is static. Put all the corresponding gamemodes in an array
$scope.gameModeList = [
{"name": "Waterworld", "contents": [
{"name": "Classic", "contents": [
{"name": "Level 1", "contents": [{"name": "beginner"}, {"name": "easy"},{"name": "intermediate"}, {"name": "ultimate"}]},
{"name": "Level 2", "contents": [{"name": "easy"}]}
]},
{"name": "Firemode", "contents": [
{"name": "Level 3", "contents": [{"name": "beginner"}]}
]},
{"name": "Watermode", "contents":[
{"name": "Level 4", "contents": [{"name": "introduction"}]}
]}
]},
{"name": "Fireworld", "contents": [
{"name": "Classic", "contents": [
{"name": "Level 1", "contents": [{"name": "Intro"}, {"name": "Beginner"}, {"name": "Intermediate"}]},
{"name": "Level 2", "contents": [{"name": "Beginner"}, {"name":"Intermediate"}]}
]},
{"name": "Fireworld", "contents": [
{"name": "Level 3", "contents": [{"name": "Beginner"}, {"name": "Intermediate"}]}
]}
]},
{"name": "Tutorial", "contents": [
{"name": "Basic Tutorial"}, {"name": "Battle Training"}
]}];
}
This array is basicly the menu itself. You see the first items in the array are the first items in the menu. And every array in the contents is the submenu and if there is a subsubmenu.
This is my controller. Now I'm new to Angular, and I've already mate routing and templating work. Got different controllers for the login screen and the options screen. But now I'm working on the homescreen, which features a menu and I'm quite uncertain what's my best step here. I've already decided that I don't want to use different pages like I'm doing with my login and options screen, because I feel that an array is more convenient, because it already features the ordering of the items and it's (imo) a bit more managable.
To the view then. I've already checked and I think I need to use ng-if to check if there are submenu's in the array and if so use ng-repeat to display the menu. But. I come from jQuery background, so my instinct was to display the list and make it work with CSS and jQuery to manipulate the DOM so the items are shown which I want them to show, I know (for sure) that thats how things work in Angular. I guess I need to check with the controller which items need to display?
<ul>
<li class="animate-repeat" ng-repeat="mode in gameModeList">
{{ mode.name }}
</li>
</ul>
Now I only get the first items in the list obviously. I guess I now have to get the contents of the item I click in the view?
While parsing inline JSON object with d3.json(obj, function(error, root), its working properly when I'm running it locally, but when I run on tomcat server I'm getting an XMLHttpparse error. I searched over the Internet. Answer that I found was CORS. But there was no clarity how to achieve this. Could you please help me?
var obj = {
"name": "vis",
"children": [
{
"name": "Votes",
"children": [
{"name": "200", "size": 200,"url":"1"},
{"name": "500", "size": 500,"url":"2"},
{"name": "300", "size": 300,"url":"3"},
{"name": "400", "size": 400,"url":"4"}
]
},
{
"name": "Reputation",
"children": [
{"name": "200", "size": 200},
{"name": "500", "size": 500},
{"name": "300", "size": 300},
{"name": "400", "size": 400}
]
},
{
"name": "Accepted Answer",
"children": [
{
"name": "encoder",
"children": [
{"name": "Accepted Answer", "size": 500}
]
}
]
}
]
};
d3.json(obj, function(error, root) {
alert('error '+error);
alert('root: '+root);
if (error) return console.log(error);
}
First, make sure you are passing in a URL as the first argument to d3.json().
Second, you need to configure Tomcat to support CORS. In version 7.0.41+, Tomcat includes a CORS filter. Add the filter to your web.xml file.
Here's the minimum configuration you need:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
See the documentation for more information and additional configuration options: http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#CORS_Filter
And here's a flowchart of request processing for this filter that may help you with setting up any additional parameters:
You are misunderstanding what d3.json is used for. d3.json makes an actual AJAX request (hence why in the documentation names the chapter as Requests) so it is literally trying to fetch that obj but can't because it doesn't need to. If you really want to use d3.json, you can move that JSON object into its own file and then reference it by doing d3.json(data.json, function(err, root)).
The result d3.json would return is literally the object you have declared. You can simply assign it to the variable name root.
Related question: d3 js - loading json without a http get
I am using this:
http://mbostock.github.io/d3/talk/20111018/partition.html
instead of d3.json("flare.json", function(root) {
how do i make it use the json file within the html, like say i have
var json = [{
"name": "flare",
"children": [
{"name": "analytics",
"children": [
{"name": "cluster","children": [{"name": "AgglomerativeCluster", "size": 3938},
{"name": "CommunityStructure", "size": 3812},
{"name": "HierarchicalCluster", "size": 6714},
{"name": "MergeEdge", "size": 743}
]
},
and i want to use this instead of an external json file, how do i achieve this?
Link to json file: http://mbostock.github.io/d3/talk/20111018/flare.json
Any JSFiddle example please?
Thank you.
You will achieve this by two method:
1.you can assign the JSON data to variable name then You can build any layout
2.use one function to get the JSON data
Fiddle for 1 solution
var root = json;
Fiddle for 2 solution
var root = getData();
var g = vis.selectAll("g")
.data(partition.nodes(root))
.enter().append("svg:g")
.attr("transform", function(d) { return "translate(" + x(d.y) + "," + y(d.x) + ")"; })
.on("click", click);
I am new to D3, so my project of D3 is a rough problem to me and I really do need some help, I have been search solutions for days.
The problem is, I want to draw a Hierarchical Bar Chart, every time one clicks a bar, the sub layout of that bar is shown, just like this one http://bl.ocks.org/mbostock/1283663, however, the value of parent node is the sum value of its children node. I want to set the parent value by myself and keep the layout. The json file is:
{
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{"name": "AgglomerativeCluster", "size": 3938},
{"name": "CommunityStructure", "size": 3812},
{"name": "HierarchicalCluster", "size": 6714},
{"name": "MergeEdge", "size": 743}
]
},
I want to edit the parent value, so I edit the file as :
{
"name": "flare",
"children": [
{
"name": "analytics",size:555555 //I want to set value by myself rather than the sum of children value
"children": [
{
"name": "cluster",
"children": [
{"name": "AgglomerativeCluster", "size": 3938},
{"name": "CommunityStructure", "size": 3812},
{"name": "HierarchicalCluster", "size": 6714},
{"name": "MergeEdge", "size": 743}
]
},
However, it does not work. Does anyone knows how to set parent's value? I searched for days and got nothing, hope you can help me, and I am appreciate your help!
Is your issue with using the parent element sizes to draw the bars? If so, you should scale everything (to say 0 to 100) and then multiply this by a constant to get the appropriate parent value. After all, if you edit each parent value, they won't necessarily be proportional.
Here's an example of a scale:
edit: (fixed the domain)
var myscale = d3.scale.linear()
.domain([0, maxParentWidth])
.range([0,y]); // .range([0,1]) is the default range
This will scale all the "parents" on the domain 0 to the largest parent value to a range of [0,y], where y is whatever you want (i.e., 100). Let's say you want the largest parent bar to be 300px. Now, all you have to do is multiply this scaled value by a constant, in this case, 3.
Using D3 Javascript and JSON, I need to create something very similar to:
http://bl.ocks.org/mbostock/4063550
The JSON file (copied from website) looks something like:
{
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{"name": "AgglomerativeCluster", "size": 3938},
{"name": "CommunityStructure", "size": 3812},
{"name": "HierarchicalCluster", "size": 6714},
{"name": "MergeEdge", "size": 743}
]
},
Now instead of the "size" in the code above, I have "score" (i.e. "score": 3).
What I want to achieve is the diagram similar to the website, but the difference is that is the score is over a certain threshold (e.g >5), I want the small blue circle to be of a certain color (i.e. red).
I know this needs to be updated in the index.html file, but I just don't know how to get around to doing that. Any pointers would be appreciated!
Thanks!
All you need to do this is to slightly modify the code that appends the circles. You need to change the snippet
node.append("circle")
.attr("r", 4.5);
to
node.append("circle")
.style("stroke", function(d) { return d.score > 5 ? "red" : "steelblue"; })
.attr("r", 4.5);
You can obviously apply something like this to e.g. the fill colour in the same way. If you have a larger number of different colours and thresholds, it might be worth investigating using a scale instead of a conditional statement.
Change your JSON like so:
{
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{"name": "AgglomerativeCluster", "score": 3938},
{"name": "CommunityStructure", "score": 3812},
{"name": "HierarchicalCluster", "score": 6714},
{"name": "MergeEdge", "score": 743}
]
},
Now use a function to check for the condition in the data and set the style for the circle:
node.append("circle")
.attr("r", 4.5)
.style("fill",function(d){
return ((d.score > 5)?"red":"blue");
});