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)})) }