Shann
Shann

Reputation: 690

D3 draw single element from geojson

am pretty new to both JS and D3js. I am trying to create a single circle on the map that transitions (Size increases then decreases) through my data. However, as from this example, 4 elements are added to the svg. and the size of each of them changes at the same time. However, what i want to create a single circle than transitions using the count field. Link to my current block: https://bl.ocks.org/shannondussoye/e8feaa2cf22f7e6a7d12582b923d999f

Thanks

Upvotes: 2

Views: 151

Answers (2)

Andrew Reid
Andrew Reid

Reputation: 38171

Your code here:

var circle = svg.selectAll("circle")
  .data(data.features)
  .enter()
  .append("circle");

Will append one circle for each item in the array data.features (assuming no circles are already present). As there are four items in the array, you'll have four circles. If you just want to append one circle, change the input data array to an array of one feature:

.data([data.features[0]]).enter().append()...

Then, you can update that data, after the initial append, when you want to transition to a new feature:

.data([data.features[i]])
  .attr("attr to be updated",...)

The example below applies this method in a non-geographic setting: 1. append a feature, 2. update the feature with properties from the next item in an array, 3. repeat:

var svg = d3.select("body")
  .append("svg")
  .attr("width",400)
  .attr("height",400);
  
var data = [{x:100,y:100,r:10},{x:200,y:100,r:30},{x:200,y:200,r:10},{y:200,x:100,r:25}];

var circle = svg.selectAll("circle")
  .data([data[0]])
  .enter()
  .append("circle")
  .attr("cx",function(d) { return d.x; })
  .attr("cy",function(d) { return d.y; })
  .attr("r",function(d) { return d.r; });
  
var i = 0;

transition();
  
function transition() {
  circle.data([data[++i%4]])  // get the next item in the data array, assign that datum to the feature
    .transition() 
    .attr("cx",function(d) { return d.x; }) // update the properties of the feature
    .attr("cy",function(d) { return d.y; })
    .attr("r", function(d) { return d.r; })
    .each("end",transition)  // loop
    .duration(2000)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Here is your map with that method (with minimal code changes - though regretfully I changed the json file name)

Upvotes: 1

Gerardo Furtado
Gerardo Furtado

Reputation: 102194

If you do console.log(data.features.length), you'll have the result 4. That means that data.features has 4 arrays and, of course, your enter selection will have 4 circles.

As those arrays seem to have the same geographic position (all of them point to the Town Hall and have the same coordinates, which is "151.2062183,-33.8732664"), use just one of them. For instance, the first array:

var circle = svg.append("circle")
    .datum(data.features[0]);

That will append just one circle, for the first element.

Here is your updated bl.ocks: https://bl.ocks.org/anonymous/7e930937a6d8c0a24c6ca3a033a7cf84/f176a662d4ccd4d33b56101a17e93e6a7e0ef724

Upvotes: 1

Related Questions