d3js - simple rendering not works [closed] - javascript

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to create a simple list inforamtion using d3js, not works. any one figure-out the wrong what i do here?
var obj = {
"status": ["GOOD SERVICE"],
"name": ["123"],
"url": [null],
"text": ["..."],
"plannedworkheadline": [null],
"Time": [" 7:35AM"],
"Date": ["12/15/2011"]
}
function draw(data) {
"use strict";
d3.select("body")
.append("ul")
.selectAll("li")
.data(data)
.enter()
.append("li")
.text(function (d) {
return d.name + ": " + d.status;
});
};
d3.json(obj, draw);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

data must be an array.
var obj = [{
"status": ["GOOD SERVICE"],
"name": ["123"],
"url": [null],
"text": ["..."],
"plannedworkheadline": [null],
"Time": [" 7:35AM"],
"Date": ["12/15/2011"]
}]
function draw(data) {
"use strict";
d3.select("body")
.append("ul")
.selectAll("li")
.data(data)
.enter()
.append("li")
.text(function (d) {
return d.name + ": " + d.status;
});
};
draw(obj);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Related

How to run D3 javascript library to create horizontal chart

i am trying to run this code but some how it throws error i have created a json file that is saved in mine data folder i am calling this file. is there anyway to solve this problem
Here is mine code snippet
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
text-align: center;
}
svg {
margin-top: 32px;
border: 1px solid #aaa;
}
.person rect {
fill: #fff;
stroke: steelblue;
stroke-width: 1px;
}
.person {
font: 14px sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
</style>
<body>
<script src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
var boxWidth = 150,
boxHeight = 40;
// Setup zoom and pan
var zoom = d3.behavior.zoom()
.scaleExtent([.1,1])
.on('zoom', function(){
svg.attr("transform", "translate(" + d3.event.translate + ") scale(" + d3.event.scale + ")");
})
// Offset so that first pan and zoom does not jump back to the origin
.translate([150, 200]);
var svg = d3.select("body").append("svg")
.attr('width', 1000)
.attr('height', 500)
.call(zoom)
.append('g')
// Left padding of tree so that the whole root node is on the screen.
// TODO: find a better way
.attr("transform", "translate(150,200)");
var tree = d3.layout.tree()
// Using nodeSize we are able to control
// the separation between nodes. If we used
// the size parameter instead then d3 would
// calculate the separation dynamically to fill
// the available space.
.nodeSize([100, 200])
// By default, cousins are drawn further apart than siblings.
// By returning the same value in all cases, we draw cousins
// the same distance apart as siblings.
.separation(function(){
return .5;
})
// Tell d3 what the child nodes are. Remember, we're drawing
// a tree so the ancestors are child nodes.
.children(function(person){
return person._parents;
});
d3.json('Data/4gens.json', function(error, json){
if(error) {
return console.error(error);
}
var nodes = tree.nodes(json),
links = tree.links(nodes);
// Style links (edges)
svg.selectAll("path.link")
.data(links)
.enter().append("path")
.attr("class", "link")
.attr("d", elbow);
// Style nodes
var node = svg.selectAll("g.person")
.data(nodes)
.enter().append("g")
.attr("class", "person")
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
// Draw the rectangle person boxes
node.append("rect")
.attr({
x: -(boxWidth/2),
y: -(boxHeight/2),
width: boxWidth,
height: boxHeight
});
// Draw the person's name and position it inside the box
node.append("text")
.attr("dx", -(boxWidth/2) + 10)
.attr("dy", 0)
.attr("text-anchor", "start")
.attr('class', 'name')
.text(function(d) {
return d.name;
});
});
/**
* Custom path function that creates straight connecting lines.
*/
function elbow(d) {
return "M" + d.source.y + "," + d.source.x
+ "H" + (d.source.y + (d.target.y-d.source.y)/2)
+ "V" + d.target.x
+ "H" + d.target.y;
}
</script>
</body>
</html>
It throws error
d3.min.js:1 Access to XMLHttpRequest at 'file:///C:/Users/xyz34/Desktop/treant-js-master/Data/4gens.json' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
when i update the cdn to this https://cdnjs.cloudflare.com/ajax/libs/d3/5.12.0/d3.min.js
then it throws the following error
Uncaught TypeError: Cannot read property 'zoom' of undefined
at basic.html:39
Uncaught TypeError: Cannot read property 'tree' of undefined
at basic.html:48
here is mine json content
{
"name": "Maude Fernandez",
"id": "06ada7cd-3078-54bc-bb87-72e9d6f38abf",
"_parents": [
{
"name": "Janie Norton",
"id": "a39bfa73-6617-5e8e-9470-d26b68787e52",
"_parents": [
{
"name": "Pearl Cannon",
"id": "fc956046-a5c3-502f-b853-d669804d428f",
"_parents": [
{
"name": "Augusta Miller",
"id": "fa5b0c07-9000-5475-a90e-b76af7693a57"
},
{
"name": "Clayton Welch",
"id": "3194517d-1151-502e-a3b6-d1ae8234c647"
}
]
},
{
"name": "Nell Morton",
"id": "06c7b0cb-cd21-53be-81bd-9b088af96904",
"_parents": [
{
"name": "Lelia Hernandez",
"id": "667d2bb6-c26e-5881-9bdc-7ac9805f96c2"
},
{
"name": "Randy Welch",
"id": "104039bb-d353-54a9-a4f2-09fda08b58bb"
}
]
}
]
},
{
"name": "Helen Alvarado",
"id": "522266d2-f01a-5ec0-9977-622e4cb054c0",
"_parents": [
{
"name": "Gussie Glover",
"id": "da430aa2-f438-51ed-ae47-2d9f76f8d831",
"_parents": [
{
"name": "Mina Freeman",
"id": "d384197e-2e1e-5fb2-987b-d90a5cdc3c15"
},
{
"name": "Charlotte Martin",
"id": "ea01728f-e542-53a6-acd0-6f43805c31a3"
}
]
},
{
"name": "Jesus Pierce",
"id": "bfd1612c-b90d-5975-824c-49ecf62b3d5f",
"_parents": [
{
"name": "Donald Cox",
"id": "4f910be4-b827-50be-b783-6ba3249f6ebc"
},
{
"name": "Alex Gonzales",
"id": "efb2396d-478a-5cbc-b168-52e028452f3b"
}
]
}
]
}
]
}
Your code works fine, I created one html file and one json file with your code and data and it just works.
Based on the comment in the question:
d3.min.js:1 Access to XMLHttpRequest at 'file:///C:/Users/ptiwar34/Desktop/treant-js-master/Data/4gens.json' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https
This is a CORS problem. D3.js is not able to access to your data because it is in a different domain, and for security reasons, the browser blocks it.
You can solve that by running a HTTP server, here is a small guide on how to do it, there are also different alternatives, but in my case, that is the one that I find more comfortable.
Good luck.

Why the data can't be bind with JSON file?

This is JSON file named Unit2Vec_tSNE.json and we can get the data points from pos element.
{
"No 0": {
"dur": 135,
"name": "00000001_0",
"lab": "sil",
"pos": [
17.64800262451172,
-1.794445514678955
]
},
"No 1": {
"dur": 28,
"name": "00000001_1",
"lab": "uo",
"pos": [
-17.94196891784668,
-0.8764857649803162
]
},
"No 2": {
"dur": 21,
"name": "00000001_2",
"lab": "x",
"pos": [
2.7473323345184326,
13.970715522766113
]
}
}
The JavaScript code is the following and I try use .data(dataset) function to bind the JSON data to points.
But very strangely, it displays nothing and the console.log('Here!!!!!!!!!') of .attr("cx", function(d) doesn't run.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3: A simple scatterplot, setting radii from data</title>
<script type="text/javascript" src="../d3.js"></script>
<style type="text/css">
/* No style rules here yet */
</style>
</head>
<body>
<script type="text/javascript">
//Width and height
var w = 500;
var h = 100;
var dataset; // a global
d3.json("Unit2Vec_tSNE.json", function(error, json) {
if (error) return console.warn(error);
dataset = json;
visualize();
});
function visualize() {
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
console.log(dataset); //work at here
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", function(d) {
console.log('Here!!!!!!!!!'); //not work at here
return d.pos[0];
})
.attr("cy", function(d) {
return d.pos[1];
})
.attr("r", 1);
}
</script>
</body>
</html>
The points can't be seen and console.log('Here!!!!!!!!!'); doesn't run.
Why? How to fix it? Thanks.
I am a new man to D3.js. Because I want to use it do an interactive project for my AI experiment, so display this points (in real application, there are 450000 points) is needed.
It is because dataset is an object and not array.
Quoting the d3 API :
selection.data([data[, key]]) Joins the specified array of data with the selected elements
So, if you change the structure of your JSON accordingly, you will see that your console.log is correctly executed.
You will have to tweak your code though to make it compatible in order to display the circles.
Demo with a correct format for the dataset variable:
var dataset = [
{"No 0": {
"dur": 135,
"name": "00000001_0",
"lab": "sil",
"pos": [
17.64800262451172,
-1.794445514678955
]
}},
{"No 1": {
"dur": 28,
"name": "00000001_1",
"lab": "uo",
"pos": [
-17.94196891784668,
-0.8764857649803162
]
}},
{"No 2": {
"dur": 21,
"name": "00000001_2",
"lab": "x",
"pos": [
2.7473323345184326,
13.970715522766113
]
}}
];
//Width and height
var w = 500;
var h = 100;
visualize();
function visualize()
{
//Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
console.log(dataset); //work at here
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", function(d) {
console.log('Here!!!!!!!!!'); //work at here now too
// return d.pos[0]; // edit this according to the new structure
})
.attr("cy", function(d) {
// return d.pos[1]; // edit this according to the new structure
})
.attr("r", 1);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

