chart2={
const svgWidth = 500;
const svgHeight = 500;
const margin = { top: 20, right: 20, bottom: 30, left: 40 };
const width = svgWidth - margin.left - margin.right;
const height = svgHeight - margin.top - margin.bottom;
const svg = d3.create("svg")
.attr("width", svgWidth)
.attr("height", svgHeight);
var e = m/2;
var ellipsesData = [
{ cx: 250, cy: 190, rx: 199, ry: 68, angle: 40 },
{ cx: 250, cy: 190, rx: 32, ry: 20, angle: 40 },
{ cx: 250, cy: 190, rx: 200 - 1.68*m, ry: 68- 0.48*m, angle: 40 , style: "black" }
];
const circleData = [
{ cx:150, cy: 260, r: 50 + e, color: "black" }
];
svg.selectAll("circle")
.data(circleData)
.enter()
.append("circle")
.attr("cx", d => d.cx) // x-coordinate of the center
.attr("cy", d => d.cy) // y-coordinate of the center
.attr("r", d => d.r) // radius
.attr("stroke", d => d.color)
.style("fill", "lightgrey");// fill color
// Function to create arrowheads
function createArrowhead(id, orientation) {
svg.append("defs").append("marker")
.attr("id", id)
.attr("refX", 6)
.attr("refY", 6)
.attr("markerWidth", 10)
.attr("markerHeight", 10)
.attr("orient", orientation)
.append("path")
.attr("d", "M2,2 L6,6 L2,10 L10,6 L2,2")
.style("fill", "grey");
}
// Create arrowheads for different directions
createArrowhead("arrowhead-left", 180);
createArrowhead("arrowhead-right", 0);
createArrowhead("arrowhead-up", 270);
createArrowhead("arrowhead-down", 90);
// Render X and Y axes
svg.append("line")
.attr("x1", 20)
.attr("y1", 260)
.attr("x2", 480)
.attr("y2", 260)
.style("stroke", "grey")
.attr("marker-start", "url(#arrowhead-left)")
.attr("marker-end", "url(#arrowhead-right)");
svg.append("line")
.attr("x1", 150)
.attr("y1", 50)
.attr("x2", 150)
.attr("y2", 380)
.style("stroke", "grey")
.attr("marker-start", "url(#arrowhead-up)")
.attr("marker-end", "url(#arrowhead-down)")
// Add "beta2" beside the Y-axis
svg.append("text")
.attr("x", 130) // Adjust the x-coordinate for positioning
.attr("y", 50) // Adjust the y-coordinate for positioning
.style("fill", "black")
.style("font-size", "14px")
.text("β")
.append("tspan")
.attr("dy", "0.5em")
.attr("font-size", "0.8em")
.text("2");
// Add "beta1" beside the X-axis
svg.append("text")
.attr("x", 480) // Adjust the x-coordinate for positioning
.attr("y", 275) // Adjust the y-coordinate for positioning
.style("fill", "black")
.style("font-size", "14px")
.text("β")
.append("tspan")
.attr("dy", "0.5em")
.attr("font-size", "0.8em")
.text("1");
// Add "beta1" beside the X-axis
svg.append("text")
.attr("x", 540) // Adjust the x-coordinate for positioning
.attr("y", 275) // Adjust the y-coordinate for positioning
.style("fill", "black")
.style("font-size", "14px")
.text("β")
.append("tspan")
.attr("dy", "0.5em")
.attr("font-size", "0.8em")
.text("1");
svg.selectAll("ellipse")
.data(ellipsesData)
.enter()
.append("ellipse")
.attr("cx", function (d) { return d.cx; })
.attr("cy", function (d) { return d.cy; })
.attr("rx", function (d) { return d.rx; })
.attr("ry", function (d) { return d.ry; })
.attr("transform", function (d) {
return "rotate(" + d.angle + " " + d.cx + " " + d.cy + ")";
})
.style("fill", "none")
.style("stroke", function (d) { return d.style || "steelblue"; }); // Use "black" if style is defined, otherwise use "steelblue"
// Make the red dotted line
svg.append("line")
.attr("x1", 187)
.attr("y1", 223)
.attr("x2", 248)
.attr("y2", 188)
.style("stroke", "red")
.style("stroke-width", 3)
.style("stroke-dasharray", "3,3");
// Make dot at the center
svg.selectAll("dot")
.data(ellipsesData)
.enter()
.append("circle")
.attr("cx", function (d) { return d.cx -2; })
.attr("cy", function (d) { return d.cy - 2; })
.attr("r", 3) // Radius of the dot
.style("fill", "black");
// Add "OLS" label beside the dots
svg.selectAll("label")
.data(ellipsesData)
.enter()
.append("text")
.attr("x", function (d) { return d.cx + 5; }) // Adjust the x-coordinate for positioning
.attr("y", function (d) { return d.cy; })
.text("OLS")
.style("fill", "black")
.style("font-size", "10px");
// Make dot for the smallest ellipse
svg.selectAll("dot")
.data(ellipsesData)
.enter()
.append("circle")
.attr("cx", 187 + 0.43*m)
.attr("cy", 223 - 0.26*m )
.attr("r", 3) // Radius of the dot
.style("fill", "steelblue");
// ... Previous code ...
// Calculate the coordinates where the circle touches the ellipse
const circleCenterX = 150;
const circleCenterY = 260;
const circleRadius = 50 + e; // Radius of the circle
const ellipseCenterX = 250;
const ellipseCenterY = 190;
const ellipseMajorAxis = 199;
const ellipseMinorAxis = 68;
const ellipseAngle = 40; // Angle of rotation
// Convert the angle to radians
const angleInRadians = (ellipseAngle * Math.PI) / 180;
// Calculate the coordinates
const x1 = ellipseCenterX + (ellipseMajorAxis / 2) * Math.cos(angleInRadians);
const y1 = ellipseCenterY + (ellipseMinorAxis / 2) * Math.sin(angleInRadians);
const x2 = ellipseCenterX - (ellipseMajorAxis / 2) * Math.cos(angleInRadians);
const y2 = ellipseCenterY - (ellipseMinorAxis / 2) * Math.sin(angleInRadians);
const touchingPoints = [];
// Check if the circle touches the ellipse
if (
(circleCenterX - x1) ** 2 + (circleCenterY - y1) ** 2 === circleRadius ** 2
) {
touchingPoints.push({ x: x1, y: y1 });
}
if (
(circleCenterX - x2) ** 2 + (circleCenterY - y2) ** 2 === circleRadius ** 2
) {
touchingPoints.push({ x: x2, y: y2 });
}
svg.append("text")
.attr("x", 10) // X-coordinate of the text
.attr("y", 100) // Y-coordinate of the text
.text(`x1= ${touchingPoints}, y1= ${y1}, x2=${x2}, y2 = ${y2}`) // Text content
.attr("font-size", "12px") // Font size
.attr("fill", "blue"); // Text color
svg.selectAll(".coordinate-text")
.data(touchingPoints)
.enter()
.append("text")
.attr("class", "coordinate-text")
.attr("x", d => d.x + 5) // Adjust the x-coordinate for positioning
.attr("y", d => d.y - 5) // Adjust the y-coordinate for positioning
.text(d => `(${d.x.toFixed(2)}, ${d.y.toFixed(2)})`) // Display coordinates with 2 decimal places
.style("fill", "black")
.style("font-size", "12px");
// ... Previous code for drawing ellipses, circle, and axes ...
// Add red dots at the points of contact
svg.selectAll(".dot")
.data(touchingPoints)
.enter()
.append("circle")
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("r", 15)
.attr("fill", "red");
// ... Return the SVG container ...
return svg.node();
}