UNPKG

cartogram-chart

Version:

Cartogram web component for visualizing geographical data by distorting a TopoJson topology

123 lines (115 loc) 4.35 kB
import { select } from 'd3-selection'; import 'd3-transition'; import { geoMercator } from 'd3-geo'; import { cartogram as cartogram$1 } from 'topogram'; import Kapsule from 'kapsule'; import accessorFn from 'accessor-fn'; import Tooltip from 'float-tooltip'; var ANIMATION_DURATION = 1200; var cartogram = new Kapsule({ props: { width: { "default": window.innerWidth }, height: { "default": window.innerHeight }, iterations: { "default": 20 }, projection: { "default": geoMercator().scale(Math.min((window.innerWidth - 3) / (2 * Math.PI), (window.innerHeight - 3) / (1.2 * Math.PI))).translate([window.innerWidth / 2, window.innerHeight / 1.5]) }, topoJson: {}, topoObjectName: {}, value: { "default": 1 }, color: { "default": 'lightgrey' }, label: { triggerUpdate: false }, valFormatter: { "default": function _default(n) { return n; }, triggerUpdate: false }, units: { "default": '', triggerUpdate: false }, tooltipContent: { triggerUpdate: false }, onClick: {} }, init: function init(domNode, state) { state.cartogram = cartogram$1().properties(function (d) { return d.properties; }); // Dom var el = select(domNode).append('div').attr('class', 'cartogram'); state.svg = el.append('svg'); // tooltip state.tooltip = new Tooltip(el); }, update: function update(state) { var valueOf = accessorFn(state.value); var colorOf = accessorFn(state.color); state.svg.attr('width', state.width).attr('height', state.height); if (!state.topoJson) return; // No features to render var topoObject = state.topoJson.objects[state.topoObjectName] || Object.values(state.topoJson.objects)[0]; if (!topoObject) { console.warn('Unable to find topology object in TopoJson'); return; } state.cartogram.projection(state.projection).value(valueOf); var features = state.svg.selectAll('path.feature').data(state.cartogram.iterations(1) // Initialize new features non-distorted (state.topoJson, topoObject.geometries).features); features.exit().remove(); var newFeatures = features.enter().append('path').attr('class', 'feature').style('fill', 'lightgrey').attr('d', state.cartogram.path).on('mouseover', function (ev, feature) { var valueOf = accessorFn(state.value); var labelOf = accessorFn(state.label); var tooltipContentOf = accessorFn(state.tooltipContent); var label = labelOf(feature); var extraContent = tooltipContentOf(feature); state.tooltip.content(!label && !extraContent ? null : "\n ".concat(label ? "<b>".concat(label, "</b>:") : '', "\n ").concat(state.valFormatter(valueOf(feature)), "\n ").concat(state.units, "\n ").concat(extraContent ? "<br/><br/>".concat(extraContent) : '', "\n ")); }).on('mouseout', function () { state.tooltip.content(null); }).on('click', function (ev, d) { return state.onClick && state.onClick(d); }); features.merge(newFeatures).data(state.cartogram.iterations(state.iterations) // distort all features (state.topoJson, topoObject.geometries).features).style('cursor', state.onClick ? 'pointer' : null).transition().duration(ANIMATION_DURATION).style('fill', colorOf).attr('d', state.cartogram.path); } }); function styleInject(css, ref) { if (ref === undefined) ref = {}; var insertAt = ref.insertAt; if (typeof document === 'undefined') { return; } var head = document.head || document.getElementsByTagName('head')[0]; var style = document.createElement('style'); style.type = 'text/css'; if (insertAt === 'top') { if (head.firstChild) { head.insertBefore(style, head.firstChild); } else { head.appendChild(style); } } else { head.appendChild(style); } if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); } } var css_248z = ".cartogram .feature {\n stroke: darkgrey;\n transition: fill-opacity .7s;\n}\n\n.cartogram .feature:hover {\n fill-opacity: 0.6;\n transition: fill-opacity .1s;\n}\n\n.cartogram {\n position: relative;\n}"; styleInject(css_248z); export { cartogram as default };