Revision 92b7df62fe7e610d1dda49309ed19a602da3a93a authored by mroberge on 18 April 2018, 02:52:48 UTC, committed by mroberge on 18 April 2018, 02:52:48 UTC
1 parent 1c252b5
Raw File
d3-line-chunked.html

<!DOCTYPE html>
<html>
<head>
    <title>d3-line-chunked</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="lib/d3-line-chunked/example.css" />
</head>
<body>
<h1 class="main-header">d3-line-chunked</h1>
<p class="main-link"><a href="https://github.com/pbeshai/d3-line-chunked">https://github.com/pbeshai/d3-line-chunked</a></p>
<div class='chart-container'></div>
<p>
    <a href="https://github.com/pbeshai/d3-line-chunked">Code on GitHub</a>
</p>
<div class='example-gallery'><h2>Example Cases</h2></div>
<script src="//d3js.org/d3.v4.min.js"></script>
<script src="lib/d3-line-chunked/d3-interpolate-path.js"></script>
<script src="lib/d3-line-chunked/d3-line-chunked.js"></script>
<script src="lib/d3-line-chunked/example-gallery.js"></script>
<script>
    var transitionDuration = 1000;

    // shared chart properties
    var x, y, xAxis, yAxis, svg, line, lineWithDefined, width, height;
    var lineColor = '#0bb';

    /* eslint-disable */
    function generateRandom(length) {
        var xRandomizer = d3.randomNormal(150, 150);
        var yRandomizer = d3.randomLogNormal(3, 1.2);
        var vRandomizer = d3.randomNormal(150, 50);
        var missingChance = 0.8;

        return d3.range(length).map(function (i) {
            return {
                x: i,
                y: Math.round(yRandomizer()),
                v: Math.round(vRandomizer())
            }
        }).map(function (d) {
            if (Math.random() > missingChance && d.x > 3 && d.x < length - 2) {
                d.y = undefined;
            }
            return d;
        });
    }

    function setupChart(data) {
        var margin = {top: 20, right: 30, bottom: 0, left: 20};
        width = 800 - margin.left - margin.right;
        height = 450 - margin.top - margin.bottom;
        var numGroups = 3;
        var groupHeight = height / numGroups;

        x = d3
                .scaleLinear()
                .domain(d3.extent(data, function (d) { return d.x; }))
                .range([0, width]);

        y = d3
                .scaleLinear()
                .domain(d3.extent(data, function (d) { return d.y; }))
                .range([0.5 * groupHeight, 0]);

        svg = d3.select('.chart-container').append('svg')
                .attr('width', width + margin.left + margin.right)
                .attr('height', height + margin.top + margin.bottom)
                .append('g')
                .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

        line = d3.line()
                .curve(d3.curveLinear)
                .x(function (d) { return x(d.x); })
                .y(function (d) { return y(d.y); });

        lineWithDefined = d3.line()
                .curve(d3.curveLinear)
                .x(function (d) { return x(d.x); })
                .y(function (d) { return y(d.y); })
                .defined(function (d) { return d.y != null; });

        svg.append('g')
                .attr('class', 'ref-lines');

        svg.append('g')
                .attr('class', 'basic-line')
                .append('text')
                .text('d3.line')
                .attr('dy', -8);

        svg.append('g')
                .attr('class', 'basic-line-defined')
                .attr('transform', 'translate(0 ' + (groupHeight) + ')')
                .append('text')
                .text('d3.line with defined()')
                .attr('dy', -8);

        svg.append('g')
                .attr('class', 'chunked-line')
                .attr('transform', 'translate(0 ' + (2 * groupHeight) + ')')
                .append('text')
                .text('d3-line-chunked')
                .style('font-weight', 'bold')
                .attr('dy', -8);

        d3.select('.chart-container').append('button')
                .text('New Data')
                .on('click', function () { updateChart(generateRandom(20)); });

        updateChart(data);
    }


    function renderChunkedLine(lineData, root) {
        var lineChunked = d3.lineChunked()
                .x(function (d) { return x(d.x); })
                .y(function (d) { return y(d.y); })
                .curve(d3.curveLinear)
                .defined(function (d) { return d.y != null; })
                .lineStyles({
                    stroke: '#0bb'
                });

        root
                .datum(lineData)
                .transition()
                .duration(transitionDuration)
                .call(lineChunked);
    }

    function renderBasicLine(newData, root, line, showPoints) {
        // render basic line
        var basicLine = root.select('path');

        if (basicLine.empty()) {
            basicLine = root.append('path')
                    .style('opacity', 1e-6);
        }

        basicLine
                .style('fill', 'none')
                .style('stroke', lineColor)
                .style('stroke-width', 2)
                .transition()
                .duration(transitionDuration)
                .style('opacity', 1)
                .attr('d', line(newData));

        if (showPoints) {
            var filteredData = newData.filter(function (d) { return d.y != null; });

            var circleBinding = root.selectAll('circle').data(filteredData);

            var circleEntering = circleBinding.enter()
                    .append('circle')
                    .attr('cx', function (d) { return x(d.x); })
                    .attr('cy', function (d) { return y(d.y); });

            circleBinding.merge(circleEntering)
                    .style('fill', lineColor)
                    .transition()
                    .duration(transitionDuration)
                    .attr('r', 3.5)
                    .attr('cx', function (d) { return x(d.x); })
                    .attr('cy', function (d) { return y(d.y); });

            circleBinding.exit().remove();
        }
    }

    function renderRefLines(newData, root) {
        var filteredData = newData.filter(function (d) { return d.y != null; });

        var binding = root.selectAll('line').data(filteredData);

        var entering = binding.enter()
                .append('line')
                .style('stroke', 'transparent')
                .attr('x1', function (d) { return x(d.x); })
                .attr('x2', function (d) { return x(d.x); });



        binding.merge(entering)
                .transition()
                .duration(transitionDuration)
                .style('stroke', '#f4f4f4')
                .attr('x1', function (d) { return x(d.x); })
                .attr('x2', function (d) { return x(d.x); })
                .attr('y1', 0)
                .attr('y2', height);

        binding.exit().remove();
    }

    function updateChart(newData) {
        console.log('Main line using data', newData);

        x.domain(d3.extent(newData, function (d) { return d.x; }));
        y.domain(d3.extent(newData, function (d) { return d.y; }));

        var gRefLines = svg.select('.ref-lines');
        renderRefLines(newData, gRefLines);

        var filteredData = newData.filter(function (d) { return d.y != null; });

        var gBasicLine = svg.select('.basic-line');
        renderBasicLine(filteredData, gBasicLine, line, true);
        var gBasicLineDefined = svg.select('.basic-line-defined');
        renderBasicLine(newData, gBasicLineDefined, lineWithDefined);

        var gChunkedLine = svg.select('.chunked-line');
        renderChunkedLine(newData, gChunkedLine);
    }

    // create the chart
    setupChart(generateRandom(20));



</script>
</body>
</html>
back to top