zoom縮放案例
源碼:https://github.com/HK-Kevin/d...;
demo:https://hk-kevin.github.io/d3...;
原理:通過zoom事件來重新繪制x軸scale,同時獲得此時scale,在zoom事件的時候調用函數,將每個數據點的xScale重新繪制一遍。
let data = [[{x: 0, y: 30}, {x: 1, y: 8}, {x: 2, y: 10}, {x: 3, y: 14}, {x: 4, y: 10}, {x: 5, y: 11}, {x: 6,y: 22}, {x: 7, y: 17}, {x: 12, y: 14}, {x: 14, y: 18}, {x: 20, y: 20}]]
//定義圖表數據
let svg = d3.select("svg"),
margin = {top :20,right:20,bottom:50,left:50}, //設值繪圖區的布局
areaWidth = svg.attr("width") - margin.left-margin.right,//獲得繪圖區的寬高
areaHeight = svg.attr("height") - margin.top - margin.bottom,
g = svg.append("g")//繪圖區容器,所有的圖形都放在這里面
.attr("transform",`translate(${margin.left},${margin.top})`)
.attr("width",areaWidth)
.attr("height",areaHeight)
let xScale =d3.scaleLinear()//添加x的尺度,線性的尺度
.domain([0,22])
.range([0,areaWidth]);
let yScale = d3.scaleLinear()//添加x的尺度,線性的尺度
.domain([40,0])
.range([0,areaHeight]) ;
let xAxis = d3.axisBottom(xScale) ;//添加底部坐標軸
let yAxis = d3.axisLeft(yScale) ;//添加左部坐標軸
let line = d3.line() //線生成器,就是把data的數據通過x,y的尺度轉化為此坐標軸對應的數據
.curve(d3.curveStepAfter)
.x(function(d){
return xScale(d.x)
})
.y(function (d) {
return yScale(d.y)
});
let t =d3.transition()//定義動畫
.duration(500) //持續時間
.ease(d3.easeLinear)//動畫type
let xGrooup = g.append("g") //生成x軸
.attr("transform",`translate(0,${areaHeight})`)
.call(xAxis)
let yGroup = g.append("g")//生成y軸
.attr("transform",`translate(0,0)`)
.call(yAxis)
g.append("clipPath") //添加一個剪切區,超出這個區的圖形都不顯示
.attr("id", "clip")
.append("rect")
.attr("width", areaWidth)
.attr("height", areaHeight);
let updateLine = g.append("g") //enter 、update、exit
.attr("class","chart")
.selectAll("line")
.data(data)
let enterLine = updateLine.enter();
let exitLine = updateLine.exit();
let path = enterLine.append("path")
.attr("clip-path", "url(#clip)")
.attr("class","line")
.attr("d",line)
.attr("fill","none")
.attr("stroke",0)
.transition(t)
.attr("stroke-width",2)
.attr("stroke","green")
exitLine.remove();
let zoom = d3.zoom() //設置zoom參數
.scaleExtent([1, 8]) //放大倍數
.translateExtent([[0,0], [areaWidth, areaHeight]])//移動的范圍
.extent([[0, 0], [width, height]])
//視窗 (左上方,右下方),默認最近父級元素的[0,0],[width,height]
.on("zoom", zoomed); //zoom事件,調用zoomed函數
let zoomRect = svg.append("rect") //設置縮放的區域,一般覆蓋整個繪圖區
.attr("width",areaWidth)
.attr("height",areaHeight)
.attr("fill","none")
.attr("pointer-events","all")
.call(zoom);
function zoomed() {
let t = d3.event.transform.rescaleX(xScale) //獲得縮放后的scale
xGrooup.call(xAxis.scale(t)) //重新設置x坐標軸的scale
g.select("path.line").attr("d", line.x(function(d){ //獲取曲線,用新的x尺度來計算line
return t(d.x)}))
}
