D3.js and Livewire Integration: Points Not Appearing on Zoomed Region

I’m working on a project that integrates D3.js with Livewire (v3.4) in a Laravel application. I aim to display points (schools) on a map when a region (polygon) is clicked and zoomed in. The points should load dynamically based on the region’s desa_code using a Livewire method.

The issue I’m facing is that while the map is zoomed and the popup with region information displays correctly, the points do not appear on the canvas, and the regions sometimes disappear.

Here’s a summary of my process:

  1. Map and regions (polygons) load correctly from a GeoJSON file.
  2. On clicking a region, it zooms in and calls the Livewire method to load the corresponding points (schools).
  3. Points should be drawn on the map after the region is zoomed in, but they don’t appear.

Code Overview:

1. Livewire Component (PHP)

#[On('loadPoints')]
public function loadPoints($desaCode)
{
    $this->points = AppModelsMapHistory::getSekolahsWithinDesa($desaCode);
    $this->dispatchBrowserEvent('pointsLoaded', ['points' => $this->points]);
}

2. JavaScript (D3 and Livewire Integration)

function clicked(event, d) {
    event.stopPropagation();

    if (active === this) { 
        return reset();
    }

    active = this;

    features.transition().duration(500)
        .style("opacity", function() {
            return this === active ? 1 : 0;
        });

    const [[x0, y0], [x1, y1]] = path.bounds(d);
    svg.transition().duration(1000).call(
        zoom.transform,
        d3.zoomIdentity.translate(width / 2, height / 2)
        .scale(Math.min(8, 0.9 / Math.max((x1 - x0) / width, (y1 - y0) / height)))
        .translate(-(x0 + x1) / 2, -(y0 + y1) / 2)
    );

    // Load points (schools) based on desaCode
    Livewire.emit('loadPoints', d.properties.desa_code);
}

Livewire.on('pointsLoaded', (event) => {
    var points = JSON.parse(event.points);
    var pointsLayer = d3.select("#map").select("svg").append("g");

    pointsLayer.selectAll("circle").remove();
    pointsLayer.selectAll("circle")
        .data(points.features)
        .enter().append("circle")
        .attr("cx", function(d) {
            return projection([d.geometry.coordinates[0], d.geometry.coordinates[1]])[0];
        })
        .attr("cy", function(d) {
            return projection([d.geometry.coordinates[0], d.geometry.coordinates[1]])[1];
        })
        .attr("r", 5)
        .attr("fill", "blue")
        .on("click", function(d) {
            alert(`Sekolah: ${d.properties.name}nBentuk: ${d.properties.bentuk}nPegawai: ${d.properties.pegawai_count}`);
        });
});

3. Complete Code

Here’s the complete code it works fine when I zoom the region, but I would like the points to appear inside the zoomed region.

function showInfoPopup(event, properties) {
    d3.select("#info-popup").remove();

    var popup = d3.select("body").append("div")
        .attr("id", "info-popup")
        .style("position", "absolute")
        .style("background", "white")
        .style("border", "1px solid #ccc")
        .style("padding", "10px")
        .style("left", (event.pageX + 10) + "px")
        .style("top", (event.pageY + 10) + "px");

    // Add close button
    popup.append("button")
        .text("Close")
        .on("click", function () {
            d3.select("#info-popup").remove();
        });

    popup.append("h4").text("Informasi Wilayah");
    popup.append("p").text(`Desa: ${properties.desa_name}`);
    popup.append("p").text(`Kecamatan: ${properties.kecamatan_name}`);
}

Issue:

  1. Regions sometimes disappear on Zoom, and points do not appear on the canvas.
  2. The pointsLoaded event returns the correct data (checked with console.log(points)), but the points aren’t rendered.
  3. I suspect there may be an issue with how the points are layered or attached to the canvas after Zoom.

What I’ve Tried:

  • Verified that points are returned correctly from Livewire.
  • Used D3’s .data() to bind the points data to circle elements.
  • Tried different projection methods and cx/cy calculations.

Any help on how to correctly render the points and maintain the regions on Zoom would be greatly appreciated!