Skip to content

Instantly share code, notes, and snippets.

@chrtze
Created November 23, 2015 20:00
Show Gist options
  • Select an option

  • Save chrtze/e5ddec8d476335d79bbc to your computer and use it in GitHub Desktop.

Select an option

Save chrtze/e5ddec8d476335d79bbc to your computer and use it in GitHub Desktop.

Revisions

  1. chrtze created this gist Nov 23, 2015.
    164 changes: 164 additions & 0 deletions chart.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,164 @@
    var Chart = (function(window,d3) {

    var svg, data, x, y, xAxis, yAxis, dim, chartWrapper, line, path, margin = {}, width, height, locator;

    var breakPoint = 768;

    d3.csv('data.csv', init); //load data, then initialize chart

    //called once the data is loaded
    function init(csv) {
    data = csv;

    //initialize scales
    xExtent = d3.extent(data, function(d,i) { return new Date(d.date) });
    yExtent = d3.extent(data, function(d,i) { return d.value });
    x = d3.time.scale().domain(xExtent);
    y = d3.scale.linear().domain(yExtent);

    //initialize axis
    xAxis = d3.svg.axis().orient('bottom');
    yAxis = d3.svg.axis();

    //the path generator for the line chart
    line = d3.svg.line()
    .x(function(d) { return x(new Date(d.date)) })
    .y(function(d) { return y(d.value) });

    //initialize svg
    svg = d3.select('#chart')
    .append('svg')
    .style('pointer-events', 'none');


    chartWrapper = svg
    .append('g')
    .style('pointer-events', 'all');

    path = chartWrapper.append('path').datum(data).classed('line', true);

    chartWrapper.append('g').classed('x axis', true);
    chartWrapper.append('g').classed('y axis', true);

    chartWrapper.on('touchmove', onTouchMove);

    //add locator
    locator = chartWrapper.append('circle')
    .style('display', 'none')
    .attr('r', 10)
    .attr('fill', '#f00');

    touchScale = d3.scale.linear();

    //render the chart
    render();
    }

    function render() {

    //get dimensions based on window size
    updateDimensions(window.innerWidth);

    //update x and y scales to new dimensions
    x.range([0, width]);
    y.range([height, 0]);

    touchScale.domain([0,width]).range([0,data.length-1]).clamp(true);

    //update svg elements to new dimensions
    svg
    .attr('width', width + margin.right + margin.left)
    .attr('height', height + margin.top + margin.bottom);

    chartWrapper
    .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

    //update the axis and line
    xAxis.scale(x);
    yAxis.scale(y).orient(window.innerWidth < breakPoint ? 'right' : 'left');

    if(window.innerWidth < breakPoint) {
    xAxis.ticks(d3.time.month, 2)
    }
    else {
    xAxis.ticks(d3.time.month, 1)
    }

    svg.select('.x.axis')
    .attr('transform', 'translate(0,' + height + ')')
    .call(xAxis);

    svg.select('.y.axis')
    .call(yAxis);

    path.attr('d', line);
    renderLabels();
    }

    var labels = [
    {
    x: new Date('03-15-2014'),
    y: .17,
    text: 'Test Label 1',
    orient: 'right'
    },
    {
    x: new Date('11-20-2014'),
    y: .24,
    text: 'Test Label 2',
    orient: 'left'
    }
    ]

    function renderLabels() {

    var _labels = chartWrapper.selectAll('text.label');

    if(_labels[0].length > 0) {
    //labels already exist
    _labels
    .attr('x', function(d) { return x(d.x) })
    .attr('y', function(d) { return y(d.y) })
    }
    else {
    //append labels if function is called for the first time
    _labels
    .data(labels)
    .enter()
    .append('text')
    .classed('label', true)
    .attr('x', function(d) { return x(d.x) })
    .attr('y', function(d) { return y(d.y) })
    .style('text-anchor', function(d) { return d.orient == 'right' ? 'start' : 'end' })
    .text(function(d) { return d.text });
    }
    }

    function updateDimensions(winWidth) {
    margin.top = 20;
    margin.right = winWidth < breakPoint ? 0 : 50;
    margin.left = winWidth < breakPoint ? 0 : 50;
    margin.bottom = 50;

    width = winWidth - margin.left - margin.right;
    height = .7 * width;
    }

    function onTouchMove() {
    var xPos = d3.touches(this)[0][0];
    var d = data[~~touchScale(xPos)];

    locator.attr({
    cx : x(new Date(d.date)),
    cy : y(d.value)
    })
    .style('display', 'block');
    }

    return {
    render : render
    }

    })(window,d3);

    window.addEventListener('resize', Chart.render);
    10 changes: 10 additions & 0 deletions create-data.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,10 @@
    var fs = require('fs');
    var startDate = new Date('2014-1-1');
    var endDate = new Date('2015-1-1');
    var csv = 'date,value\n';

    for(var i = startDate; i < endDate; startDate.setDate(startDate.getDate() + 10)) {
    csv += '' + startDate.toString() + ',' + Math.random() + '\n';
    }

    fs.writeFileSync('data.csv', csv);
    38 changes: 38 additions & 0 deletions data.csv
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,38 @@
    date,value
    Wed Jan 01 2014 00:00:00 GMT+0100 (CET),0.505003142170608
    Sat Jan 11 2014 00:00:00 GMT+0100 (CET),0.5459181617479771
    Tue Jan 21 2014 00:00:00 GMT+0100 (CET),0.14592946274206042
    Fri Jan 31 2014 00:00:00 GMT+0100 (CET),0.7082753519061953
    Mon Feb 10 2014 00:00:00 GMT+0100 (CET),0.010393543168902397
    Thu Feb 20 2014 00:00:00 GMT+0100 (CET),0.6583312929142267
    Sun Mar 02 2014 00:00:00 GMT+0100 (CET),0.24273463618010283
    Wed Mar 12 2014 00:00:00 GMT+0100 (CET),0.15577656053937972
    Sat Mar 22 2014 00:00:00 GMT+0100 (CET),0.8833602059166878
    Tue Apr 01 2014 00:00:00 GMT+0200 (CEST),0.26687808078713715
    Fri Apr 11 2014 00:00:00 GMT+0200 (CEST),0.649613720132038
    Mon Apr 21 2014 00:00:00 GMT+0200 (CEST),0.4543698029592633
    Thu May 01 2014 00:00:00 GMT+0200 (CEST),0.7719218074344099
    Sun May 11 2014 00:00:00 GMT+0200 (CEST),0.5177543167956173
    Wed May 21 2014 00:00:00 GMT+0200 (CEST),0.9994703007396311
    Sat May 31 2014 00:00:00 GMT+0200 (CEST),0.7990491802338511
    Tue Jun 10 2014 00:00:00 GMT+0200 (CEST),0.2791274816263467
    Fri Jun 20 2014 00:00:00 GMT+0200 (CEST),0.00961384573020041
    Mon Jun 30 2014 00:00:00 GMT+0200 (CEST),0.17923940671607852
    Thu Jul 10 2014 00:00:00 GMT+0200 (CEST),0.5797557467594743
    Sun Jul 20 2014 00:00:00 GMT+0200 (CEST),0.41668077907525003
    Wed Jul 30 2014 00:00:00 GMT+0200 (CEST),0.26668014749884605
    Sat Aug 09 2014 00:00:00 GMT+0200 (CEST),0.9645155349280685
    Tue Aug 19 2014 00:00:00 GMT+0200 (CEST),0.9435918028466403
    Fri Aug 29 2014 00:00:00 GMT+0200 (CEST),0.4980645985342562
    Mon Sep 08 2014 00:00:00 GMT+0200 (CEST),0.9871973677072674
    Thu Sep 18 2014 00:00:00 GMT+0200 (CEST),0.8283164533786476
    Sun Sep 28 2014 00:00:00 GMT+0200 (CEST),0.6416109406854957
    Wed Oct 08 2014 00:00:00 GMT+0200 (CEST),0.6466128702741116
    Sat Oct 18 2014 00:00:00 GMT+0200 (CEST),0.7002710588276386
    Tue Oct 28 2014 00:00:00 GMT+0100 (CET),0.9069056580774486
    Fri Nov 07 2014 00:00:00 GMT+0100 (CET),0.6439003541599959
    Mon Nov 17 2014 00:00:00 GMT+0100 (CET),0.7253473403397948
    Thu Nov 27 2014 00:00:00 GMT+0100 (CET),0.22283505811356008
    Sun Dec 07 2014 00:00:00 GMT+0100 (CET),0.6578892532270402
    Wed Dec 17 2014 00:00:00 GMT+0100 (CET),0.14639883721247315
    Sat Dec 27 2014 00:00:00 GMT+0100 (CET),0.31333006569184363
    14 changes: 14 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,14 @@
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width" />
    <title>D3 Line Chart</title>
    <link rel="stylesheet" href="style.css">
    <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
    </head>
    <body>
    <div id="chart"></div>
    <script src="chart.js"></script>
    </body>
    </html>
    21 changes: 21 additions & 0 deletions style.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,21 @@
    body {
    font: 12px sans-serif;
    margin: 0;
    }

    .axis path,
    .axis line {
    fill: none;
    stroke: #000;
    shape-rendering: crispEdges;
    }

    .x.axis path {
    display: none;
    }

    .line {
    fill: none;
    stroke: steelblue;
    stroke-width: 1.5px;
    }