Use data imported from a csv file with spaces in the header
When importing data from a csv file(dataSpace.csv) that has headers with spaces in the middle of some of the fields there is need to address the data slightly differently in order for it to be used easily in your JavaScript.
1 2
Date Purchased,close 1-May-12,58.13
When we go to import the data using the d3.csv function, we need to reference the Data Purchased column in a way that makes allowances for the space. The following piece of script appears to be the most basic solution.
// declare a tree layout and assigns the size const treemap = d3.tree() .size([width, height])
// assigns the node data to the tree layout let nodes = d3.hierarchy(treeData)
// map the node data to the tree layout nodes = treemap(nodes)
// append the svg object to the body of the page // append a 'group' element to 'svg' // move the 'groupd' element to the top left margin const svg = d3.select('body').append('svg') .attr('width', width + margin.left + margin.right) .attr('height', height + margin.top + margin.bottom) const g = svg.append('g') .attr('transform', `translate(${margin.left}, ${margin.top})`)
// add links between nodes const link = g.selectAll('.link') .data(nodes.descendants().slice(1)) .enter().append('path') .attr('class', 'link') .attr('d', d => { return`M${d.x},${d.y}C${d.x},${(d.y + d.parent.y) / 2} ${d.parent.x},${(d.y + d.parent.y) /2}${d.parent.x},${d.parent.y}` })
// add each node as a group const node = g.selectAll('.node') .data(nodes.descendants()) .enter().append('circle') .attr('class', d => { return`node ${d.children ? 'node--internal' : 'node--leaf'}` }) .attr('transform', d => { `translate(${d.x}, ${d.y})` })
// add the circle to node node.append('circle') .attr('r', 10)
// add the text to the node node.append('text') .attr('dy', '0.35em') .attr('y', d => (d.children ? -20 : 20)) .style('text-anchor', 'middle') .text(d => d.data.name)
1 2 3 4 5 6 7 8 9
// declare a tree layout and assign the size const treemap = d3.tree() .size([width, height])
// assign the data to a hierarchy using parent-child relationships let nodes = d3.hierarchy(treeData)
// maps the node data to the tree layout nodes = treemap(nodes)
d3.hierarchy
1
const nodes = d3.hierarchy(treeData, d => d.children)
This assigns a range of properties to each node including:
node.data - the data assocaited with the node(in our case it will include the name accessible as node.data.name).
node.depth - a representation of the depth or number of hops from the initial root node.
node.height - the greatest distance from any descendants leaf nodes.
node.parent - the parent node, or null if it’s the root node.
node.children - child nodes or undefined for any leaf nodes.
Above is the vertical tree map code.
If you want a horizontal tree map, you can make a transform like this.
Tooltips have a marvellous duality. They are on one hand a pretty darned useful thing that aids in giving context and information where required and on the other hand, if done with a bit of care they can look stylish.
// add linear gradient element svg.append('linearGradent') // add id for css anchor .attr('id', 'line-gradient') .attr('gradientUnits', 'userSpaceOnUse') // use x1, y1, x2, y2 to define the bounds of the area over which the gradient will act. // here we set x1, x2 to the same value so the gradient won't act on x direction. .attr('x1', 0).attr('y1', yScale(0)) .attr('x2', 0).attr('y2', yScale(1000)) // select all 'stop' elements for the gradients, these 'stop' elements define where on the range covered by our coordinates the color start and stop(percent or decimal) .selectAll('stop') .data([ {offset: '0%', color: 'red'}, {offset: '40%', color: 'red'}, {offset: '40%', color: 'black'}, {offset: '62%', color: 'black'}, {offset: '62%', color: 'lawngreen'}, {offset: '62%', color: 'lawngreen'}, {offset: '100%', color: 'lawngreen'}, ]) .enter().append('stop') .attr('offset', d => d.offset) .attr('stop-color', d => d.color)
There is our anchor on the third line.
If you want to apply the gradient on area, simply change the css