javascript - Creat gantt chart from d3.js -
this kind of data have:
[ {'totaltime': 10, 'hour': 0, 'name': 'sam'}, {'totaltime': 15, 'hour': 1, 'name': 'bob'}, {'totaltime': 300, 'hour': 2, 'name': 'tom'}, ... , on till, {'totaltime': 124, 'hour': 23, 'name': 'jon'} ]
data every hour of day. , wish create gantt chart size of bars based on totaltime.
names on y axis , hour on x.
is possible make gantt chart without start time , end time on d3.js?
it's possible, you'd need draw if you're using d3.js. if you've made bar charts before, along lines, setup axes, add them svg , use them convert data rectangles you'll put on chart, label rects names data. d3.js not include layout this. if haven't done already, go through tutorials: let’s make bar chart, parts i, ii & iii, move on looking @ custom time axis example, , related apis.
there many other libraries build on d3.js, c3 provide prefab charts (like d3's layouts) i'm not aware of 1 gantt style charts. there one example gantt chart out there (that randomly adds tasks various scaled time views 1 hour 1 week) found more confusing own time blocks below. ymmv.
i made more calendar looking chart d3js can read through here: https://github.com/dlamblin/timeblocks. you've got different input data formatting, adapt in pinch , swap axes rotation. assuming you're willing urgently asap.
to make aforementioned easier read & view took apart jsfiddle example.
and here's javascript inlined answer (this not gantt chart, it's vertical layout of scheduled blocks of time on 7 day week):
var timefmt = d3.time.format.utc('%h.%m'), weekdaydef = 'mon tue wed thu fri sat sun'.split(' '), weekdayseq = 'mon tue wed thu fri sat sun'.split(' '), axes = [null, null, null, null]; function hm(i) { var s = i.tofixed(2); return timefmt.parse((s.length < 4) ? '0' + s : s); } var timedata = [ {key: "m1","wday": 0,"begin": hm(6.00),"end": hm(7.00), label: "rising, dress etc\n\retc"}, {key: "m2","wday": 0,"begin": hm(7.00),"end": hm(7.30), label: "prep sophie"}, {key: "m3","wday": 0,"begin": hm(7.30),"end": hm(8.00), label: "transit school" }, { key: "t1", "wday": 1, "begin": hm(6.00), "end": hm(7.00), label: "rising, dress etc" }, { key: "t2", "wday": 1, "begin": hm(17.00), "end": hm(18.00), label: "call" }, { key: "w1", "wday": 2, "begin": hm(6.00), "end": hm(7.00), 'color': 0, label: "rising, dress etc" }, { key: "w2", "wday": 2, "begin": hm(7.00), "end": hm(7.30), 'color': 0, label: "prep sophie" }, { key: "w3", "wday": 2, "begin": hm(7.30), "end": hm(8.00), 'color': 1, label: "transit school" }, { key: "w4", "wday": 2, "begin": hm(8.00), "end": hm(9.00), 'color': 2, label: "read emails" }, { key: "w5", "wday": 2, "begin": hm(9.00), "end": hm(10.00), 'color': 2, label: "write emails" }, { key: "w6", "wday": 2, "begin": hm(10.00), "end": hm(13.00), 'color': 3, label: "job" }, { key: "w7", "wday": 2, "begin": hm(13.00), "end": hm(14.00), 'color': 4, label: "lunch & meditation" }, { key: "w8", "wday": 2, "begin": hm(14.00), "end": hm(15.00), 'color': 5, label: "pick sophie & home" }, { key: "w9", "wday": 2, "begin": hm(15.00), "end": hm(18.00), 'color': 0, label: "clean" }, { key: "wa", "wday": 2, "begin": hm(18.00), "end": hm(19.00), 'color': 0, label: "plan" }, { key: "wb", "wday": 2, "begin": hm(19.00), "end": hm(20.00), 'color': 0, label: "wrap: read email & clean" }, { key: "r1", "wday": 3, "begin": hm(6.00), "end": hm(7.00), label: "rising, dress etc" }, { key: "f1", "wday": 4, "begin": hm(6.00), "end": hm(7.00), label: "rising, dress etc" } ]; timedata = timedata.sort(function(a, b) { var o = d3.ascending(a.wday, b.wday); return o === 0 ? d3.ascending(a.begin, b.begin) : o; }); // spacing out times 5 minutes... see display // var timedatamap = d3.map(timedata, function(d) {return d.key;}); // timedatamap.foreach(function(k,v) {v.end.setminutes(v.end.getminutes()-5);}); // timedata = timedatamap.values(); var scale, colors = d3.scale.category10(); colors.range(d3.range(10).map( function(i) { return d3.rgb(colors(i)).brighter(1.25).tostring(); })); function d3updatescales() { var svg = d3.select('#timeblock')[0][0], margin = { top: 25, right: 80, bottom: 25, left: 80 }, width = svg.clientwidth - margin.left - margin.right, height = svg.clientheight - margin.top - margin.bottom; return scale = { margin: margin, width: width, height: height, time: d3.time.scale.utc() // not d3.scale.linear() .domain([d3.min(timedata, function(d) { return d.begin }), d3.max(timedata, function(d) { return d.end }) ]) .rangeround([0, height]), days: d3.scale.ordinal() .domain(weekdayseq) .rangepoints([0, width]), week: d3.scale.ordinal() .domain(weekdayseq) .rangeroundbands([0, width], 0.05), } } function d3update() { var scale = d3updatescales(); // update… var svg = d3.select('#timeblock'); if (svg.select('g.view')[0][0] == null) { svg.append('g').attr('class', 'view').attr('transform', 'translate(' + scale.margin.left + ',' + scale.margin.top + ')'); } var g = svg.select('g.view').selectall('g.data') .data(timedata); // enter… var ge = g.enter() .append("g") .attr('class', 'data'); ge.append("rect") .attr("x", function(d) { return scale.week(weekdaydef[d.wday]) + (scale.week.rangeband() / 2) }) .attr("y", function(d) { var e = new date(d.end); e.setminutes(e.getminutes() - 5); return scale.time(d.begin) + ((scale.time(e) - scale.time(d.begin)) / 2) }) .attr("width", 0) .attr("height", 0) .attr("style", function(d) { return ("color" in d) ? "fill:" + colors(d.color) : null }) ge.append("text") .attr("dy", "1.1em") .text(function(d) { return d.label; }); // exit… g.exit().remove(); // update… g.select("rect") .transition() .attr("x", function(d) { return scale.week(weekdaydef[d.wday]) }) .attr("y", function(d) { return scale.time(d.begin) }) .attr("width", function(d) { return scale.week.rangeband() }) .attr("height", function(d) { var e = new date(d.end); e.setminutes(e.getminutes() - 5); return (scale.time(e) - scale.time(d.begin)) }) g.select("text") .transition() .attr("x", function(d) { return scale.week(weekdaydef[d.wday]) + 5 }) .attr("y", function(d) { return scale.time(d.begin) }); axesaddorupdate(svg); } function axesaddorupdate(svg) { var xaxis_t = d3.svg.axis().scale(scale.week).ticksize(13).orient('top'), yaxis_r = d3.svg.axis().scale(scale.time).ticksize(7).orient('right'), xaxis_b = d3.svg.axis().scale(scale.week).ticksize(13), yaxis_l = d3.svg.axis().scale(scale.time).ticksize(7).orient('left'); // global axes array contains top, right, bottom, left axis. if (null == axes[0]) { axes[0] = svg.append("g").attr('class', 'axis') .attr('transform', 'translate(' + string(scale.margin.left) + ',' + string(scale.margin.top) + ')') .call(xaxis_t); } else { axes[0].transition().call(xaxis_t); } if (null == axes[2]) { axes[2] = svg.append("g").attr('class', 'axis') .attr('transform', 'translate(' + string(scale.margin.left) + ',' + string(scale.height + scale.margin.top) + ')') .call(xaxis_b); } else { axes[2].transition().call(xaxis_b); } if (null == axes[3]) { axes[3] = svg.append("g").attr('class', 'axis') .attr('transform', 'translate(' + string(scale.margin.left - 5) + ',' + string(scale.margin.top) + ')') .call(yaxis_l); } else { axes[3].transition().call(yaxis_l); } if (null == axes[1]) { axes[1] = svg.append("g").attr('class', 'axis') .attr('transform', 'translate(' + string(scale.margin.left + scale.width + 5) + ',' + string(scale.margin.top) + ')') .call(yaxis_r); } else { axes[1].transition().call(yaxis_r); } } window.onload = d3update; d3.select('#b_rotate').on("click", function(d, i, t) { weekdayseq.push(weekdayseq.shift()); d3update(); });
Comments
Post a Comment