蝴蝶刀刀
				不要.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>