D3.js - accessing data in nested array

I have a data array that looks like this:
var data = [
{
"key": "user",
"values": [
"roles",
"manager",
"otherRoles",
"reports",
"devices",
"coffees"
]
},
{
"key": "role",
"values": [
"assignments",
"members",
"otherMembers"
]
},
{
"key": "assignment",
"values": [
"roles"
]
},
{
"key": "Device",
"values": [
"owners",
"roles"
]
},
{
"key": "Coffee",
"values": [
"drinkers"
]
}
];
I am attempting to render tables from SVG rectangles where the table header is the "key" and the table rows are the "values". The only way I was able to make this work was to give a unique incremental class to each table (table0, table1 etc.) I know this is terrible and prevents me from easily accessing all tables in the future. Here is the pertinent code:
parentBox = svgContainer.selectAll('.table')
.data(data, function(d) {return d.key;})
.enter()
.append('g')
.attr('class', function(d, i) {
return "table" + i;
})
.attr("transform", function(d, i) {
return "translate(" + boxWidth*i + "," + rowHeight*i + ")";
});
I'd like to figure out the right way to access nested data in D3. Here is the code in its entirety: D3 Example
Turns out the solution just requires understanding selections better. I first created the parentBox container:
parentBox = svgContainer.selectAll('.table')
.data(data, function(d) {return d.key;})
.enter()
.append('g')
.attr('class', 'table') (etc.)
Then, when populating the table with rows I first selected the created tables, used the each method to loop through each table and create each row. The one trick was to use d3.select(this) to make sure the rows were created properly.
svgContainer.selectAll('.table')
.each(function (d, i) {
tableRows = d3.select(this).selectAll('.row')
.data(d.values)
.enter()
.append(g) (etc.)

jSon to D3js grouping data from nested arrays

I'm very new to doing anything with d3 and jSon. Here is a pice of data I'm trying to get out from json and I would just like to know if I'm even on the right path.
Basically each status group would have more servers inside than just one like at the moment and the idea would be to get rectangle graph for one server and list these nicely next to each other.
I've been reading a lot of tutorials and trying to browse for similiar kind of issues other people might've had, but so far had really no luck...
jSon data I'm trying to pull out
[
{
"status": "ok",
"servers":
[
{
"id": "VR01",
"servername": "Server_1",
"cpu": 45, "mem": 25,
"diskIO": 0, "bandwith": 200
}
]
},
{
"status": "attention",
"servers":
[
{
"id": "VR10",
"servername": "Server_10",
"cpu": 55, "mem": 35,
"diskIO": 1, "bandwith": 2000
}
]
},
{
"status": "warning",
"servers":
[
{
"id": "VR02",
"servername": "Server_02",
"cpu": 98, "mem": 85,
"diskIO": 1,
"bandwith": 2000
}
]
},
{
"status": "dead",
"servers":
[
{
"id": "VR20",
"servername": "Server_20",
"cpu": 0, "mem": 0,
"diskIO": 0,
"bandwith": 0
}
]
}
]
the D3 bit
<script>
var width = ("width", 1000);
var height = ("height", 800);
d3.json("mydata.json", function(data) {
var canvas = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
var status = function sortData(data){
for (i = 0; i < d.length; i++) {
if(d.status ==="ok")
canvas.selectAll("rect")
.data(d.server)
.enter()
.append("rect")
.attr("x", 25)
.attr("y", function(d, i){return 25 * i;})
.attr("fill", "purple")
}
}
})
</script>
Really appreciate any suggestions you might have!
I think that it would be better to use nested selections to create your dashboard.
// Create one group for each server group
var serverGroup = svg.selectAll('g')
.data(data)
.enter()
.append('g')
.attr('transform', function(d, i) { return 'translate(0, ' + 50 * i + ')');
// Create the inner elements for each group
var servers = serverGroup.selectAll('rect')
.data(function(d) { return d.servers; })
.enter()
.append('rect')
// ... more settings here ...
This will create three groups, one for each group of servers and translate each one vertically. Each group contains the group data, so we can use the group data to create elements inside each group. Also, you can add a title, background color and other settings for each group using this structure. This article contains the concepts that you need to work on your problem: How Selections Work. Regards,

Referencing json data in D3.js

Basically I'm doing a basic enough family tree where each person is represented by a with their own properties. One property is "a Marriage" tag with can have attributes such as "married", "single" etc. but "widowed" is dependant on whether their spouse is dead or not. I decided to work off "id_number" as the marriage reference as different people can have the same name.
Assuming I have json data which looks like this:
var people = [
{ "name": "John Doe", "id_number": 1, "date_of_death": "1984", "married": 2, "father": 0, "mother": 0},
{ "name": "Jane Doe", "id_number": 2, "date_of_death": "1994", "married": 1, "father": 0, "mother": 0}
];
var person = d3.select("body").append("div")
.data(people)
.enter()
.append("div")
.text(function (d) { return d.name; })
.attr("id", function (d) {
if (typeof(d.married) != "undefined"){
if (typeof(people[married].date_of_death) != "undefined"){ ## error occurs here
m_status = "married";
} else {
m_status = "widowed";
}
}else{
m_status = "single";
}
return m_status;
});
My question is what is the proper syntax to reference a separate line of data in the same json file?
I have a feeling nodes solves the issue but I have yet to get any example node code working locally even without any changes...

Categories