不需要的“边界”在用SVG / D3重叠的形状上

发布于 2025-02-10 22:29:13 字数 2369 浏览 2 评论 0 原文

我遵循了本教程:展示SVG / D3的进度栏。

您在教程(至少在Chrome上)可以看到,此图像并非完全重叠,因此我们看到一个小边框。

这两个形状具有完全相同的坐标和大小。

我可以调整顶部的形状以使其尺寸稍大一些,但这很混乱,可能会在某些浏览器上看起来更大?是什么原因导致了这一点,是否有适当的修复?

作为参考,教程的代码:

var svg = d3.select('.progress')
  .append('svg')
  .attr('height', 100)
  .attr('width', 500);

var states = ['started', 'inProgress', 'completed'],
  segmentWidth = 100,
  currentState = 'started';

var colorScale = d3.scale.ordinal()
  .domain(states)
  .range(['yellow', 'orange', 'green']);

svg.append('rect')
  .attr('class', 'bg-rect')
  .attr('rx', 10)
  .attr('ry', 10)
  .attr('fill', 'gray')
  .attr('height', 15) 
  .attr('width', function(){
    return segmentWidth * states.length;
  })
  .attr('x', 0);

var progress = svg.append('rect')
  .attr('class', 'progress-rect')
  .attr('fill', function(){
    return colorScale(currentState);
  })
  .attr('height', 15)
  .attr('width', 0)
  .attr('rx', 10)
  .attr('ry', 10)
  .attr('x', 0);

progress.transition()
  .duration(1000)
  .attr('width', function(){
    var index = states.indexOf(currentState);
    return (index + 1) * segmentWidth;
  });

