Algorithm-TimelinePacking
view release on metacpan or search on metacpan
examples/conference.html view on Meta::CPAN
var COLORS = { keynote: '#e74c3c', beginner: '#3498db', advanced: '#9b59b6', workshop: '#27ae60', community: '#f39c12', break: '#95a5a6' };
var LABELS = { keynote: 'Keynote', beginner: 'Beginner Track', advanced: 'Advanced Track', workshop: 'Workshop', community: 'Community', break: 'Break' };
var LINE_HEIGHT = 40;
var BAR_HEIGHT = 30;
var MARGIN_LEFT = 80;
var SCALE = 900 / LATEST;
function fmt(m) { return String(Math.floor(m/60)).padStart(2,'0') + ':' + String(m%60).padStart(2,'0'); }
var tooltip = d3.select("#tooltip");
var svg = d3.select("#chart")
.append("svg")
.attr("width", MARGIN_LEFT + 920)
.attr("height", 30 + lines.length * LINE_HEIGHT);
// Time axis
for (var h = 9; h <= 19; h++) {
svg.append("text")
.attr("class", "time-label")
.attr("x", MARGIN_LEFT + (h - 9) * 60 * SCALE)
.attr("y", 15)
examples/conference.html view on Meta::CPAN
// Rooms
lines.forEach(function(line, idx) {
var y = 30 + idx * LINE_HEIGHT;
svg.append("text")
.attr("class", "room-label")
.attr("x", 0)
.attr("y", y + 20)
.text("Room " + (idx + 1));
var talks = svg.selectAll(".talk-" + idx)
.data(line)
.enter()
.append("g")
.attr("class", "talk");
talks.append("rect")
.attr("x", function(d) { return MARGIN_LEFT + d[0] * SCALE; })
.attr("y", y + 2)
.attr("width", function(d) { return Math.max(30, (d[1] - d[0]) * SCALE - 3); })
.attr("height", BAR_HEIGHT)
examples/conference.html view on Meta::CPAN
talks.append("text")
.attr("x", function(d) { return MARGIN_LEFT + d[0] * SCALE + 6; })
.attr("y", y + 22)
.text(function(d) {
var w = Math.max(30, (d[1] - d[0]) * SCALE);
var maxChars = Math.floor(w / 7);
return d[2].length > maxChars ? d[2].substring(0, maxChars - 1) + '...' : d[2];
});
talks.on("mouseover", function(event, d) {
d3.select("#tooltip-title").text(d[2]);
d3.select("#tooltip-time").text(fmt(d[0] + EARLIEST) + ' - ' + fmt(d[1] + EARLIEST));
d3.select("#tooltip-speaker").text(d[3] ? 'Speaker: ' + d[3] : '');
d3.select("#tooltip-track").text('Track: ' + LABELS[d[4]]);
tooltip.style("display", "block")
.style("left", (event.pageX + 10) + "px")
.style("top", (event.pageY - 10) + "px");
})
.on("mousemove", function(event) {
tooltip.style("left", (event.pageX + 10) + "px")
.style("top", (event.pageY - 10) + "px");
})
.on("mouseout", function() {
tooltip.style("display", "none");
});
});
// Legend
var legend = d3.select("#legend");
Object.keys(COLORS).forEach(function(track) {
var item = legend.append("div").attr("class", "legend-item");
item.append("div").attr("class", "legend-color").style("background", COLORS[track]);
item.append("span").text(LABELS[track]);
});
// Stats
d3.select("#stats").text(INPUT.length + ' sessions arranged in ' + lines.length + ' rooms | Conference runs ' + fmt(EARLIEST) + ' - ' + fmt(EARLIEST + LATEST));
</script>
</body>
</html>
examples/generate_demo.pl view on Meta::CPAN
const LINE_HEIGHT = 20;
const BAR_HEIGHT = 18;
const SCALE_DIVISOR = 3; // adjust based on data range
const INTENSITY_MAX = 5000;
const myData = $json;
const levelColor = d3.scaleLinear().domain([1, INTENSITY_MAX]).range([0, 1]);
const svgHeight = myData.length * LINE_HEIGHT;
d3.select("#timeline").attr("height", svgHeight);
myData.forEach(function(line, idx) {
const lineGroup = d3.select("#timeline")
.append("g")
.attr("id", "line_" + idx)
.attr("transform", "translate(0," + (idx * LINE_HEIGHT) + ")");
lineGroup.selectAll("rect")
.data(line)
.enter()
.append("rect")
.style("fill", function(d) {
if (d[4] > INTENSITY_MAX) return "#f00";
return d3.interpolateLab("#eee", "#f00")(levelColor(d[4]));
})
.attr("height", BAR_HEIGHT)
.attr("width", function(d) {
return Math.max(2, d[1] / SCALE_DIVISOR - d[0] / SCALE_DIVISOR);
examples/hadoop-jobs.html view on Meta::CPAN
// =============================================================================
var LINE_HEIGHT = 22;
var BAR_HEIGHT = 18;
var SCALE = 1100 / LATEST;
var colorFn = function(d) { return d3.interpolateLab("#eee", "#f00")(d); };
document.getElementById('legend-low').style.background = colorFn(0);
document.getElementById('legend-high').style.background = colorFn(1);
var svg = d3.select("#timeline");
svg.attr("height", lines.length * LINE_HEIGHT);
var tooltip = document.getElementById('tooltip');
lines.forEach(function(line, idx) {
var lineGroup = svg.append("g")
.attr("transform", "translate(0, " + (idx * LINE_HEIGHT) + ")");
lineGroup.selectAll("rect")
.data(line)
.enter()
.append("rect")
.style("fill", function(d) { return colorFn(Math.min(d[4] / 5000, 1)); })
.attr("height", BAR_HEIGHT)
.attr("width", function(d) { return Math.max(3, (d[1] - d[0]) * SCALE); })
.attr("x", function(d) { return d[0] * SCALE; })
.attr("y", 0)
.attr("rx", 2)
.attr("ry", 2)
( run in 1.616 second using v1.01-cache-2.11-cpan-e1769b4cff6 )