const rxColumn = 'value' const ryColumn = 'gdp' const outerWidth = 960 const outerHeight = 500 const barPadding = 0.2 const radiusMax = 60 const columnCount = 6 const padding = [ 122, 100 ] const radiusScale = d3.scale.sqrt().range([10, radiusMax]) const margin = { left: 230, top: 60, right: 100, bottom: 205 } const innerWidth = outerWidth - margin.left - margin.right const innerHeight = outerHeight - margin.top - margin.bottom // Create tooltip to be show on hoever later const tooltip = d3.select('body') .append('div') .style('position', 'absolute') .style('background', 'white') .style('font-size', '2em') .style('z-index', '10') .style('visibility', 'hidden') .text('a simple tooltip') // Initialize SVG element that all charting will be done in const svg = d3.select('#abacus-app').append('svg') .attr('width', outerWidth) .attr('height', outerHeight) // Add SVG group in which the axis will be drawn const g = svg.append('g') .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')') const legendG = svg.append('g').attr('class', 'legend') legendG .attr('class', 'legend-ordinal') .attr('transform', 'translate(20,20)') const xScale = d3.scale.ordinal().rangePoints([0, innerWidth], barPadding) const continentColors = { asia : '#5E2D5E', 'north-america' : '#AA312D', australia : '#8A710F', europe : '#B97309', antartica : '#CC3F07', 'south-america' : '#A9B641', africa : '#896786' } const continentKeys = Object.keys(continentColors) const continentColorScale = d3.scale.ordinal().domain(continentKeys).range(Object.values(continentColors)) const legendOrdinal = d3.legend.color() .shapePadding(10) .scale(continentColorScale) .labels(continentKeys.map(k => k .split('-') .map(w => `${w[0].toUpperCase()}${w.slice(1)}`) .join(' '))) svg.select('.legend-ordinal') .call(legendOrdinal) function render (data) { console.dir(JSON.stringify(data)) const activeDate = moment(data[0].date, dateFormats.data) document.querySelector('h2#date-header').innerText = activeDate.format(dateFormats.html) xScale.domain(data.sort((a, b) => d3.ascending(a[rxColumn], b[rxColumn])).map(d => d[rxColumn])) radiusScale.domain([ 0, d3.max(data, d => d[ryColumn]) ]) const currencies = g.selectAll('g').data(data) const currenciesEnter = currencies.enter() currenciesEnter.append('g') .attr('class', 'currency') .each(function (d, i) { const selectedThis = d3.select(this) selectedThis .append('ellipse') .attr('cx', i % columnCount * padding[0]) .attr('cy', Math.floor(i / columnCount) * padding[1]) .attr('rx', radiusScale(d[rxColumn])) .attr('ry', radiusScale(d[ryColumn])) .attr('fill', continentColors[d.continent]) .on('mouseover', () => { tooltip.text(`Minor unit: ${d.minorUnit}`) return tooltip.style('visibility', 'visible') }) .on('mousemove', () => tooltip.style('top', (d3.event.pageY-10)+'px').style('left',(d3.event.pageX+10)+'px')) .on('mouseout', () => tooltip.style('visibility', 'hidden')) selectedThis .append('text') .attr('x', i % columnCount * padding[0]) .attr('y', Math.floor(i / columnCount) * padding[1]) .text(`${d.entity} |${d.minorUnit}`) .attr('text-anchor', 'middle') .attr('stroke', continentColors[d.continent]) .attr('fill', 'white') .attr('stroke-width', '.6') .style('pointer-events', 'none') .style('font-weight', '900') .style('font-size', '14') .style('font-family', 'Helvetica Neue') }) currencies.exit().remove() } // Retrieve the pre-formatted currency information. // To create this information for a different date, see the // `fetch` call in 'fetch-money-json.js' d3.json('money.json', entries => render(entries.map(e => { // `minorUnit` is the smallest unit of currency in practical // use within the currency zone. It'd be the penny in the USA. e.minorUnit = +e.minorUnit return e })))