d3.js - D3js vertical and horizontal custom line display overflow in zoombable chart -


for project, had create point chart 2 set of lines (the first 1 copprespond d3js axis coordinates in chart basic information , custom 1 particular decimal offsets.

so have created axis x , y , corresponding lines in graph, second set of line corresponding x , y coordinates , zoom.

result, works fine despite second set of lines overflowing chart when zoom/pan. looks lines disappearing when go out of entire svg element.

here code:

let margin = { top: 8, right: 50, bottom: 22, left: 70 },   width = 1140 - margin.left - margin.right,   height = 560 - margin.top - margin.bottom;  let xscale = d3.scale.linear()   .domain([0, this.area.length])   .range([0, width]);  let yscale = d3.scale.linear()   .domain([+(this.area.width / 2), -(this.area.width / 2)])   .range([height, 0]);  let formataxis = d3.format('.0f');  let xaxis = d3.svg.axis()   .scale(xscale)   .orient('bottom')   .ticks(10)   .tickformat(formataxis)   .innerticksize(-height)   .outerticksize(0)   .tickpadding(10);  let yaxis = d3.svg.axis()   .scale(yscale)   .orient('left')   .ticks(6)   .tickformat(formataxis)   .innerticksize(-width)   .outerticksize(0)   .tickpadding(10);    // create svg let svg = d3.select('.chart').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 + ')');    // add x axis svg.append('g')   .attr('class', 'x axis')   .attr('transform', 'translate(0,' + height + ')')   .call(xaxis);    // add y axis svg.append('g')   .attr('class', 'y axis')   .call(yaxis);  // function create x lines let make_x_line = (i: number) => {   svg.append('line')     .attr('y1', yscale(+(this.area.width / 2)))     .attr('y2', yscale(-(this.area.width / 2)))     .attr('x1', xscale(this.xvaluedata[i]))     .attr('x2', xscale(this.xvaluedata[i]))     .attr('class', 'xline' + i)     .attr('stroke-dasharray', '5,5')     .attr('stroke', 'black')     .attr('stroke-width', 2.5)     .attr('fill', 'none'); };  // function create y lines let make_y_line = (i: number) => {   svg.append('line')     .attr('y1', yscale(this.yvaluedata[i]))     .attr('y2', yscale(this.yvaluedata[i]))     .attr('x1', xscale(0))     .attr('x2', xscale(this.area.length))     .attr('class', 'yline' + i)     .attr('stroke-dasharray', '5,5')     .attr('stroke', 'black')     .attr('stroke-width', 2.5)     .attr('fill', 'none'); };  // function zoom let zoom = d3.behavior.zoom()   .x(xscale)   .y(yscale)   .scaleextent([1, 8])   .on('zoom', () => {     d3.select('.x.axis').call(xaxis);     d3.select('.y.axis').call(yaxis);     (let = 0; < this.xvaluedata.length; i++) {       d3.select('.xline' + i).attr('y1', yscale(+(this.area.width / 2)))         .attr('y2', yscale(-(this.area.width / 2)))         .attr('x1', xscale(this.xvaluedata[i]))         .attr('x2', xscale(this.xvaluedata[i]));     }     (let = 0; < this.yvaluedata.length; i++) {       d3.select('.yline' + i).attr('y1', yscale(this.yvaluedata[i]))         .attr('y2', yscale(this.yvaluedata[i]))         .attr('x1', xscale(0))         .attr('x2', xscale(this.area.length));     }   });  // lines grid selection , point creation in x (let = 0; < this.xvaluedata.length; i++) {   make_x_line(i); }  // // // lines grid selection , point creation in y (let = 0; < this.yvaluedata.length; i++) {   make_y_line(i); }  svg.append('rect')   .attr('width', width)   .attr('height', height)   .attr('fill', 'transparent')   .attr('class', 'pane')   .call(zoom)   }); 

here result: normal chart

here display when zoom: zoomed chart

you should use clip path, great idea add lines group, easier handle them.

so create clip path , new groups vertical , horizontal lines , set clip-path attribute. this:

svg.append('clippath').attr('id', 'clip').append('rect').attr('x', 0).attr('y',0).attr('width', width).attr('height', height); let verticallines = svg.append('g').attr('clip-path', 'url(#clip)').attr('class', 'verticallines'); let horizontallines= svg.append('g').attr('clip-path', 'url(#clip)').attr('class', 'horizontallines'); 

and in loop add lines groups above this:

  let make_x_line = (i: number) => {   verticallines.append('line')     .attr('y1', yscale(+(this.area.width / 2)))     .attr('y2', yscale(-(this.area.width / 2)))     .attr('x1', xscale(this.xvaluedata[i]))     .attr('x2', xscale(this.xvaluedata[i]))     .attr('class', 'xline' + i)     .attr('stroke-dasharray', '5,5')     .attr('stroke', 'black')     .attr('stroke-width', 2.5)     .attr('fill', 'none'); }; 

Comments