score:11
The problem is that your Illustrator file already specifies fill colours on the individual <path>
elements, and your id values are for parent <g>
elements. Child elements inherit styles from parents, but only if the child doesn't have values of its own.
There are a couple things you could do to change it:
Change the Illustrator file so that the paths have no fill. Then they will inherit a fill colour set on the parent.
Select the paths directly, using
d3.selectAll("g#id path")
ord3.select("g#id").selectAll("path")
; either version will select all<path>
elements that are descendents of the<g>
elment with id "id". Then you can set the fill attribute directly to over-write the value from Illustrator.
As discussed in the comments to the main question, if you want to take this a step further and actually join the data to the elements for future reference (e.g., in an event handler), the easiest way is to loop through your dataset, select each element, then use the .datum(newData)
method to attach the data to each element:
dataset.forEach(function(d){ //d is of form [id,value]
d3.select("g#"+d[0]) //select the group matching the id
.datum(d) //attach this data for future reference
.selectAll("path, polygon") //grab the shapes
.datum(d) //attach the data directly to *each* shape for future reference
.attr("fill", colour(d[1]) ); //colour based on the data
});
If you want to be able to select all the top-level <g>
elements in the future, I would suggest also giving them a class, so you can select them with, for example, d3.select("g.region")
. For example:
dataset.forEach(function(d){ //d is of form [id,value]
d3.select("g#"+d[0]) //select the group matching the id
.datum(d) //attach this data for future reference
.classed("region", true) //add a class, without erasing any existing classes
.selectAll("path, polygon") //grab the shapes
.datum(d) //attach the data directly to *each* shape for future reference
.attr("fill", colour(d[1]) ); //colour based on the data
});
d3.selectAll("g.region")
.on("click", function(d,i) {
infoBox.html("<strong>" + d[0] + ": </strong>" + d[1] );
//print the associated data to the page
});
Example implementation: http://jsfiddle.net/ybAj5/7/
Although using dataset.forEach
doesn't seem to be using the full capability of d3, it is actually much simpler than trying to attach the whole dataset at once -- especially since there is such variability in the structure of the regions, some of which have nested <g>
elements:
//Option two: select all elements at once and create a datajoin
d3.selectAll("g[id]") //select only g elements that have id values
.datum(function(){
var id=d3.select(this).attr("id");
return [id, null]; })
//create an initial [id, value] dataset based on the id attribute,
//with null value for now
.data(dataset, function(d){return d[0];})
//use the first entry in [id,value] as the key
//to match the dataset with the placeholder data we just created for each
.selectAll("path, polygon") //grab the shapes
.datum(function(){
return d3.select(this.parentNode).datum() ||
d3.select(this.parentNode.parentNode).datum();
}) //use the parent's data if it exists, else the grandparent's data
.attr("fill", function(d){return d?colour(d[1]):"lightgray";});
//set the colour based on the data, if there is a valid data element
//else use gray.
This fiddle shows the above code in action, but again I would recommend using the forEach
approach.
Source: stackoverflow.com
Related Query
- How to update the fill color on existing svg elements with d3.js?
- How to force update the fill color of existing elements in d3?
- How do you update an existing svg element with the d3v5 join syntax
- How to simultaneously update the color of elements in a SVG when I mouseover elements of a second SVG using D3
- How to update all existing elements in the same level with same parent value?
- How to use D3 force layout with existing SVG elements as nodes
- d3.js: How to deal with svg elements that are being appended on the same position, one on top of the other?
- How to fill half of the rectangle with color in d3.js
- d3js - How to update an existing svg path in a simple d3 line chart with new data flowing through?
- How do I remove all children elements from a node and then apply them again with different color and size?
- d3.js - How can I set the cursor to hand when mouseover these elements on SVG container?
- How to update elements of D3 force layout when the underlying data changes
- How to update an svg path with d3.js
- Fill SVG element with a repeating linear gradient color
- How do I associate SVG elements generated by graphviz to elements in the DOT source code
- How can I set the each line color or width in SVG path
- How to update elements of an HTML that the elements are created using data from a CSV file?
- Join existing elements of the DOM to data with d3.js
- How to move elements along with svg group
- D3.js how to transition in opposite direction with basic SVG elements
- d3 update selections: How does d3 decide which existing html elements to capture for its own use?
- How do I scroll d3 elements while keeping a portion of the svg in a fixed position?
- How to update the contents of a text input with d3?
- Get attributes of existing SVG elements and bind as data with d3.js
- How to update the fill and sorting the values of lollipop chart?
- How do you translate HTML elements along with SVG elements when zooming and panning with D3
- How to add links from CSV file to SVG elements generated with D3?
- How can I add an external group to an existing svg with d3.js?
- How to properly use the Use tag in SVG with d3 js?
- How do you prevent the interference of MULTIPLE SVG elements (text labels) on mouseover of a different SVG element?
More Query from same tag
- d3js Text Transition I example with v3 library
- What is Null doing when it is inserted into an attribute function in d3?
- Code flow through callback in java script
- D3 unexpected value translate, won't accept variable
- How to group multiple values in nested D3 to create multiple rollup sum chart ?
- updating d3 data using intervals
- how to add tooltip for rectangles in d3.js reading from json
- Problem with drawing an arc on a d3 canvas map
- How do I save/export an SVG file after creating an SVG with D3.js (IE, safari and chrome)?
- d3JS cloud chart: avoid overlapping words
- Remove Duplicates from D3js Dropdown
- Electron file loaded but not showing in Network tab
- D3.js combining bar and line chart
- D3 hierarchy collapse to first level by default
- How to interpolate or get color for the point/values not in specified color table range
- How to properly calculate width for D3 Siluohette stacked Area chart
- Why my rotated tick values are not getting displayed completely d3js?
- Is there a correct way to spot non-fatal errors in js?
- D3 version 4 tree view with rectangle nodes links not showing up
- How to add d3 or any module to angular 2 using Angular CLI?
- Given latitude and longitude, plotting points on D3 geo projection
- How to load and print json array/object in javascript
- Drawing data 1 by 1 D3 js
- d3.js How to not graph values outside of range?
- d3 get all nodes of tree
- Where is this fill function defined?
- d3 sunburst hardcoded data
- Two array of objects are merging, but they're not sorting - D3
- d3 force collapsible layout - start page with all nodes collapsed
- Linking up JSON data to g elements in d3