CodePudding user response:
First of all, if you're using D3 for plotting math functions, you're using the wrong tool. I wrote an explanation here and here.
That said, the important thing here is realising that the tangents go from minus infinity to infinity, and that's clearly something that you don't want. So, what you can do is using the defined
method for skipping some values.
Here, I'm setting a maximum and minimum tangent value you want to plot in the y axis (named maxTan
) in the line generator:
const lineGenerator = d3.line()
.defined(d => Math.tan(d) < maxTan && Math.tan(d) > (-maxTan))
That way the chart will stop at the maxTan
y value, and will resume from minus maxTan
at the bottom, using a single <path>
.
And here is a demo (using radians):
const svg = d3.select("svg"),
margin = 20,
width = 500,
height = 300,
maxTan = 5,
circles = 1;
const xScale = d3.scaleLinear()
.domain([-circles * Math.PI * 2, circles * Math.PI * 2])
.range([margin, width - margin]);
const yScale = d3.scaleLinear()
.domain([-maxTan, maxTan])
.range([height - margin, margin]);
d3.axisBottom(xScale)(svg.append("g").attr("transform", `translate(0,${height/2})`));
d3.axisLeft(yScale)(svg.append("g").attr("transform", `translate(${width/2},0)`));
const data = d3.range(xScale.domain()[0], xScale.domain()[1], 0.025);
const lineGenerator = d3.line()
.defined(d => Math.tan(d) < maxTan && Math.tan(d) > (-maxTan))
.x(d => xScale(d))
.y(d => yScale(Math.tan(d)));
const tan = svg.append("path")
.attr("class", "tanPath")
.datum(data)
.attr("d", d => lineGenerator(d));
.tanPath {
fill: none;
stroke: blue;
stroke-width: 2;
}
<script src="https://d3js.org/d3.v7.min.js"></script>
<svg width="500" height="300"></svg>