猿问

d3.js:图表外显示的网格线

我在图表中添加了一些网格线。现在我的问题是网格线与图表不对齐。

另外,右侧图表末尾添加了最后一条网格线,是否有可能防止这种情况发生,并且仅向 x 轴上的每个标签添加一条线?

我尝试以某种方式将网格线添加到剪辑路径,但它不起作用。

我的网格线是这样创建的:

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


慕妹3146593
浏览 170回答 1
1回答

蝴蝶刀刀

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

相关分类

JavaScript
我要回答