蝴蝶刀刀
不要.append()在updateChart. 你永远不会删除你绘制的轴,只需在它们上面绘制新的轴......只需使用以下命令将现有的轴变成带有网格线的轴即可tickSizeInner():var signalData = { signal1: { name: "signal1", data: [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 1, 2, 3, 5, 4, 1, 4, 2, 9, 7, 5, 7, 4, 6], }, signal2: { name: "signal2", data: [6, 4, 8, 5, 4, 8, 4, 3, 5, 4, 5, 8, 7, 2, 9, 5, 4, 1, 2, 6, 0, 5, 7, 1], }, signal3: { name: "signal3", data: [9, 5, 12, 3, 8, 4, 8, 6, 3, 4, 7, 8, 5, 2, 1, 8, 6, 8, 5, 8, 4, 8, 5, 1], },}var margin = { top: 10, right: 50, bottom: 40, left: 50,};var width = window.innerWidth - margin.left - margin.right;var height = 230 - margin.top - margin.bottom;var minimapHeight = 150 - margin.top - margin.bottom;var xScale = d3 .scaleLinear() .domain([ 0, d3.max(Object.keys(signalData), (d) => signalData[d].data.length), ]) // input .range([0, width]); // outputvar brushXScale = d3 .scaleLinear() .domain([ 0, d3.max(Object.keys(signalData), (d) => signalData[d].data.length), ]) // input .range([0, width]); // outputvar zoomBrush = d3 .brushX() .extent([ [0, 0], [width, minimapHeight], ]) .on("brush", zoomBrushed) .on("end", function(event) { if (event.selection == null) { resetZoom(); } });var selectBrush = d3 .brushX() .extent([ [0, 0], [width, height], ]) .on("brush", selectBrushed) .on("end", function(event) { if (event.selection == null) { resetSelection(); } });function resetZoom() { brushXScale.domain([ 0, d3.max(Object.keys(signalData), (d) => signalData[d].data.length), ]); // input for (var signal in signalData) { updateChart(signalData[signal].data, signalData[signal].name); }}function zoomBrushed() { var selectionPx = d3.brushSelection(this); // === [lower, upper] in pixels // transform from pixels to x-values var selectionX = [ xScale.invert(selectionPx[0]), xScale.invert(selectionPx[1]), ]; // set x scale domain, then redraw the lines brushXScale.domain(selectionX); for (var signal in signalData) { updateChart(signalData[signal].data, signalData[signal].name); }}function resetSelection() { selectBrush.on("end", null); d3.selectAll("div[id^=signal] svg .brushcontainer").call( selectBrush.clear ); selectBrush.on("end", function(event) { if (event.selection == null) { resetSelection(); } });}function selectBrushed() { var selectionPx = d3.brushSelection(this); // === [lower, upper] in pixels selectBrush.on("brush", null); d3.selectAll("div[id^=signal] svg .brushcontainer").call( selectBrush.move, selectionPx ); selectBrush.on("brush", selectBrushed);}//Generate the brush focus chartgenerateMinimap(signalData.signal1.data);//Generate charts dynamically as often as i have signalsfor (var signal in this.signalData) { generateChart(signalData[signal].data, signalData[signal].name);}// This function is for the one time preparationsfunction generateChart(data, name) { var svg = d3 .select("#" + name) .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 + ")" ); //clipPath to prevent path from overflow svg .append("defs") .append("clipPath") .attr("id", "clip") .append("rect") .attr("width", width) .attr("height", height); svg.append("g").attr("class", "brushcontainer").call(selectBrush); svg .append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")"); svg.append("g").attr("class", "y axis"); svg .append("path") .attr("clip-path", "url(#clip)") .attr("class", "line") // Assign a class for styling .attr("fill", "none") .attr("stroke", "blue"); updateChart(data, name);}// This function needs to be called to update the already prepared chartfunction updateChart(data, name) { var svg = d3.select("#" + name + " svg"); var yScale = d3 .scaleLinear() .domain([0, d3.max(data)]) // input .range([height, 0]); // output var line = d3 .line() .x((d, i) => brushXScale(i)) .y((d) => yScale(d)); svg.select(".x.axis").call( d3.axisBottom(brushXScale) .tickSizeOuter(0) .tickSizeInner(-height) ); svg.select(".y.axis").call( d3.axisLeft(yScale) .tickSizeInner(-width) .tickSizeOuter(0) .ticks(5) ); svg .select(".line") .datum(data) // 10. Binds data to the line .attr("d", line); // 11. Calls the line generator}function generateMinimap(data) { var yScale = d3 .scaleLinear() .domain([0, d3.max(data)]) // input .range([minimapHeight, 0]); // output var line = d3 .line() .x((d, i) => xScale(i)) .y((d) => yScale(d)); var svg = d3 .select("#minimap") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", minimapHeight + margin.top + margin.bottom) .append("g") .attr( "transform", "translate(" + margin.left + "," + margin.top + ")" ); svg.append("g").call(zoomBrush); svg .append("g") .attr("class", "x axis") .attr("transform", "translate(0," + minimapHeight + ")") .call(d3.axisBottom(xScale)); // Create an axis component with d3.axisBottom svg .append("path") .datum(data) // 10. Binds data to the line .attr("class", "line") // Assign a class for styling .attr("d", line) // 11. Calls the line generator .attr("fill-opacity", "0.17") .attr("fill", "blue") .attr("stroke", "blue");}.tick line { stroke-dasharray: 3 3;}<div id="minimap"></div><!-- In the original project these divs are not static and get generated with v-for as many times as i have a signal in signalData --><div id="signal1"></div><div id="signal2"></div><div id="signal3"></div><script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.min.js"></script>