function createScatterPlot(dataset, width = 600, height = 400) { // Remove existing SVG (for reusability) d3.select("#scatter-plot").select("svg").remove(); // Set margins const margin = { top: 20, right: 30, bottom: 50, left: 50 }; const svgWidth = width - margin.left - margin.right; const svgHeight = height - margin.top - margin.bottom; // Create SVG container const svg = d3.select("#scatter-plot") .append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", `translate(${margin.left},${margin.top})`); // Define scales const xScale = d3.scaleLinear() .domain([0, d3.max(dataset, d => d.hours_studied)]) .range([0, svgWidth]); const yScale = d3.scaleLinear() .domain([0, d3.max(dataset, d => d.test_score)]) .range([svgHeight, 0]); // Add axes svg.append("g") .attr("transform", `translate(0,${svgHeight})`) .call(d3.axisBottom(xScale)); svg.append("g") .call(d3.axisLeft(yScale)); // Add scatter points svg.selectAll("circle") .data(dataset) .enter() .append("circle") .attr("cx", d => xScale(d.hours_studied)) .attr("cy", d => yScale(d.test_score)) .attr("r", 5) .style("fill", "steelblue") .style("opacity", 0.7); // Add axis labels svg.append("text") .attr("x", svgWidth / 2) .attr("y", svgHeight + 40) .style("text-anchor", "middle") .text("Hours Studied"); svg.append("text") .attr("transform", "rotate(-90)") .attr("x", -svgHeight / 2) .attr("y", -35) .style("text-anchor", "middle") .text("Test Score"); } // Example dataset const studentData = [ { hours_studied: 1, test_score: 50 }, { hours_studied: 2, test_score: 55 }, { hours_studied: 3, test_score: 65 }, { hours_studied: 5, test_score: 80 }, { hours_studied: 7, test_score: 90 }, { hours_studied: 9, test_score: 95 } ]; // Render the chart createScatterPlot(studentData);