block by shimizu c9ce56d302c4766fe31037d593f52422

D3 v4 - 水平パンニング

Full Screen

ドラッグでチャートのX軸を移動できます。

Built with blockbuilder.org

index.html


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>D3 Template</title>
<style>
    .axis path{
	fill:none;
	stroke:black;
}
.axis {
	font-size:8pt;
	font-family:sans-serif;
}
.tick{
	fill:none;
	stroke:black;
}
</style>
</head>
<body>

<script src="//unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
<script src="//unpkg.com/d3@4.12.2/build/d3.min.js"></script>    
<script type="text/babel"> 
//データセットの作成
const dataSet = d3.range(1000).map( (d, i)  => { return {x: (i * 10), y: ~~(Math.random()*100)} })

//svg ステージ設置
const width = 980;
const maxWisth = width*4;
const thresholdWisth = maxWisth - width;
const height = 400;
const svg = d3.select('body')
    .append('svg')
    .attr('width', width)
    .attr('height', height)
    .attr('cursor', 'move'); 

const stage = svg.append("g")            
            
//データセットの最大値取得
const xMax = d3.max(dataSet, d => d.x ); //X最大値取得
const yMax = d3.max(dataSet, d => d.y ); //Y最大値取得

const margin = 20; //X軸両端のマージン

//スケール関数を作成
const xScale = d3.scaleLinear().domain([0, xMax]).range([margin, maxWisth - margin]);
const yScale = d3.scaleLinear().domain([0, yMax]).range([height, 0]);


//スケールを元にpathのd属性を設定するline関数を作成    
const line = d3.line()
    .x(d => xScale(d.x) )
    .y(d => yScale(d.y) )
    .curve(d3.curveBasis)

//折れ線グラフ描画        
stage.append('g')
    .datum(dataSet)
    .append('path')
    .attr('d', line) 
    .attr('stroke', 'red')
    .attr('fill', 'none')

//X軸補助目盛線描画
const x_axis = d3.axisBottom().scale(xScale); //スケールを元に目盛線を作成
stage.append('g')
    .attr('class', 'x axis')
    .attr('transform', `translate(0, ${height-margin})`) 
    .call(x_axis);
    
//ズームイベントリスナーの設定
const zoom = d3.zoom()
    .on('zoom', function(){
        const t = d3.event.transform; //マウスの移動量を取得
        let tx = null;
            
        //移動範囲を制限
        if(t.x <= -thresholdWisth){ //右端の最大移動量を設定
            tx = -thresholdWisth;
        }else if(t.x >= 0){ //左端の最大移動量を設定
            tx = 0;
        }else{
            tx = t.x;
        }
        
        //マウスに移動量に合わせてステージを移動
        stage.attr('transform', `translate(${tx}, 0)`);
    });
    
//ズームイベントリスナーをsvgに設置    
svg.call(zoom);



</script>
</body>
</html>