23
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

D3.jsで第2軸を使うサンプル

Posted at
index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
    svg {
        font: 16px sans-serif;
        font-weight: bold;
    }

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

    .x.axis path {
        display: none;
    }

    .line0 {
        fill: none;
        stroke: rgba(255,0,0,0.85);
        stroke-width: 5px;
        stroke-linecap: round;
        stroke-linejoin: round;
    }

    .line1 {
        fill: none;
        stroke: rgba(0,0,255,0.85);
        stroke-width: 5px;
        stroke-linecap: round;
        stroke-linejoin: round;
    }
    .circle0, .circle1{
        cursor: pointer;
    }

    #tooltip{
        position: absolute;
        top: 40px;
        left: 80px;
        display: none;
        width: 160px;
        height: auto;
        padding: 10px;
        background-color: white;
        border-radius: 10px;
        box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
        pointer-events: none;
        opacity: 0.85;
    }

    #tooltip p{
        margin: 0;
        font-family: sans-serif;
        font-size: 16px;
        line-height:20px;
    }

    #temp{
        color: rgba(255,0,0,0.85);
    }

    #humid{
        color: rgba(0,0,225,0.85);
    }
    </style>
</head>
<body>
    <div id="tooltip">
        <p><strong id="date"></strong></p>
        <p><strong id="time"></strong></p>
        <p>温度: <span id="temp"></span></span></p>
        <p>湿度: <span id="humid"></span></p>
    </div>
    <script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
    <script src="http://d3js.org/d3.v3.js"></script>
    <script>

    //グラフクラス
    var cGraph = function(){}
    var timer;

    //グラフの描画メソッド
    cGraph.prototype.draw = function(){

        var margin = {top: 20, right: 50, bottom: 30, left: 50},
        //width = 960 - margin.left - margin.right,
        width = innerWidth - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;

        //var parseDate = d3.time.format('%d-%b-%y').parse;
        var parseDate = d3.time.format('%Y%m%d-%H%M%S').parse;
        var formatDate = d3.time.format('%Y年%m月%d日');
        var formatTime = d3.time.format('%H時%M分');

        //グラフの幅
        var x = d3.time.scale()
            .range([0, width]);

        //グラフの高さ
        var y = d3.scale.linear()
            .range([height, 0]);

        //グラフの高さ
        var y0 = d3.scale.linear()
            .range([height, 0]);

        //グラフの高さ
        var y1 = d3.scale.linear()
            .range([height, 0]);

        var xAxis = d3.svg.axis()
            .scale(x)
            .orient('bottom')
            .ticks(d3.time.months, 1)
            .tickFormat(d3.time.format('%_m月'));
            //.tickFormat(d3.time.format('%b'));
            //.ticks(5)
            //.ticks(10)
            //.ticks(15)
            //.tickFormat(d3.time.format('%Y/%m/%d'));

        var yAxis = d3.svg.axis()
            .scale(y)
            .orient('left');

        var yAxisLeft = d3.svg.axis().scale(y0) 
            .orient('left').ticks(5)
            .tickFormat(function(d){return d + ''});

        var yAxisRight = d3.svg.axis().scale(y1)
            .orient('right').ticks(5)
            .tickFormat(function(d){return d + ''});

        var line0 = d3.svg.line()
            .x(function(d) { return x(d.date); })
            //.y(function(d) { return y(d.temp); });
            .y(function(d) { return y0(d.temp); });

        var line1 = d3.svg.line()
            .x(function(d) { return x(d.date); })
            //.y(function(d) { return y(d.humid); });
            .y(function(d) { return y1(d.humid); });


        var svg = d3.select('body').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 + ')');

        //CSV読み込み
        d3.csv('data.csv', function(error, data) {
            data.forEach(function(d) {
                d.date = parseDate(d.date);
                //console.log(d.date);
                //console.log(formatDate(d.date));
                //d.date = formatDate(d.date);
                d.temp = +d.temp;
                d.humid = +d.humid;
            });

            x.domain(d3.extent(data, function(d) { return d.date; })).nice();
            //y.domain(d3.extent(data, function(d) { return d.temp; }));
            //y.domain(d3.extent(data, function(d) { return d.humid; }));

            /*
            y0.domain([0, d3.max(data, function(d) { return Math.max(d.temp); })]); 
            y1.domain([0, d3.max(data, function(d) { return Math.max(d.humid); })]);
            */
            y0.domain([d3.min(data, function(d) { return Math.min(d.temp); }), d3.max(data, function(d) { return Math.max(d.temp); })]).nice(); 
            y1.domain([d3.min(data, function(d) { return Math.min(d.humid); }), d3.max(data, function(d) { return Math.max(d.humid); })]).nice();


            svg.append('g')
                .attr('class', 'x axis')
                .attr('transform', 'translate(0,' + height + ')')
                .attr('fill','rgba(0,0,0,0.85)')
                .call(xAxis);
                //.append('text')
                //.attr('transform', 'translate(-35, 20)')
                //.text('日付');

            //左y軸(温度)
            svg.append('g')
                .attr('class', 'y axis')
                .attr('fill','rgba(255,0,0,0.85)')
                //.call(yAxis)
                .call(yAxisLeft);
            /*
            .append('text')
                .attr('transform', 'translate(80, -20) rotate(0)')
                .attr('y', 6)
                .attr('dy', '.71em')
                //.attr('dy', '5em')
                .attr('fill','rgba(255,0,0,0.85)')
                .style('text-anchor', 'end')
                .text('温度 (℃)');
            */

            //右y軸(湿度)
            svg.append('g')
                .attr('class', 'y axis')
                .attr('transform', 'translate(' + (width-18) + ' ,0)')
                .attr('fill','rgba(0,0,255,0.85)')
                //.call(yAxis)
                .call(yAxisRight);
            /*
            .append('text')
                .attr('transform', 'translate(-5, -20) rotate(0)')
                .attr('y', 6)
                .attr('dy', '.71em')
                //.attr('dy', '5em')
                .attr('fill','rgba(0,0,255,0.85)')
                .style('text-anchor', 'end')
                .text('湿度 (%)');
            */

            //グラフ温度
            svg.append('path')
                .datum(data)
                .attr('class', 'line0')
                .attr('d', line0)
                .attr('opacity','0')
                .transition()
                .duration(500)
                .attr('opacity','1.0');

            //グラフ湿度
            svg.append('path')
                .datum(data)
                .attr('class', 'line1')
                .attr('d', line1)
                .attr('opacity','0')
                .transition()
                .delay(500)
                .duration(500)
                .attr('opacity','1.0');
            
            //横方向と縦方向のグリッド間隔を自動生成
            var rangeX = d3.range(0, width-18, 20);
            var rangeY = d3.range(0, height, 20);

            // 縦方向のグリッドを生成
            svg.selectAll('line.y')
                .data(rangeY)
                .enter()
                .append('line')
                    .attr('x1', 0).attr('y1', function(d,i){return d; })
                    .attr('x2', width-18).attr('y2', function(d,i){return d ;});

            // 横方向のグリッドを生成
            svg.selectAll('line.x')
                .data(rangeX)
                .enter()
                .append('line')
                    .attr('x1', function(d,i){return d;}).attr('y1', 0)
                    .attr('x2', function(d,i){return d;}).attr('y2', height);

            // グリッドを描画
            svg.selectAll('line')
                .attr('stroke', 'rgba(0,0,0,0.3)')
                .attr('shape-rendering', 'crispEdges');


            svg.selectAll('circle.t')
                .data(data)
                .enter()
                .append('circle')
                    .attr('cx', function(d, i) { return x(d.date); })
                    .attr('cy', function(d, i) { return y0(d.temp); })
                    .attr('r', 0)
                    .attr('class', 'circle0')
                    .style('fill','rgba(255,0,0,0.85)')
                    .on('click',function(d){
                        $('#tooltip').fadeIn();
                        $('#date').text(formatDate(d.date));
                        $('#time').text(formatTime(d.date));
                        $('#temp').text(d.temp);
                        $('#humid').text(d.humid);
                        clearTimeout(timer);
                        timer = setTimeout(function(){
                            $('#tooltip').fadeOut();
                        }, 5000);
                    })
                    .on('mouseover',function(d){
                        $('#tooltip').fadeIn();
                        $('#date').text(formatDate(d.date));
                        $('#time').text(formatTime(d.date));
                        $('#temp').text(d.temp);
                        $('#humid').text(d.humid);
                        clearTimeout(timer);
                        timer = setTimeout(function(){
                            $('#tooltip').fadeOut();
                        }, 5000);
                    })
                    .transition()
                    // .delay(function(d, i){
                    //     return (i+1) * 1000;
                    // })
                    .duration(1000)
                    .attr('r', 6);

            svg.selectAll('circle.h')
                .data(data)
                .enter()
                .append('circle')
                    .attr('cx', function(d, i) { return x(d.date); })
                    .attr('cy', function(d, i) { return y1(d.humid); })
                    .attr('r', 0)
                    .attr('class', 'circle1')
                    .style('fill','rgba(0,0,255,0.85)')
                    .on('click',function(d){
                        $('#tooltip').fadeIn();
                        $('#date').text(formatDate(d.date));
                        $('#time').text(formatTime(d.date));
                        $('#temp').text(d.temp);
                        $('#humid').text(d.humid);
                        clearTimeout(timer);
                        timer = setTimeout(function(){
                            $('#tooltip').fadeOut();
                        }, 5000);
                    })
                    .on('mouseover',function(d){
                        $('#tooltip').fadeIn();
                        $('#date').text(formatDate(d.date));
                        $('#time').text(formatTime(d.date));
                        $('#temp').text(d.temp);
                        $('#humid').text(d.humid);
                        clearTimeout(timer);
                        timer = setTimeout(function(){
                            $('#tooltip').fadeOut();
                        }, 5000);
                    })
                    .transition()
                    .delay(500)
                    // .delay(function(d, i){
                    //     return (i+1) * 1000;
                    // })
                    .duration(1000)
                    .attr('r', 6);
        });
    };

    //DOMの構築
    $(function(){

        //グラフの初回描画
        var graph = new cGraph();
        graph.draw();

        var timer;
        timer = false;
        //リサイズ時svgサイズ変更
        $(window).resize(function() {
            if (timer !== false) {
                clearTimeout(timer);
            }
            timer = setTimeout(function() {
                
                d3.select('svg').remove();
                graph.draw();

            }, 200);
        });
    });
    </script>
</body>
</html>
data.csv
date,temp,humid
20130301-010101,12.54,38.63
20130401-010101,16.73,24.37
20130501-010101,18.53,20.52
20130515-010101,20.23,30.52
20130601-010101,18.21,20.63
20130615-010101,21.73,35.36
20130701-010101,24.84,30.73
20130706-010101,27.25,20.49
20130707-010101,23.26,40.29
20130709-010101,22.27,30.72
20130815-010101,32.65,30.72
20131010-010101,14.26,36.93
23
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?