Algorithm-TimelinePacking

 view release on metacpan or  search on metacpan

examples/generate_demo.pl  view on Meta::CPAN

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Timeline Demo</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
            margin: 20px;
            background: #f5f5f5;
        }
        h1 {
            color: #333;
        }
        .info {
            margin-bottom: 20px;
            color: #666;
        }
        #chart {
            background: white;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        svg {
            overflow: visible;
        }
        rect {
            stroke: #fff;
            stroke-width: 0.5;
        }
        rect:hover {
            stroke: #000;
            stroke-width: 2;
        }
    </style>
</head>
<body>
    <h1>Timeline Visualization Demo</h1>
    <div class="info">
        <p>50 simulated Hadoop jobs arranged on ${\(scalar @$lines)} lines.
           Hover over bars to see job details.</p>
        <p>Color intensity represents map task count (gray → red = few → many).</p>
    </div>
    <div id="chart">
        <svg id="timeline" width="$width"></svg>
    </div>

<script>
(function() {
    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);
            })
            .attr("x", function(d) {
                return d[0] / SCALE_DIVISOR;
            })
            .attr("y", 0)
            .attr("rx", 2)
            .attr("ry", 2)
            .append("title")
            .text(function(d) {
                return "Job: " + d[2] + "\\nUser: " + d[3] + "\\nMaps: " + d[4] + "\\nReduces: " + d[5];
            });
    });
})();
</script>
</body>
</html>
HTML



( run in 1.091 second using v1.01-cache-2.11-cpan-140bd7fdf52 )