D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
renecnielsen
Full window
Github gist
Swimlane
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> <title>Swimlane Chart</title> <script type="text/javascript" src="https://d3js.org/d3.v3.min.js"></script> <link rel="stylesheet" href="style.css" type="text/css"> <link href='https://fonts.googleapis.com/css?family=Open+Sans:300' rel='stylesheet' type='text/css'> </head> <body> <script type="text/javascript"> //data var lanes = ["Phase I","Phase II","Phase III","Phase IV","Phase V","Phase VI"], laneLength = lanes.length, items = [{"lane": 0, "id": "Item 1", "start": 5, "end": 205}, {"lane": 0, "id": "Item 2", "start": 265, "end": 420}, {"lane": 0, "id": "Item 3", "start": 580, "end": 615}, {"lane": 0, "id": "Item 4", "start": 620, "end": 900}, {"lane": 0, "id": "Item 5", "start": 960, "end": 1265}, {"lane": 0, "id": "Item 6", "start": 1270, "end": 1365}, {"lane": 0, "id": "Item 7", "start": 1370, "end": 1640}, {"lane": 0, "id": "Item 8", "start": 1645, "end": 1910}, {"lane": 1, "id": "Item 9", "start": 300, "end": 530}, {"lane": 1, "id": "Item 10", "start": 550, "end": 700}, {"lane": 1, "id": "Item 11", "start": 710, "end": 790}, {"lane": 1, "id": "Item 12", "start": 800, "end": 1180}, {"lane": 1, "id": "Item 13", "start": 1190, "end": 1330}, {"lane": 1, "id": "Item 14", "start": 1340, "end": 1560}, {"lane": 1, "id": "Item 15", "start": 1610, "end": 1860}, {"lane": 1, "id": "Item 16", "start": 1870, "end": 1900}, {"lane": 1, "id": "Item 17", "start": 1910, "end": 1920}, {"lane": 1, "id": "Item 18", "start": 1925, "end": 1985}, {"lane": 1, "id": "Item 19", "start": 1990, "end": 1995}, {"lane": 2, "id": "Item 20", "start": 10, "end": 670}, {"lane": 2, "id": "Item 21", "start": 690, "end": 900}, {"lane": 2, "id": "Item 22", "start": 920, "end": 1380}, {"lane": 2, "id": "Item 23", "start": 1390, "end": 1890}, {"lane": 2, "id": "Item 24", "start": 1900, "end": 1945}, {"lane": 3, "id": "Item 25", "start": 5, "end": 205}, {"lane": 3, "id": "Item 26", "start": 265, "end": 420}, {"lane": 3, "id": "Item 27", "start": 580, "end": 615}, {"lane": 3, "id": "Item 28", "start": 620, "end": 900}, {"lane": 3, "id": "Item 29", "start": 960, "end": 1265}, {"lane": 3, "id": "Item 30", "start": 1270, "end": 1365}, {"lane": 3, "id": "Item 31", "start": 1370, "end": 1640}, {"lane": 3, "id": "Item 32", "start": 1645, "end": 1910}, {"lane": 4, "id": "Item 33", "start": 300, "end": 530}, {"lane": 4, "id": "Item 34", "start": 550, "end": 700}, {"lane": 4, "id": "Item 35", "start": 710, "end": 790}, {"lane": 4, "id": "Item 36", "start": 800, "end": 1180}, {"lane": 4, "id": "Item 37", "start": 1190, "end": 1330}, {"lane": 4, "id": "Item 38", "start": 1340, "end": 1560}, {"lane": 4, "id": "Item 39", "start": 1610, "end": 1860}, {"lane": 4, "id": "Item 40", "start": 1870, "end": 1900}, {"lane": 4, "id": "Item 41", "start": 1910, "end": 1920}, {"lane": 4, "id": "Item 42", "start": 1925, "end": 1985}, {"lane": 4, "id": "Item 43", "start": 1990, "end": 1995}, {"lane": 5, "id": "Item 44", "start": 10, "end": 670}, {"lane": 5, "id": "Item 45", "start": 690, "end": 900}, {"lane": 5, "id": "Item 46", "start": 920, "end": 1380}, {"lane": 5, "id": "Item 47", "start": 1390, "end": 1890}, {"lane": 5, "id": "Item 48", "start": 1900, "end": 1945}] timeBegin = 0, timeEnd = 2000; </script> <script type="text/javascript"> var m = [20, 15, 15, 120], //top right bottom left w = 960 - m[1] - m[3], h = 500 - m[0] - m[2], miniHeight = laneLength * 12 + 50, mainHeight = h - miniHeight - 50; //scales var x = d3.scale.linear() .domain([timeBegin, timeEnd]) .range([0, w]); var x1 = d3.scale.linear() .range([0, w]); var y1 = d3.scale.linear() .domain([0, laneLength]) .range([0, mainHeight]); var y2 = d3.scale.linear() .domain([0, laneLength]) .range([0, miniHeight]); var chart = d3.select("body") .append("svg") .attr("width", w + m[1] + m[3]) .attr("height", h + m[0] + m[2]) .attr("class", "chart"); chart.append("defs").append("clipPath") .attr("id", "clip") .append("rect") .attr("width", w) .attr("height", mainHeight); var main = chart.append("g") .attr("transform", "translate(" + m[3] + "," + m[0] + ")") .attr("width", w) .attr("height", mainHeight) .attr("class", "main"); var mini = chart.append("g") .attr("transform", "translate(" + m[3] + "," + (mainHeight + m[0]) + ")") .attr("width", w) .attr("height", miniHeight) .attr("class", "mini"); //main lanes and texts main.append("g").selectAll(".laneLines") .data(items) .enter().append("line") .attr("x1", m[1]) .attr("y1", function(d) {return y1(d.lane);}) .attr("x2", w) .attr("y2", function(d) {return y1(d.lane);}) //.attr("stroke", "#96999b") //Uncomment to insert lines between lanes ; main.append("g").selectAll(".laneText") .data(lanes) .enter().append("text") .text(function(d) {return d;}) .attr("x", -m[1]) .attr("y", function(d, i) {return y1(i + .5);}) .attr("dy", ".5ex") .attr("text-anchor", "end") .attr("class", "laneText"); //mini lanes and texts mini.append("g").selectAll(".laneLines") .data(items) .enter().append("line") .attr("x1", m[1]) .attr("y1", function(d) {return y2(d.lane);}) .attr("x2", w) .attr("y2", function(d) {return y2(d.lane);}) //.attr("stroke", "#96999b") //Uncomment to insert lines between lanes ; mini.append("g").selectAll(".laneText") .data(lanes) .enter().append("text") .text(function(d) {return d;}) .attr("x", -m[1]) .attr("y", function(d, i) {return y2(i + .5);}) .attr("dy", ".5ex") .attr("text-anchor", "end") .attr("class", "laneText"); var itemRects = main.append("g") .attr("clip-path", "url(#clip)"); //mini item rects mini.append("g").selectAll("miniItems") .data(items) .enter().append("rect") .attr("class", function(d) {return "miniItem" + d.lane;}) .attr("x", function(d) {return x(d.start);}) .attr("y", function(d) {return y2(d.lane + .5) - 5;}) .attr("width", function(d) {return x(d.end - d.start);}) .attr("height", 10); //mini labels mini.append("g").selectAll(".miniLabels") .data(items) .enter().append("text") .text(function(d) {return d.id;}) .attr("x", function(d) {return x(d.start);}) .attr("y", function(d) {return y2(d.lane + .5);}) .attr("dy", ".5ex"); //brush var brush = d3.svg.brush() .x(x) .on("brush", display); mini.append("g") .attr("class", "x brush") .call(brush) .selectAll("rect") .attr("y", 1) .attr("height", miniHeight - 1); display(); function display() { var rects, labels, minExtent = brush.extent()[0], maxExtent = brush.extent()[1], visItems = items.filter(function(d) {return d.start < maxExtent && d.end > minExtent;}); mini.select(".brush") .call(brush.extent([minExtent, maxExtent])); x1.domain([minExtent, maxExtent]); //update main item rects rects = itemRects.selectAll("rect") .data(visItems, function(d) { return d.id; }) .attr("x", function(d) {return x1(d.start);}) .attr("width", function(d) {return x1(d.end) - x1(d.start);}); rects.enter().append("rect") .attr("class", function(d) {return "miniItem" + d.lane;}) .attr("x", function(d) {return x1(d.start);}) .attr("y", function(d) {return y1(d.lane) + 10;}) .attr("width", function(d) {return x1(d.end) - x1(d.start);}) .attr("height", function(d) {return .8 * y1(1);}); rects.exit().remove(); //update the item labels labels = itemRects.selectAll("text") .data(visItems, function (d) { return d.id; }) .attr("x", function(d) {return x1(Math.max(d.start, minExtent) + 2);}); labels.enter().append("text") .text(function(d) {return d.id;}) .attr("x", function(d) {return x1(Math.max(d.start, minExtent));}) .attr("y", function(d) {return y1(d.lane + .5);}) .attr("text-anchor", "start"); labels.exit().remove(); } </script> </body> </html>
Modified
http://d3js.org/d3.v3.min.js
to a secure url
https://d3js.org/d3.v3.min.js