The red box area is the part that annoys me, that's the start and end point of the path, but it doesn't have a curve effect
my code is simple:
const svg = d3.select("svg");
let data = [[1, 3], [2, 4], [3, 4], [5, 6], [6, 5], [7, 3], [6, 1], [4, 2], [2, 2], [1, 3]]
let datax = data.map(v => v[0])
let datay = data.map(v => v[1])
let scale_x = d3.scaleLinear()
.domain([d3.min(datax), d3.max(datax)])
.range([0, 960])
let scale_y = d3.scaleLinear()
.domain([d3.min(datay), d3.max(datay)])
.range([500, 0])
let curve_generator = d3.line()
.x((d) => scale_x(d[0]))
.y((d) => scale_y(d[1]))
.curve(d3.curveBasis)
svg.append('path')
.attr('d', curve_generator(data))
.attr('stroke', 'gray')
.attr('stroke-width', 2)
.attr('fill', 'none')
CodePudding user response:
It seems to me that in your data the last point is at the same position of the first simply to "close" the path. If that's the case, just remove that last point and use d3.curveBasisClosed
, so D3 will close the path for you:
const svg = d3.select("svg");
let data = [
[1, 3],
[2, 4],
[3, 4],
[5, 6],
[6, 5],
[7, 3],
[6, 1],
[4, 2],
[2, 2]
]
let datax = data.map(v => v[0])
let datay = data.map(v => v[1])
let scale_x = d3.scaleLinear()
.domain([d3.min(datax), d3.max(datax)])
.range([0, 300])
let scale_y = d3.scaleLinear()
.domain([d3.min(datay), d3.max(datay)])
.range([150, 0])
let curve_generator = d3.line()
.x((d) => scale_x(d[0]))
.y((d) => scale_y(d[1]))
.curve(d3.curveBasisClosed)
svg.append('path')
.attr('d', curve_generator(data))
.attr('stroke', 'gray')
.attr('stroke-width', 2)
.attr('fill', 'none')
<script src="https://d3js.org/d3.v7.min.js"></script>
<svg></svg>