2

I am new with d3 and json. I am trying to construct a horizontal gantt chart. Earlier I have acieved the same using inline arrays which i stored in var dataset. But now I have replaced the arrays with json object array .

[   {
        "process" :"process-name 1",
        "stage" : "stage name 1",
        "activities": [
            {
            "activity_name": "waiting",
            "start": new Date('2012-12-10T06:45+05:30'),
            "end": new Date('2012-10-10T08:45+05:30'),
            },
            {
            "activity_name": "processing",
            "start": new Date('2012-10-11T05:45+05:30'),
            "end": new Date('2012-10-11T06:45+05:30'),
            },
            {
            "activity_name": "pending",
            "start": new Date('2012-10-12T11:45+05:30'),
            "end": new Date('2012-10-13T12:45+05:30'),
            }
            ]

    },
    {
        "process" :"process-name 2",
        "stage" : "stage name 2",
        "activities": [
            {
            "activity_name": "waiting",
            "start": new Date('2012-10-22T06:45+05:30'),
            "end": new Date('2012-10-23T08:45+05:30'),
            },
            {
            "activity_name": "processing",
            "start": new Date('2012-10-25T05:45+05:30'),
            "end": new Date('2012-10-25T06:45+05:30'),
            },
            {
            "activity_name": "pending",
            "start": new Date('2012-10-27T11:45+05:30'),
            "end": new Date('2012-10-27T12:45+05:30'),
            }
            ]
    }       

    ];

The d3 part of the code to draw the rectangle is this :

console.log(dataset);

var height = 600;
var width = 500;
var x = d3.time.scale().domain([new Date(2011, 0, 1,23,33,00), new Date(2013, 0, 1, 23, 59)]).range([0, width]);



var svg = d3.selectAll("body")
.append("svg")
.attr("width",width)
.attr("height",height)
.attr("shape-rendering","crispEdges");


temp = svg.selectAll("body")
.data(dataset) // LINE 1 
.enter()


temp.append("rect")
.attr("width", 4)
.attr("height",12)
.attr("x", function(d) {return x(d.activities[0].start)}) // LINE 2
.attr("y",function(d,i){return i*10;})
.attr("fill","steelblue");

I have following questions :

  1. I want to access START date inside activities but with the code lines (marked LINE 1 and LINE 2) I have written it is giving only 2 rectangles for first start of each activity . WHY?

  2. In LINE 1 can I use dataset.actitvies instead of just dataset? I tried using that , gave me this error :

Uncaught TypeError: Cannot read property '0' of undefined

1 Answer 1

3
  1. Because the length of dataset is 2, so when you join it with your rects you're only going to get 2 rects.

  2. You can use dataset.activities, but you would change LINE 2 to

    .attr("x", function(d) {return x(d.start)})

because you've changed the join so that d now refers to the activities. However, if you do that, you're just going to get three rectangles -- the activities for one of your projects.

If you're going to use nested data, you either need to use a nested selection or you need to flatten the data first by adding all activities to a simple array.

var data = [];

for (var i = 0, len = dataset.length; i < len; i++) {
    data = data.concat(dataset[i].activities);
}

A nested selection would look something like this:

projects = svg.selectAll("g")
    .data(dataset)
  .enter().append("g")
    .attr("transform", function (d, i) { return "translate(0," + (i * 10) + ")"; }),

rects = projects.selectAll("rect")
    .data(function (d) { return d.activities; })
  .enter().append("rect")
    .attr("height", 12)
    .attr("width", 4)
    .attr("x", function (d) { return x(d.start); })

EDIT: here's a jsfiddle

Sign up to request clarification or add additional context in comments.

2 Comments

Just one question . The place where you wrote this .data(function (d) { return d.activities; }) I wrote .data(d.activities) but it was giving back unidentified objects why ?
Good to hear! Please accept the answer so it shows up as answered. bost.ocks.org/mike/nest will give you an overview on nested selections. Basically, you join the groups to the dataset, and then define an accessor function for the rects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.