function moveProgressBar(state){
  progress.transition()
    .duration(1000)
    .attr('fill', function(){
      return colorScale(state);
    })
    .attr('width', function(){
      var index = states.indexOf(state);
      return (index + 1) * segmentWidth;
    });
}
.progressSelector{
  margin-bottom: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<select class="progressSelector" onchange="moveProgressBar(value)">
  <option value="started" selected>Started</option>
  <option value="inProgress">In Progress</option>
  <option value="completed">Completed</option>
</select>

<div class="progress"></div>

I followed this tutorial: https://bl.ocks.org/sarahob/1e291c95c4169ddabb77bbd10b6a7ef7 to show a progress bar with SVG / D3. enter image description here

As you can see on the tutorial (at least on Chrome) and this image, the background shape isn't overlapped entirely, so we see a small border.

The two shapes have exactly the same coordinates and sizes.

I could adjust the shape on top to have a slightly bigger size but that's messy and might risk that it looks bigger on some browsers? What's causing this and is there a proper fix?

For reference, the tutorial's code:

var svg = d3.select('.progress')
  .append('svg')
  .attr('height', 100)
  .attr('width', 500);

var states = ['started', 'inProgress', 'completed'],
  segmentWidth = 100,
  currentState = 'started';

var colorScale = d3.scale.ordinal()
  .domain(states)
  .range(['yellow', 'orange', 'green']);

svg.append('rect')
  .attr('class', 'bg-rect')
  .attr('rx', 10)
  .attr('ry', 10)
  .attr('fill', 'gray')
  .attr('height', 15) 
  .attr('width', function(){
    return segmentWidth * states.length;
  })
  .attr('x', 0);

var progress = svg.append('rect')
  .attr('class', 'progress-rect')
  .attr('fill', function(){
    return colorScale(currentState);
  })
  .attr('height', 15)
  .attr('width', 0)
  .attr('rx', 10)
  .attr('ry', 10)
  .attr('x', 0);

progress.transition()
  .duration(1000)
  .attr('width', function(){
    var index = states.indexOf(currentState);
    return (index + 1) * segmentWidth;
  });

function moveProgressBar(state){
  progress.transition()
    .duration(1000)
    .attr('fill', function(){
      return colorScale(state);
    })
    .attr('width', function(){
      var index = states.indexOf(state);
      return (index + 1) * segmentWidth;
    });
}
.progressSelector{
  margin-bottom: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<select class="progressSelector" onchange="moveProgressBar(value)">
  <option value="started" selected>Started</option>
  <option value="inProgress">In Progress</option>
  <option value="completed">Completed</option>
</select>

<div class="progress"></div>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

余生一个溪 2025-02-17 22:29:13

请参阅此 - 但对于您的教程,有趣的是,它似乎只在灰色上发生黄色。

d3 解决问题的方法是设置:

.style("shape-rendering", "crispEdges");

在背景和前景上 rect

这是一个工作示例:

var svg = d3.select('.progress')
  .append('svg')
  .attr('height', 100)
  .attr('width', 500);

var states = ['started', 'inProgress', 'completed'],
    segmentWidth = 100,
  currentState = 'started';

var colorScale = d3.scale.ordinal()
  .domain(states)
  .range(['yellow', 'orange', 'green']);

svg.append('rect')
  .attr('class', 'bg-rect')
  .attr('rx', 10)
  .attr('ry', 10)
  .attr('fill', 'gray')
  .attr('height', 75) // was 15
  .attr('width', function(){
    return segmentWidth * states.length;
  })
  .attr('x', 0)
  .style("shape-rendering", "crispEdges");

var progress = svg.append('rect')
  .attr('class', 'progress-rect')
  .attr('fill', function(){
    return colorScale(currentState);
  })
  .attr('height', 75) // was 15
  .attr('width', 0)
  .attr('rx', 10)
  .attr('ry', 10)
  .attr('x', 0)
  .style("shape-rendering", "crispEdges");

progress.transition()
  .duration(1000)
  .attr('width', function(){
    var index = states.indexOf(currentState);
    return (index + 1) * segmentWidth;
  });

function moveProgressBar(state){
  progress.transition()
    .duration(1000)
    .attr('fill', function(){
      return colorScale(state);
    })
    .attr('width', function(){
      var index = states.indexOf(state);
      return (index + 1) * segmentWidth;
    });
}
.progressSelector{
  margin-bottom: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<select class="progressSelector" onchange="moveProgressBar(value)">
  <option value="started" selected>Started</option>
  <option value="inProgress">In Progress</option>
  <option value="completed">Completed</option>
</select>

<div class="progress"></div>

See this post - but for your tutorial, interestingly, it only seems to happen with yellow on grey.

The way to resolve the issue is to set:

.style("shape-rendering", "crispEdges");

On both the background and foreground rect.

Here's a working example:

var svg = d3.select('.progress')
  .append('svg')
  .attr('height', 100)
  .attr('width', 500);

var states = ['started', 'inProgress', 'completed'],
    segmentWidth = 100,
  currentState = 'started';

var colorScale = d3.scale.ordinal()
  .domain(states)
  .range(['yellow', 'orange', 'green']);

svg.append('rect')
  .attr('class', 'bg-rect')
  .attr('rx', 10)
  .attr('ry', 10)
  .attr('fill', 'gray')
  .attr('height', 75) // was 15
  .attr('width', function(){
    return segmentWidth * states.length;
  })
  .attr('x', 0)
  .style("shape-rendering", "crispEdges");

var progress = svg.append('rect')
  .attr('class', 'progress-rect')
  .attr('fill', function(){
    return colorScale(currentState);
  })
  .attr('height', 75) // was 15
  .attr('width', 0)
  .attr('rx', 10)
  .attr('ry', 10)
  .attr('x', 0)
  .style("shape-rendering", "crispEdges");

progress.transition()
  .duration(1000)
  .attr('width', function(){
    var index = states.indexOf(currentState);
    return (index + 1) * segmentWidth;
  });

function moveProgressBar(state){
  progress.transition()
    .duration(1000)
    .attr('fill', function(){
      return colorScale(state);
    })
    .attr('width', function(){
      var index = states.indexOf(state);
      return (index + 1) * segmentWidth;
    });
}
.progressSelector{
  margin-bottom: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<select class="progressSelector" onchange="moveProgressBar(value)">
  <option value="started" selected>Started</option>
  <option value="inProgress">In Progress</option>
  <option value="completed">Completed</option>
</select>

<div class="progress"></div>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文