Reputation: 23
I am new to d3, I have referred some examples and have introduced swimlanes. I have updated the code with whatever I have tried so far, but I am stuck with one problem here.
var lanedata = [
{id: 0, label: "lane 0"},
{id: 1, label: "lane 1"},
{id: 2, label: "lane 2"},
{id: 3, label: "lane 3"},
{id: 4, label: "lane 4"},
{id: 5, label: "lane 5"},
{id: 6, label: "lane 6"},
];
var items_data = [
{id: 10, label: "lane 0", start: 0,end:3, lane:0, source:1,target:"col 1"},
{id: 11, label: "lane 0", start: 1,end:4, lane:0, source:2,target:"col 2"},
{id: 12, label: "lane 0", start: 5,end:3, lane:0, source:3,target:"col 3"},
{id: 13, label: "lane 0", start: 8,end:7, lane:0, source:4,target:"col 4"},
{id: 7, label: "lane 1", start: 0,end:8, lane:1, source:5,target:"col 5"},
{id: 8, label: "lane 1", start: 1,end:7, lane:1, source:6,target:"col 6"},
{id: 9, label: "lane 1", start: 5,end:8, lane:1, source:7,target:"col 7"},
{id: 14, label: "lane 1", start: 8,end:7, lane:1, source:8,target:"col 4"},
{id: 15, label: "lane 2", start: 1,end:7, lane:2, source:9,target:"col 4"},
{id: 16, label: "lane 2", start: 2,end:7, lane:2, source:0,target:"col 4"},
{id: 17, label: "lane 2", start: 5,end:7, lane:2, source:8,target:"col 4"},
{id: 18, label: "lane 3", start: 2,end:7, lane:3, source:8,target:"col 4"},
{id: 19, label: "lane 3", start: 3,end:7, lane:3, source:8,target:"col 4"},
{id: 20, label: "lane 3", start: 5,end:7, lane:3, source:8,target:"col 4"},
{id: 21, label: "lane 3", start: 6,end:7, lane:3, source:8,target:"col 4"},
{id: 22, label: "lane 4", start: 2,end:7, lane:4, source:8,target:"col 4"},
{id: 23, label: "lane 4", start: 3,end:7, lane:4, source:8,target:"col 4"},
{id: 24, label: "lane 4", start: 5,end:7, lane:4, source:8,target:"col 4"},
{id: 25, label: "lane 4", start: 6,end:7, lane:4, source:8,target:"col 4"},
{id: 26, label: "lane 5", start: 2,end:7, lane:5, source:8,target:"col 4"},
{id: 27, label: "lane 5", start: 3,end:7, lane:5, source:8,target:"col 4"},
{id: 28, label: "lane 5", start: 5,end:7, lane:5, source:8,target:"col 4"},
{id: 29, label: "lane 5", start: 6,end:7, lane:5, source:8,target:"col 4"},
{id: 30, label: "lane 6", start: 0,end:7, lane:6, source:8,target:"col 4"},
{id: 31, label: "lane 6", start: 1,end:7, lane:6, source:8,target:"col 4"},
{id: 32, label: "lane 6", start: 2,end:7, lane:6, source:8,target:"col 4"},
];
var lanes = lanedata;
var items = items_data;
var max_width = 0;
var max_width_array = [];
for (var i = 0; i < items_data.length; i++) {
max_width_array.push(items_data[i].start);
}
max_width = Math.max.apply(null, max_width_array)
var margin = {
top: 20,
right: 15,
bottom: 15,
left: 60
},
width = 1100 - margin.left - margin.right,
height = 900 - margin.top - margin.bottom,
miniHeight = lanes.length * 17 + 50,
mainHeight = height;
var x1 = d3.scaleLinear().domain([0, 8]).range([0, width]);
var y1 = d3.scaleLinear().domain([0, 10]).range([0, mainHeight]);
var y2 = d3.scaleLinear().domain([0, 10]).range([0, miniHeight]);
var chart = d3.select('svg')
.attr('width', width + margin.right + margin.left + margin.right + margin.left + margin.right + margin.left)
.attr('height', height + margin.top + margin.bottom)
.attr('class', 'chart');
chart.append('defs')
.attr('id', 'clip')
.append('rect')
.attr('width', width)
.attr('height', mainHeight);
var main = chart.append('g')
.attr('transform', 'translate(' + 150 + ',' + 90 + ')')
.attr('width', width)
.attr('height', mainHeight)
.attr('class', 'main')
main.append('g')
.attr('transform', 'translate(0,' + mainHeight + ')')
.attr('class', 'main axis date');
var rects = main.selectAll('rect')
.data(items, function(d) {
return d.id;
})
// draw the lanes for the main chart
main.append('g').selectAll('.laneLines')
.data(lanes)
.enter().append('line')
.attr('x1', 0)
.attr('y1', function(d) {
return Math.round(y1(d.id)) + 1.5;
})
.attr('x2', width + 250)
.attr('y2', function(d) {
return Math.round(y1(d.id)) + 1.5;
})
.attr('stroke', function(d) {
return d.label === '' ? '#c7ced9' : '#202124'
});
main.append('g').selectAll('.laneLines_1')
.data(items)
.enter().append('line')
.attr('x1', function(d) {
return Math.round(x1(d.source)) - 1.5;
})
.attr('y1', -20)
.attr('x2', function(d) {
return Math.round(x1(d.source)) - 1.5;
})
.attr('y2', height - 250)
.attr('stroke', function(d) {
return d.label === '' ? 'black' : '#202124'
})
.attr('class', function(d) {
if (d.source == 0 || d.source == 1 || d.source == 5 || d.source == 8) {
return 'solid';
} else {
return 'dashed'
}
});
main.append('g').selectAll('.laneText')
.data(lanes)
.enter().append('text')
.text(function(d) {
return d.label;
})
.attr('x', -10)
.attr('y', function(d) {
return y1(d.id + .5);
})
.attr('dy', '0.5ex')
.attr('text-anchor', 'end')
.attr('class', 'laneText');
rects.enter().append('rect')
.attr('x', function(d) {
if (d.id == 9 || d.id == 12 || d.id == 13 || d.id == 14)
return x1(d.start) - 60;
else
return x1(d.start) + 10;
})
.attr('y', function(d) {
return y1(d.lane) + 3
})
.attr('width', function(d) {
if (d.source == 6)
return 220;
else
return 110;
})
.attr('height', function(d) {
return .8 * y1(1);
})
.attr('class', "rect_low")
.attr('rx', 2)
.attr("marker-end", "url(#end)")
.attr('fill', "white");
var minExtent = 0;
rects.selectAll("text.label")
.data(items)
.enter().append("text")
.attr("class", "label")
.attr("x", function(d) {
return x1(d.start);
}).attr("y", function(d) {
return y1(d.lane);
})
.style("text-anchor", "middle")
.text("Class average");
.chart {
shape-rendering: crispEdges;
}
.month text {
text-anchor: start;
}
.todayLine {
stroke: blue;
stroke-width: 1.5;
}
.axis line,
.axis path {
stroke: black;
}
.rect_low {
fill: rgb(255, 255, 255);
stroke-width: 1px;
stroke: rgb(0, 0, 0);
}
.solid {
stroke: solid;
stroke-width: 2px;
}
.dashed {
stroke-dasharray: 5, 5;
fill: grey;
}
.triangle_label {
fill: white;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
Here I want to add links/connectors/arrow between few of the rectangles,
Example: In lane 0 I want to add arrow between the rect 1 and rect 2.
Also is there a way where I can add connectors from any rect to other?
How can I achieve that?
Upvotes: 0
Views: 106
Reputation: 438
You can use d3 data bind logic to link each datum to an svg line
element.
For example, use can do something like that:
main
.append('g')
.selectAll('line')
.data(items_data)
.enter()
.append('line')
.attr('x1', 100)
.attr('x2', 300)
.attr('y1', 100)
.attr('y2', 100)
.attr('stroke', 'red')
Instead of use fixed values for x1, x2, y1, y2
you have to compute them from you data, I don't know which should be the logic behind that but I suppose the depend on items_data
values.
I suggest you to use d3 scales to compute these values and also the other ones you use to create rects and grid.
Upvotes: 1