score:3
Accepted answer
- Get the value range:
const valueRange = json.reduce((r, s) => r ?
[Math.min(r[0], s.Total), Math.max([1], s.Total)] :
[s.Total, s.Total], null);
- Build a color scale:
const color = d3.scaleLinear()
.domain(valueRange)
.range(["#FF0000", "#800000"]);
- Set color for each state's path:
svg.selectAll('g.state')
.select('path')
.style('fill', d => {
const stateData = json.find(s => s.State === d.properties.STATE_NAME);
return stateData ? color(stateData.Total) : 'white';
})
const w = 850;
const h = 700;
//Define map projection // geoEqualEarth
const projection = d3.geoMercator()
.center([ 132, -28 ])
.translate([ w/2, h/2 ])
.scale(1000);
//Define path generator
const path = d3.geoPath()
.projection(projection);
//Create SVG
const svg = d3.select("svg")
.attr('width', w)
.attr('height', h)
//Load in GeoJSON data
d3.json('https://gist.githubusercontent.com/GerardoFurtado/02aa65e5522104cb692e/raw/8108fbd4103a827e67444381ff594f7df8450411/aust.json')
.then(json => onGeoJsonLoaded(json))
.catch(err => console.log('GEO ERROR: ', err));
const onGeoJsonLoaded = json => {
//Bind data and create one path per GeoJSON feature
const states = svg.selectAll('g.state')
.data(json.features)
.enter()
.append('g')
.classed('state', true);
states.append('path')
.attr("d", path)
.attr("stroke", 'white');
//.attr("fill", (d, i) => color[i]);
//States
states.append("text")
.attr("fill", "white")
.attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; })
.attr("text-anchor", "middle")
.attr("dy", 15)
.text(function(d) {
return d.properties.STATE_NAME;
});
//Append the name
d3.json('https://api.jsonbin.io/b/60af2dc3d0f4985540524d62')
.then(dataJson => onDataJsonLoaded(dataJson))
.catch(err => console.log('DATA JSON ERR: ', err));
}
const tooltipPath = (width, height, offset, radius) => {
const left = -width / 2
const right = width / 2
const top = -offset - height
const bottom = -offset
return `M 0,0
L ${-offset},${bottom}
H ${left + radius}
Q ${left},${bottom} ${left},${bottom - radius}
V ${top + radius}
Q ${left},${top} ${left + radius},${top}
H ${right - radius}
Q ${right},${top} ${right},${top + radius}
V ${bottom - radius}
Q ${right},${bottom} ${right - radius},${bottom}
H ${offset}
L 0,0 z`
}
const onDataJsonLoaded = json => {
const valueRange = json.reduce((r, s) => r ?
[Math.min(r[0], s.Total), Math.max([1], s.Total)] :
[s.Total, s.Total], null);
const color = d3.scaleLinear()
.domain(valueRange)
.range(["#FF0000", "#800000"]);
const states = svg.selectAll('g.state');
states.select('path')
.style('fill', d => {
const stateData = json.find(s => s.State === d.properties.STATE_NAME);
return stateData ? color(stateData.Total) : 'white';
})
const rows = Object.keys(json[0]).filter(n => n !== 'State');
const tooltip = svg.append('g')
.classed('tooltip', true)
.style('visibility', 'hidden');
tooltip.append('path')
.attr('d', tooltipPath(150, 80, 5, 5))
rows.forEach((row, index) => {
tooltip.append('text')
.text(`${row} :`)
.attr('x', -70)
.attr('y', -68 + index * 18);
tooltip.append('text')
.classed(row.replace(' ', '_'), true)
.attr('x', 40)
.attr('y', -68 + index * 18)
}
);
states
.on('mouseenter', d => {
const stateData = json.find(s => s.State === d.properties.STATE_NAME);
rows.forEach(row => tooltip.select(`.${row.replace(' ', '_')}`).text(stateData[row]));
tooltip.attr('transform', `translate(${path.centroid(d)})`);
tooltip.style('visibility', 'visible');
})
.on('mouseleave', () => tooltip.style('visibility', 'hidden'));
};
.tooltip > path {
fill: white;
stroke: black;
}
.tooltip > text {
font-family: "Ubuntu";
font-size: 12px;
fill: black;
stroke: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg/>
Source: stackoverflow.com
Related Query
- How can we load color from a sequential scale into a map in D3 v5?
- How can I color one Y-axis line different from the other grid-lines?
- how to map numbers to a three color scale with D3.js?
- d3: how can I load external CSV file into data?
- How to get a value from a stylesheet into the code so that it can be used programmatically?
- How to load a csv file from static in django into javascript function
- How can I scale my map to fit my svg size with d3 and geojson path data
- How can I pass json data returned from a webservice into D3.json(...)?
- How can we load a CSV file into JupyterLab using d3?
- Using d3 to read in information from a CSV file, how can i store values of a particular type into a variable?
- In D3 Sankey, how can I load the from objects or arrays instead of either json or csv files?
- How do I remove all children elements from a node and then apply them again with different color and size?
- How to load data from a CSV file in D3 v5
- How to customize the color scale in a D3 line chart?
- How can I efficiently move from a Pandas dataframe to JSON
- how can I exclude an element from an Angular scope?
- How can I keep tick marks from repeating when I have a small number of dates on an nvd3 chart
- Continuous color scale from discrete domain of strings?
- How to load data from an internal JSON array rather than from an external resource / file for a collapsible tree in d3.js?
- How to make a color scale in D3 JS to use in fill attribute?
- How can I dispatch a 'zoom' event after setting scale (d3, zoom.behavior)
- How can I set the each line color or width in SVG path
- How to divide a map into zipcodes using d3, javascript, and a json file?
- How can I convert SVG coordinates (x,y) defined relatively to an element into absolute coordinates/position?
- How can I remove a line from the 110m TopoJson world map?
- How can I connect two parent node into one child node and how to make a tooltip for each node in the tree pragmatically? in D3 js (SVG)
- How can I connect coordinate points on a map using d3js?
- how much can d3 js scale
- For some reason, my D3 Map is displaying upside down - how can I flip it?
- How to center & scale map in d3js (use projection.center/translate/rotate?)
More Query from same tag
- How to make d3-diagram visualization from json-array working?
- d3 appears to silently truncate array in .data() method
- D3.js: Set fitExtent or fitSize (or center and scale programmatically) for map with multiple geoJSON files
- Angular 7 integration with D3: adding click listener throws error
- Force a d3 line chart to ignore null values
- d3.js:670 Error: <rect> attribute y: Expected length, "NaN"
- d3/jQuery - On start select all, but when one is selected - deselect all except that one, but allow individual selection of each element again
- Rotate D3 SVG to line up to specific angle
- zoom d3.js tree for a particular node
- bring circle to top on mouseover with d4.v4
- How to make axis have a top tick
- How to specify multiple event types in D3.js
- How to pause d3.js simulation using javascript?
- How to draw graphs using d3.js for a big dataset?
- D3 - Update single grid line after data change
- d3.js v3 time scale: How to change default hour in label to specific hour
- Problems Passing JSON from Flask Template to HTML to Static JS Script
- Uncaught (in promise) TypeError: d3.group is not a function
- How to access original data after applying d3.stratify()?
- Choropleth Alternative Method and more
- Loop D3 animation of polygon vertex
- Importing data from excel files in D3 js
- How to add columnn titles in a Sankey chart networkD3
- Append links to side of rectangles in D3 tree layout
- I am trying to visualize my json object with D3. I want date to be the x axis and y to be sales. number values stored a string
- getTotalLength() returns 0 on path
- Customize grid lines in d3 bar chart
- How to redraw my d3.js chart with data from html form?
- Line with nested json attributes
- Events in d3 graphs