How to update the fill color on existing svg elements with d3.js? -


so i'm trying make map .svg file produced illustrator because it's map of netherlands not straightforward regions.

all regions have own #id.

now i'm trying color each region according value in dataset. can force color on regions css ive done on 1 region thats not solution.

if example try select(#id) , change .attr("fill","red"); doesnt work.

how update region colors id using d3.js according d[1] value in dataset ?

files: https://gist.github.com/gordonhatusupy/9466794

live link: http://www.gordonjakob.me/regio_map/

the problem illustrator file specifies fill colours on individual <path> elements, , id values parent <g> elements. child elements inherit styles parents, if child doesn't have values of own.

there couple things change it:

  1. change illustrator file paths have no fill. inherit fill colour set on parent.

  2. select paths directly, using d3.selectall("g#id path") or d3.select("g#id").selectall("path"); either version select <path> elements descendents of <g> elment id "id". can set fill attribute directly over-write value illustrator.


as discussed in comments main question, if want take step further , join data elements future reference (e.g., in event handler), easiest way loop through dataset, select each element, use .datum(newdata) method attach data each element:

dataset.foreach(function(d){ //d of form [id,value]     d3.select("g#"+d[0]) //select group matching id       .datum(d) //attach data future reference       .selectall("path, polygon") //grab shapes       .datum(d) //attach data directly *each* shape future reference       .attr("fill", colour(d[1]) ); //colour based on data }); 

http://jsfiddle.net/ybaj5/6/

if want able select top-level <g> elements in future, suggest giving them class, can select them with, example, d3.select("g.region"). example:

dataset.foreach(function(d){ //d of form [id,value]     d3.select("g#"+d[0]) //select group matching id       .datum(d) //attach data future reference       .classed("region", true) //add class, without erasing existing classes       .selectall("path, polygon") //grab shapes       .datum(d) //attach data directly *each* shape future reference       .attr("fill", colour(d[1]) ); //colour based on data });  d3.selectall("g.region")   .on("click", function(d,i) {          infobox.html("<strong>" + d[0] + ": </strong>" + d[1] );            //print associated data page   }); 

example implementation: http://jsfiddle.net/ybaj5/7/

although using dataset.foreach doesn't seem using full capability of d3, simpler trying attach whole dataset @ once -- since there such variability in structure of regions, of have nested <g> elements:

//option two: select elements @ once , create datajoin d3.selectall("g[id]") //select g elements have id values     .datum(function(){         var id=d3.select(this).attr("id");          return [id, null]; })         //create initial [id, value] dataset based on id attribute,          //with null value     .data(dataset, function(d){return d[0];})         //use first entry in [id,value] key        //to match dataset placeholder data created each     .selectall("path, polygon") //grab shapes     .datum(function(){         return d3.select(this.parentnode).datum() ||         d3.select(this.parentnode.parentnode).datum();     }) //use parent's data if exists, else grandparent's data     .attr("fill", function(d){return d?colour(d[1]):"lightgray";});          //set colour based on data, if there valid data element          //else use gray. 

this fiddle shows above code in action, again recommend using foreach approach.


Comments

Popular posts from this blog

Android layout hidden on keyboard show -

google app engine - 403 Forbidden POST - Flask WTForms -

c - Why would PK11_GenerateRandom() return an error -8023? -