Como faço para ajustar o tamanho do zoom para um ponto no D3?

Este poderia ser um caso clássico de "você está fazendo errado", mas todas as minhas buscas até hoje não me ajudaram.

Aqui está o meu cenário:

Eu estou usando uma projeção de mapa albersUSA em conjunto com os arquivos GeoJson nacionais e municipais para desenhar tudo.

Eu também tenho um arquivo de "cidades" auto-criado que contém as principais cidades para cada estado. As coordenadas são precisas e tudo parece bem.

Quando um usuário clica em um determinado estado, eu oculto todas as formas de estado e, em seguida, calculo a transformação necessária para obter as formas do município para que esse estado se ajuste à minha viewport. Em seguida, aplico essa transformação a todas as formas de concelho necessárias para obter a visualização "ampliada". Meu código é o seguinte:

function CalculateTransform(objectPath)
{
   var results = '';

   // Define bounds/points of viewport
   var mapDimensions = getMapViewportDimensions();
   var baseWidth = mapDimensions[0];
   var baseHeight = mapDimensions[1];

   var centerX = baseWidth / 2;
   var centerY = baseHeight / 2;

   // Get bounding box of object path and calculate centroid and zoom factor
   // based on viewport.
   var bbox = objectPath.getBBox();
   var centroid = [bbox.x + bbox.width / 2, bbox.y + bbox.height / 2];
   var zoomScaleFactor = baseHeight / bbox.height;
   var zoomX = -centroid[0];
   var zoomY = -centroid[1];

   // If the width of the state is greater than the height, scale by
   // that property instead so that state will still fit in viewport.
   if (bbox.width > bbox.height) {
      zoomScaleFactor = baseHeight / bbox.width;
   }

   // Calculate how far to move the object path from it's current position to
   // the center of the viewport.
   var augmentX = -(centroid[0] - centerX);
   var augmentY = -(centroid[1] - centerY);

   // Our transform logic consists of:
   // 1. Move the state to the center of the screen.
   // 2. Move the state based on our anticipated scale.
   // 3. Scale the state.
   // 4. Move the state back to accomodate for the scaling.   
   var transform = "translate(" + (augmentX) + "," + (augmentY) + ")" +
                 "translate(" + (-zoomX) + "," + (-zoomY) + ")" +
                 "scale(" + zoomScaleFactor + ")" +
                 "translate(" + (zoomX) + "," + (zoomY) + ")";

   return results;
}

... e a função de ligação

// Load county data for the state specified.
d3.json(jsonUrl, function (json) {
    if (json === undefined || json == null || json.features.length == 0) 
    {
       logging.error("Failed to retrieve county structure data.");
       showMapErrorMessage("Unable to retrieve county structure data.");
       return false;
    }
    else 
    {
       counties.selectAll("path")
                .data(json.features)
                .enter()
                   .append("path")
                      .attr("id", function (d, i) {
                         return "county_" + d.properties.GEO_ID
                      })
                      .attr("data-id", function (d, i) { return d.properties.GEO_ID })
                      .attr("data-name", function (d, i) { return countyLookup[d.properties.GEO_ID] })
                      .attr("data-stateid", function (d, i) { return d.properties.STATE })
                      .attr("d", path);

        // Show all counties for state specified and apply zoom transform.
        d3.selectAll(countySelector).attr("visibility", "visible");
        d3.selectAll(countySelector).attr("transform", stateTransform);

        // Show all cities for the state specified and apply zoom transform
        d3.selectAll(citySelector).attr("visibility", "visible");
        d3.selectAll(citySelector).attr("transform", stateTransform);
    }
});

Isso funciona bem aqui, exceto por estados realmente pequenos, o fator de zoom é muito maior e os círculos ficam distantes.

Existe uma maneira de forçar o tamanho dos pontos a ter um tamanho fixo (digamos, um raio de 15px) mesmo após a transformação ocorrer?

questionAnswers(2)

yourAnswerToTheQuestion