@simspace/nivo-circle-packing
Version:
[](https://www.npmjs.com/package/@nivo/circle-packing)
1,245 lines (1,167 loc) • 45.9 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('@simspace/nivo-core'), require('d3-hierarchy'), require('lodash/cloneDeep'), require('lodash/sortBy'), require('@simspace/nivo-colors'), require('@simspace/nivo-tooltip'), require('react/jsx-runtime'), require('@react-spring/web')) :
typeof define === 'function' && define.amd ? define(['exports', 'react', '@simspace/nivo-core', 'd3-hierarchy', 'lodash/cloneDeep', 'lodash/sortBy', '@simspace/nivo-colors', '@simspace/nivo-tooltip', 'react/jsx-runtime', '@react-spring/web'], factory) :
(global = global || self, factory(global.nivo = global.nivo || {}, global.React, global['@simspace/nivo-core'], global.d3, global['lodash/cloneDeep'], global['lodash/sortBy'], global['@simspace/nivo-colors'], global['@simspace/nivo-tooltip'], global['react/jsx-runtime'], global['@react-spring/web']));
}(this, (function (exports, React, nivoCore, d3Hierarchy, cloneDeep, sortBy, nivoColors, nivoTooltip, jsxRuntime, web) { 'use strict';
cloneDeep = cloneDeep && Object.prototype.hasOwnProperty.call(cloneDeep, 'default') ? cloneDeep['default'] : cloneDeep;
sortBy = sortBy && Object.prototype.hasOwnProperty.call(sortBy, 'default') ? sortBy['default'] : sortBy;
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function ownKeys(object, enumerableOnly) {
var keys = Object.keys(object);
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(object);
if (enumerableOnly) symbols = symbols.filter(function (sym) {
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
});
keys.push.apply(keys, symbols);
}
return keys;
}
function _objectSpread2(target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i] != null ? arguments[i] : {};
if (i % 2) {
ownKeys(Object(source), true).forEach(function (key) {
_defineProperty(target, key, source[key]);
});
} else if (Object.getOwnPropertyDescriptors) {
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
} else {
ownKeys(Object(source)).forEach(function (key) {
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
});
}
}
return target;
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
function _objectWithoutProperties(source, excluded) {
if (source == null) return {};
var target = _objectWithoutPropertiesLoose(source, excluded);
var key, i;
if (Object.getOwnPropertySymbols) {
var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
for (i = 0; i < sourceSymbolKeys.length; i++) {
key = sourceSymbolKeys[i];
if (excluded.indexOf(key) >= 0) continue;
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
target[key] = source[key];
}
}
return target;
}
function _arrayWithHoles(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterableToArrayLimit(arr, i) {
if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
function _arrayLikeToArray(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for (var i = 0, arr2 = new Array(len); i < len; i++) {
arr2[i] = arr[i];
}
return arr2;
}
function _unsupportedIterableToArray(o, minLen) {
if (!o) return;
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(o);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}
function _nonIterableRest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _slicedToArray(arr, i) {
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
}
function _arrayWithoutHoles(arr) {
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
}
function _iterableToArray(iter) {
if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _toConsumableArray(arr) {
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
}
var useCirclePacking = function useCirclePacking(_ref) {
var _hierarchy$value;
var data = _ref.data,
id = _ref.id,
value = _ref.value,
valueFormat = _ref.valueFormat,
width = _ref.width,
height = _ref.height,
padding = _ref.padding,
leavesOnly = _ref.leavesOnly,
colors = _ref.colors,
colorBy = _ref.colorBy,
inheritColorFromParent = _ref.inheritColorFromParent,
childColor = _ref.childColor;
var getId = nivoCore.usePropertyAccessor(id);
var getValue = nivoCore.usePropertyAccessor(value);
var formatValue = nivoCore.useValueFormatter(valueFormat);
var getColor = nivoColors.useOrdinalColorScale(colors, colorBy);
var theme = nivoCore.useTheme();
var getChildColor = nivoColors.useInheritedColor(childColor, theme);
var clonedData = cloneDeep(data);
var hierarchy = d3Hierarchy.hierarchy(clonedData).sum(getValue);
var pack = d3Hierarchy.pack().size([width, height]).padding(padding);
var packedData = pack(hierarchy);
var nodes = leavesOnly ? packedData.leaves() : packedData.descendants();
var sortedNodes = sortBy(nodes, 'depth');
var total = (_hierarchy$value = hierarchy.value) !== null && _hierarchy$value !== void 0 ? _hierarchy$value : 0;
var computedNodes = sortedNodes.reduce(function (acc, descendant) {
var id = getId(descendant.data);
var value = descendant.value;
var percentage = 100 * value / total;
var path = descendant.ancestors().map(function (ancestor) {
return getId(ancestor.data);
});
var parent;
if (descendant.parent) {
parent = acc.find(function (node) {
return node.id === getId(descendant.parent.data);
});
}
var normalizedNode = {
id: id,
path: path,
value: value,
percentage: percentage,
formattedValue: valueFormat ? formatValue(value) : "".concat(percentage.toFixed(2), "%"),
x: descendant.x,
y: descendant.y,
radius: descendant.r,
color: '',
data: descendant.data,
depth: descendant.depth,
height: descendant.height
};
if (inheritColorFromParent && parent && normalizedNode.depth > 1) {
normalizedNode.color = getChildColor(parent);
} else {
normalizedNode.color = getColor(normalizedNode);
}
return [].concat(_toConsumableArray(acc), [normalizedNode]);
}, []);
return computedNodes;
};
var useCirclePackingZoom = function useCirclePackingZoom(nodes, zoomedId, width, height) {
return React.useMemo(function () {
if (!zoomedId) return nodes;
var zoomedNode = nodes.find(function (_ref2) {
var id = _ref2.id;
return id === zoomedId;
});
if (!zoomedNode) return nodes;
var ratio = Math.min(width, height) / (zoomedNode.radius * 2);
var offsetX = width / 2 - zoomedNode.x * ratio;
var offsetY = height / 2 - zoomedNode.y * ratio;
return nodes.map(function (node) {
return _objectSpread2(_objectSpread2({}, node), {}, {
x: node.x * ratio + offsetX,
y: node.y * ratio + offsetY,
radius: node.radius * ratio
});
});
}, [nodes, zoomedId, width, height]);
};
var useCirclePackingLabels = function useCirclePackingLabels(_ref3) {
var nodes = _ref3.nodes,
label = _ref3.label,
filter = _ref3.filter,
skipRadius = _ref3.skipRadius,
textColor = _ref3.textColor;
var getLabel = nivoCore.usePropertyAccessor(label);
var theme = nivoCore.useTheme();
var getTextColor = nivoColors.useInheritedColor(textColor, theme);
var labels = React.useMemo(function () {
return nodes.filter(function (node) {
return node.radius >= skipRadius;
}).map(function (node) {
return {
label: getLabel(node),
textColor: getTextColor(node),
node: node
};
});
}, [nodes, skipRadius, getLabel, getTextColor]);
return React.useMemo(function () {
if (!filter) return labels;
return labels.filter(filter);
}, [labels, filter]);
};
var useNodeMouseHandlers = function useNodeMouseHandlers(node, _ref4) {
var onMouseEnter = _ref4.onMouseEnter,
onMouseMove = _ref4.onMouseMove,
onMouseLeave = _ref4.onMouseLeave,
onClick = _ref4.onClick;
return React.useMemo(function () {
return {
onMouseEnter: onMouseEnter ? function (event) {
onMouseEnter(node, event);
} : undefined,
onMouseMove: onMouseMove ? function (event) {
onMouseMove(node, event);
} : undefined,
onMouseLeave: onMouseLeave ? function (event) {
onMouseLeave(node, event);
} : undefined,
onClick: onClick ? function (event) {
onClick(node, event);
} : undefined
};
}, [node, onMouseEnter, onMouseMove, onMouseLeave, onClick]);
};
var useMouseCircleDetection = function useMouseCircleDetection(_ref5) {
var nodes = _ref5.nodes,
canvasEl = _ref5.canvasEl,
margin = _ref5.margin;
var sortedNodes = React.useMemo(function () {
return sortBy(nodes, 'height');
}, [nodes]);
return React.useCallback(function (event) {
if (!canvasEl.current) return null;
var _getRelativeCursor = nivoCore.getRelativeCursor(canvasEl.current, event),
_getRelativeCursor2 = _slicedToArray(_getRelativeCursor, 2),
x = _getRelativeCursor2[0],
y = _getRelativeCursor2[1];
return sortedNodes.find(function (node) {
var distanceFromNode = nivoCore.getDistance(node.x, node.y, x - margin.left, y - margin.top);
return distanceFromNode <= node.radius;
});
}, [canvasEl, margin, sortedNodes]);
};
var useCirclePackingLayerContext = function useCirclePackingLayerContext(_ref6) {
var nodes = _ref6.nodes;
return React.useMemo(function () {
return {
nodes: nodes
};
}, [nodes]);
};
var CirclePackingTooltip = function CirclePackingTooltip(_ref) {
var id = _ref.id,
formattedValue = _ref.formattedValue,
color = _ref.color;
return jsxRuntime.jsx(nivoTooltip.BasicTooltip, {
id: id,
value: formattedValue,
enableChip: true,
color: color
});
};
var _window$devicePixelRa;
var defaultProps = {
id: 'id',
value: 'value',
padding: 0,
leavesOnly: false,
layers: ['circles', 'labels'],
colors: {
scheme: 'nivo'
},
colorBy: 'depth',
inheritColorFromParent: false,
childColor: {
from: 'color',
modifiers: [['darker', 0.3]]
},
borderWidth: 0,
borderColor: {
from: 'color',
modifiers: [['darker', 0.3]]
},
defs: [],
fill: [],
enableLabels: false,
label: 'id',
labelTextColor: {
from: 'color',
modifiers: [['darker', 1.6]]
},
labelsSkipRadius: 8,
isInteractive: true,
tooltip: CirclePackingTooltip,
animate: true,
motionConfig: 'gentle',
role: 'img',
pixelRatio: typeof window !== 'undefined' ? (_window$devicePixelRa = window.devicePixelRatio) !== null && _window$devicePixelRa !== void 0 ? _window$devicePixelRa : 1 : 1
};
var interpolateRadius = function interpolateRadius(radiusValue) {
return web.to([radiusValue], function (radius) {
return Math.max(0, radius);
});
};
var getTransitionPhases = function getTransitionPhases(getBorderColor) {
return {
enter: function enter(node) {
return {
x: node.x,
y: node.y,
radius: 0,
color: node.color,
borderColor: getBorderColor(node),
opacity: 0
};
},
update: function update(node) {
return {
x: node.x,
y: node.y,
radius: node.radius,
color: node.color,
borderColor: getBorderColor(node),
opacity: 1
};
},
leave: function leave(node) {
return {
x: node.x,
y: node.y,
radius: 0,
color: node.color,
borderColor: getBorderColor(node),
opacity: 0
};
}
};
};
var Circles = function Circles(_ref) {
var nodes = _ref.nodes,
borderWidth = _ref.borderWidth,
borderColor = _ref.borderColor,
component = _ref.component,
isInteractive = _ref.isInteractive,
onMouseEnter = _ref.onMouseEnter,
onMouseMove = _ref.onMouseMove,
onMouseLeave = _ref.onMouseLeave,
onClick = _ref.onClick,
tooltip = _ref.tooltip;
var _useTooltip = nivoTooltip.useTooltip(),
showTooltipFromEvent = _useTooltip.showTooltipFromEvent,
hideTooltip = _useTooltip.hideTooltip;
var handleMouseEnter = React.useMemo(function () {
if (!isInteractive) return undefined;
return function (node, event) {
showTooltipFromEvent(React.createElement(tooltip, node), event);
onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(node, event);
};
}, [isInteractive, showTooltipFromEvent, tooltip, onMouseEnter]);
var handleMouseMove = React.useMemo(function () {
if (!isInteractive) return undefined;
return function (node, event) {
showTooltipFromEvent(React.createElement(tooltip, node), event);
onMouseMove === null || onMouseMove === void 0 ? void 0 : onMouseMove(node, event);
};
}, [isInteractive, showTooltipFromEvent, tooltip, onMouseMove]);
var handleMouseLeave = React.useMemo(function () {
if (!isInteractive) return undefined;
return function (node, event) {
hideTooltip();
onMouseLeave === null || onMouseLeave === void 0 ? void 0 : onMouseLeave(node, event);
};
}, [isInteractive, hideTooltip, onMouseLeave]);
var handleClick = React.useMemo(function () {
if (!isInteractive) return undefined;
return function (node, event) {
onClick === null || onClick === void 0 ? void 0 : onClick(node, event);
};
}, [isInteractive, onClick]);
var _useMotionConfig = nivoCore.useMotionConfig(),
animate = _useMotionConfig.animate,
springConfig = _useMotionConfig.config;
var theme = nivoCore.useTheme();
var getBorderColor = nivoColors.useInheritedColor(borderColor, theme);
var transitionPhases = React.useMemo(function () {
return getTransitionPhases(getBorderColor);
}, [getBorderColor]);
var transition = web.useTransition(nodes, {
keys: function keys(node) {
return node.id;
},
initial: transitionPhases.update,
from: transitionPhases.enter,
enter: transitionPhases.update,
update: transitionPhases.update,
leave: transitionPhases.leave,
config: springConfig,
immediate: !animate
});
return jsxRuntime.jsx(jsxRuntime.Fragment, {
children: transition(function (transitionProps, node) {
return React.createElement(component, {
key: node.id,
node: node,
style: _objectSpread2(_objectSpread2({}, transitionProps), {}, {
radius: interpolateRadius(transitionProps.radius),
borderWidth: borderWidth
}),
onMouseEnter: handleMouseEnter,
onMouseMove: handleMouseMove,
onMouseLeave: handleMouseLeave,
onClick: handleClick
});
})
});
};
var CircleSvg = function CircleSvg(_ref) {
var node = _ref.node,
style = _ref.style,
onMouseEnter = _ref.onMouseEnter,
onMouseMove = _ref.onMouseMove,
onMouseLeave = _ref.onMouseLeave,
onClick = _ref.onClick;
var handlers = useNodeMouseHandlers(node, {
onMouseEnter: onMouseEnter,
onMouseMove: onMouseMove,
onMouseLeave: onMouseLeave,
onClick: onClick
});
return jsxRuntime.jsx(web.animated.circle, {
cx: style.x,
cy: style.y,
r: style.radius,
fill: node.fill || style.color,
stroke: style.borderColor,
strokeWidth: style.borderWidth,
opacity: style.opacity,
onMouseEnter: handlers.onMouseEnter,
onMouseMove: handlers.onMouseMove,
onMouseLeave: handlers.onMouseLeave,
onClick: handlers.onClick
}, node.id);
};
var getTransitionPhases$1 = function getTransitionPhases() {
return {
enter: function enter(label) {
return {
x: label.node.x,
y: label.node.y,
radius: label.node.radius,
textColor: label.textColor,
opacity: 0
};
},
update: function update(label) {
return {
x: label.node.x,
y: label.node.y,
radius: label.node.radius,
textColor: label.textColor,
opacity: 1
};
},
leave: function leave(label) {
return {
x: label.node.x,
y: label.node.y,
radius: label.node.radius,
textColor: label.textColor,
opacity: 0
};
}
};
};
var Labels = function Labels(_ref) {
var nodes = _ref.nodes,
label = _ref.label,
filter = _ref.filter,
skipRadius = _ref.skipRadius,
textColor = _ref.textColor,
component = _ref.component;
var _useMotionConfig = nivoCore.useMotionConfig(),
animate = _useMotionConfig.animate,
springConfig = _useMotionConfig.config;
var labels = useCirclePackingLabels({
nodes: nodes,
label: label,
filter: filter,
skipRadius: skipRadius,
textColor: textColor
});
var transitionPhases = React.useMemo(function () {
return getTransitionPhases$1();
}, []);
var transition = web.useTransition(labels, {
keys: function keys(label) {
return label.node.id;
},
initial: transitionPhases.update,
from: transitionPhases.enter,
enter: transitionPhases.update,
update: transitionPhases.update,
leave: transitionPhases.leave,
config: springConfig,
immediate: !animate
});
return jsxRuntime.jsx(jsxRuntime.Fragment, {
children: transition(function (transitionProps, label) {
return React.createElement(component, {
key: label.node.id,
label: label.label,
style: _objectSpread2(_objectSpread2({}, transitionProps), {}, {
radius: interpolateRadius(transitionProps.radius)
}),
node: label.node
});
})
});
};
var LabelSvg = function LabelSvg(_ref) {
var node = _ref.node,
label = _ref.label,
style = _ref.style;
var theme = nivoCore.useTheme();
return jsxRuntime.jsx(web.animated.text, {
x: style.x,
y: style.y,
textAnchor: "middle",
dominantBaseline: "central",
style: _objectSpread2(_objectSpread2({}, theme.labels.text), {}, {
fill: style.textColor,
opacity: style.opacity,
pointerEvents: 'none'
}),
children: label
}, node.id);
};
var InnerCirclePacking = function InnerCirclePacking(_ref) {
var data = _ref.data,
_ref$id = _ref.id,
id = _ref$id === void 0 ? defaultProps.id : _ref$id,
_ref$value = _ref.value,
value = _ref$value === void 0 ? defaultProps.value : _ref$value,
valueFormat = _ref.valueFormat,
width = _ref.width,
height = _ref.height,
partialMargin = _ref.margin,
_ref$padding = _ref.padding,
padding = _ref$padding === void 0 ? defaultProps.padding : _ref$padding,
_ref$leavesOnly = _ref.leavesOnly,
leavesOnly = _ref$leavesOnly === void 0 ? defaultProps.leavesOnly : _ref$leavesOnly,
_ref$colors = _ref.colors,
colors = _ref$colors === void 0 ? defaultProps.colors : _ref$colors,
_ref$colorBy = _ref.colorBy,
colorBy = _ref$colorBy === void 0 ? defaultProps.colorBy : _ref$colorBy,
_ref$inheritColorFrom = _ref.inheritColorFromParent,
inheritColorFromParent = _ref$inheritColorFrom === void 0 ? defaultProps.inheritColorFromParent : _ref$inheritColorFrom,
_ref$childColor = _ref.childColor,
childColor = _ref$childColor === void 0 ? defaultProps.childColor : _ref$childColor,
_ref$borderWidth = _ref.borderWidth,
borderWidth = _ref$borderWidth === void 0 ? defaultProps.borderWidth : _ref$borderWidth,
_ref$borderColor = _ref.borderColor,
borderColor = _ref$borderColor === void 0 ? defaultProps.borderColor : _ref$borderColor,
_ref$circleComponent = _ref.circleComponent,
circleComponent = _ref$circleComponent === void 0 ? CircleSvg : _ref$circleComponent,
_ref$defs = _ref.defs,
defs = _ref$defs === void 0 ? defaultProps.defs : _ref$defs,
_ref$fill = _ref.fill,
fill = _ref$fill === void 0 ? defaultProps.fill : _ref$fill,
_ref$enableLabels = _ref.enableLabels,
enableLabels = _ref$enableLabels === void 0 ? defaultProps.enableLabels : _ref$enableLabels,
_ref$label = _ref.label,
label = _ref$label === void 0 ? defaultProps.label : _ref$label,
labelsFilter = _ref.labelsFilter,
_ref$labelsSkipRadius = _ref.labelsSkipRadius,
labelsSkipRadius = _ref$labelsSkipRadius === void 0 ? defaultProps.labelsSkipRadius : _ref$labelsSkipRadius,
_ref$labelTextColor = _ref.labelTextColor,
labelTextColor = _ref$labelTextColor === void 0 ? defaultProps.labelTextColor : _ref$labelTextColor,
_ref$labelComponent = _ref.labelComponent,
labelComponent = _ref$labelComponent === void 0 ? LabelSvg : _ref$labelComponent,
_ref$layers = _ref.layers,
layers = _ref$layers === void 0 ? defaultProps.layers : _ref$layers,
isInteractive = _ref.isInteractive,
onMouseEnter = _ref.onMouseEnter,
onMouseMove = _ref.onMouseMove,
onMouseLeave = _ref.onMouseLeave,
onClick = _ref.onClick,
_ref$tooltip = _ref.tooltip,
tooltip = _ref$tooltip === void 0 ? defaultProps.tooltip : _ref$tooltip,
zoomedId = _ref.zoomedId,
_ref$role = _ref.role,
role = _ref$role === void 0 ? defaultProps.role : _ref$role;
var _useDimensions = nivoCore.useDimensions(width, height, partialMargin),
outerWidth = _useDimensions.outerWidth,
outerHeight = _useDimensions.outerHeight,
margin = _useDimensions.margin,
innerWidth = _useDimensions.innerWidth,
innerHeight = _useDimensions.innerHeight;
var nodes = useCirclePacking({
data: data,
id: id,
value: value,
valueFormat: valueFormat,
width: innerWidth,
height: innerHeight,
padding: padding,
leavesOnly: leavesOnly,
colors: colors,
colorBy: colorBy,
inheritColorFromParent: inheritColorFromParent,
childColor: childColor
});
var zoomedNodes = useCirclePackingZoom(nodes, zoomedId, innerWidth, innerHeight);
var boundDefs = React.useMemo(function () {
return nivoCore.bindDefs(defs, zoomedNodes, fill, {
targetKey: 'fill'
});
}, [defs, zoomedNodes, fill]);
var layerById = {
circles: null,
labels: null
};
if (layers.includes('circles')) {
layerById.circles = jsxRuntime.jsx(Circles, {
nodes: zoomedNodes,
borderWidth: borderWidth,
borderColor: borderColor,
isInteractive: isInteractive,
onMouseEnter: onMouseEnter,
onMouseMove: onMouseMove,
onMouseLeave: onMouseLeave,
onClick: onClick,
component: circleComponent,
tooltip: tooltip
}, "circles");
}
if (enableLabels && layers.includes('labels')) {
layerById.labels = jsxRuntime.jsx(Labels, {
nodes: zoomedNodes,
label: label,
filter: labelsFilter,
skipRadius: labelsSkipRadius,
textColor: labelTextColor,
component: labelComponent
}, "labels");
}
var layerContext = useCirclePackingLayerContext({
nodes: nodes
});
return jsxRuntime.jsx(nivoCore.SvgWrapper, {
width: outerWidth,
height: outerHeight,
margin: margin,
defs: boundDefs,
role: role,
children: layers.map(function (layer, i) {
if (layerById[layer] !== undefined) {
return layerById[layer];
}
if (typeof layer === 'function') {
return jsxRuntime.jsx(React.Fragment, {
children: React.createElement(layer, layerContext)
}, i);
}
return null;
})
});
};
var CirclePacking = function CirclePacking(_ref2) {
var theme = _ref2.theme,
_ref2$isInteractive = _ref2.isInteractive,
isInteractive = _ref2$isInteractive === void 0 ? defaultProps.isInteractive : _ref2$isInteractive,
_ref2$animate = _ref2.animate,
animate = _ref2$animate === void 0 ? defaultProps.animate : _ref2$animate,
_ref2$motionConfig = _ref2.motionConfig,
motionConfig = _ref2$motionConfig === void 0 ? defaultProps.motionConfig : _ref2$motionConfig,
otherProps = _objectWithoutProperties(_ref2, ["theme", "isInteractive", "animate", "motionConfig"]);
return jsxRuntime.jsx(nivoCore.Container, {
isInteractive: isInteractive,
animate: animate,
motionConfig: motionConfig,
theme: theme,
children: jsxRuntime.jsx(InnerCirclePacking, _objectSpread2({
isInteractive: isInteractive
}, otherProps))
});
};
var ResponsiveCirclePacking = function ResponsiveCirclePacking(props) {
return jsxRuntime.jsx(nivoCore.ResponsiveWrapper, {
children: function children(_ref) {
var width = _ref.width,
height = _ref.height;
return jsxRuntime.jsx(CirclePacking, _objectSpread2({
width: width,
height: height
}, props));
}
});
};
var interpolatePosition = function interpolatePosition(positionValue, radiusValue) {
return web.to([positionValue, radiusValue], function (position, radius) {
return position - radius;
});
};
var interpolateSize = function interpolateSize(radiusValue) {
return web.to([radiusValue], function (radius) {
return radius * 2;
});
};
var interpolateBorderWidth = function interpolateBorderWidth(borderWidth, radiusValue) {
return web.to([radiusValue], function (radius) {
return Math.min(borderWidth, radius);
});
};
var CircleHtml = function CircleHtml(_ref) {
var node = _ref.node,
style = _ref.style,
onMouseEnter = _ref.onMouseEnter,
onMouseMove = _ref.onMouseMove,
onMouseLeave = _ref.onMouseLeave,
onClick = _ref.onClick;
var size = interpolateSize(style.radius);
var handlers = useNodeMouseHandlers(node, {
onMouseEnter: onMouseEnter,
onMouseMove: onMouseMove,
onMouseLeave: onMouseLeave,
onClick: onClick
});
return jsxRuntime.jsx(web.animated.div, {
style: {
position: 'absolute',
top: interpolatePosition(style.y, style.radius),
left: interpolatePosition(style.x, style.radius),
height: size,
width: size,
borderRadius: style.radius,
backgroundColor: style.color,
borderWidth: interpolateBorderWidth(style.borderWidth, style.radius),
borderStyle: 'solid',
borderColor: style.borderColor,
boxSizing: 'border-box'
},
onMouseEnter: handlers.onMouseEnter,
onMouseMove: handlers.onMouseMove,
onMouseLeave: handlers.onMouseLeave,
onClick: handlers.onClick
});
};
var LabelHtml = function LabelHtml(_ref) {
var node = _ref.node,
label = _ref.label,
style = _ref.style;
var theme = nivoCore.useTheme();
var size = interpolateSize(style.radius);
return jsxRuntime.jsx(web.animated.div, {
style: _objectSpread2(_objectSpread2({}, theme.labels.text), {}, {
position: 'absolute',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
top: interpolatePosition(style.y, style.radius),
left: interpolatePosition(style.x, style.radius),
width: size,
height: size,
color: style.textColor,
opacity: style.opacity,
pointerEvents: 'none'
}),
children: label
}, node.id);
};
var InnerCirclePackingHtml = function InnerCirclePackingHtml(_ref) {
var data = _ref.data,
_ref$id = _ref.id,
id = _ref$id === void 0 ? defaultProps.id : _ref$id,
_ref$value = _ref.value,
value = _ref$value === void 0 ? defaultProps.value : _ref$value,
valueFormat = _ref.valueFormat,
width = _ref.width,
height = _ref.height,
partialMargin = _ref.margin,
_ref$padding = _ref.padding,
padding = _ref$padding === void 0 ? defaultProps.padding : _ref$padding,
_ref$leavesOnly = _ref.leavesOnly,
leavesOnly = _ref$leavesOnly === void 0 ? defaultProps.leavesOnly : _ref$leavesOnly,
_ref$colors = _ref.colors,
colors = _ref$colors === void 0 ? defaultProps.colors : _ref$colors,
_ref$colorBy = _ref.colorBy,
colorBy = _ref$colorBy === void 0 ? defaultProps.colorBy : _ref$colorBy,
_ref$inheritColorFrom = _ref.inheritColorFromParent,
inheritColorFromParent = _ref$inheritColorFrom === void 0 ? defaultProps.inheritColorFromParent : _ref$inheritColorFrom,
_ref$childColor = _ref.childColor,
childColor = _ref$childColor === void 0 ? defaultProps.childColor : _ref$childColor,
_ref$borderWidth = _ref.borderWidth,
borderWidth = _ref$borderWidth === void 0 ? defaultProps.borderWidth : _ref$borderWidth,
_ref$borderColor = _ref.borderColor,
borderColor = _ref$borderColor === void 0 ? defaultProps.borderColor : _ref$borderColor,
_ref$circleComponent = _ref.circleComponent,
circleComponent = _ref$circleComponent === void 0 ? CircleHtml : _ref$circleComponent,
_ref$enableLabels = _ref.enableLabels,
enableLabels = _ref$enableLabels === void 0 ? defaultProps.enableLabels : _ref$enableLabels,
_ref$label = _ref.label,
label = _ref$label === void 0 ? defaultProps.label : _ref$label,
labelsFilter = _ref.labelsFilter,
_ref$labelsSkipRadius = _ref.labelsSkipRadius,
labelsSkipRadius = _ref$labelsSkipRadius === void 0 ? defaultProps.labelsSkipRadius : _ref$labelsSkipRadius,
_ref$labelTextColor = _ref.labelTextColor,
labelTextColor = _ref$labelTextColor === void 0 ? defaultProps.labelTextColor : _ref$labelTextColor,
_ref$labelComponent = _ref.labelComponent,
labelComponent = _ref$labelComponent === void 0 ? LabelHtml : _ref$labelComponent,
_ref$layers = _ref.layers,
layers = _ref$layers === void 0 ? defaultProps.layers : _ref$layers,
isInteractive = _ref.isInteractive,
onMouseEnter = _ref.onMouseEnter,
onMouseMove = _ref.onMouseMove,
onMouseLeave = _ref.onMouseLeave,
onClick = _ref.onClick,
_ref$tooltip = _ref.tooltip,
tooltip = _ref$tooltip === void 0 ? defaultProps.tooltip : _ref$tooltip,
zoomedId = _ref.zoomedId,
_ref$role = _ref.role,
role = _ref$role === void 0 ? defaultProps.role : _ref$role;
var _useDimensions = nivoCore.useDimensions(width, height, partialMargin),
outerWidth = _useDimensions.outerWidth,
outerHeight = _useDimensions.outerHeight,
margin = _useDimensions.margin,
innerWidth = _useDimensions.innerWidth,
innerHeight = _useDimensions.innerHeight;
var nodes = useCirclePacking({
data: data,
id: id,
value: value,
valueFormat: valueFormat,
width: innerWidth,
height: innerHeight,
padding: padding,
leavesOnly: leavesOnly,
colors: colors,
colorBy: colorBy,
inheritColorFromParent: inheritColorFromParent,
childColor: childColor
});
var zoomedNodes = useCirclePackingZoom(nodes, zoomedId, innerWidth, innerHeight);
var layerById = {
circles: null,
labels: null
};
if (layers.includes('circles')) {
layerById.circles = jsxRuntime.jsx(Circles, {
nodes: zoomedNodes,
borderWidth: borderWidth,
borderColor: borderColor,
isInteractive: isInteractive,
onMouseEnter: onMouseEnter,
onMouseMove: onMouseMove,
onMouseLeave: onMouseLeave,
onClick: onClick,
component: circleComponent,
tooltip: tooltip
}, "circles");
}
if (enableLabels && layers.includes('labels')) {
layerById.labels = jsxRuntime.jsx(Labels, {
nodes: zoomedNodes,
label: label,
filter: labelsFilter,
skipRadius: labelsSkipRadius,
textColor: labelTextColor,
component: labelComponent
}, "labels");
}
var layerContext = useCirclePackingLayerContext({
nodes: nodes
});
return jsxRuntime.jsx("div", {
role: role,
style: {
position: 'relative',
overflow: 'hidden',
width: outerWidth,
height: outerHeight
},
children: jsxRuntime.jsx("div", {
style: {
position: 'absolute',
top: margin.top,
left: margin.left
},
children: layers.map(function (layer, i) {
if (layerById[layer] !== undefined) {
return layerById[layer];
}
if (typeof layer === 'function') {
return jsxRuntime.jsx(React.Fragment, {
children: React.createElement(layer, layerContext)
}, i);
}
return null;
})
})
});
};
var CirclePackingHtml = function CirclePackingHtml(_ref2) {
var theme = _ref2.theme,
_ref2$isInteractive = _ref2.isInteractive,
isInteractive = _ref2$isInteractive === void 0 ? defaultProps.isInteractive : _ref2$isInteractive,
_ref2$animate = _ref2.animate,
animate = _ref2$animate === void 0 ? defaultProps.animate : _ref2$animate,
_ref2$motionConfig = _ref2.motionConfig,
motionConfig = _ref2$motionConfig === void 0 ? defaultProps.motionConfig : _ref2$motionConfig,
otherProps = _objectWithoutProperties(_ref2, ["theme", "isInteractive", "animate", "motionConfig"]);
return jsxRuntime.jsx(nivoCore.Container, {
isInteractive: isInteractive,
animate: animate,
motionConfig: motionConfig,
theme: theme,
children: jsxRuntime.jsx(InnerCirclePackingHtml, _objectSpread2({
isInteractive: isInteractive
}, otherProps))
});
};
var ResponsiveCirclePackingHtml = function ResponsiveCirclePackingHtml(props) {
return jsxRuntime.jsx(nivoCore.ResponsiveWrapper, {
children: function children(_ref) {
var width = _ref.width,
height = _ref.height;
return jsxRuntime.jsx(CirclePackingHtml, _objectSpread2({
width: width,
height: height
}, props));
}
});
};
var InnerCirclePackingCanvas = function InnerCirclePackingCanvas(_ref) {
var data = _ref.data,
_ref$id = _ref.id,
id = _ref$id === void 0 ? defaultProps.id : _ref$id,
_ref$value = _ref.value,
value = _ref$value === void 0 ? defaultProps.value : _ref$value,
valueFormat = _ref.valueFormat,
width = _ref.width,
height = _ref.height,
partialMargin = _ref.margin,
_ref$padding = _ref.padding,
padding = _ref$padding === void 0 ? defaultProps.padding : _ref$padding,
_ref$leavesOnly = _ref.leavesOnly,
leavesOnly = _ref$leavesOnly === void 0 ? defaultProps.leavesOnly : _ref$leavesOnly,
_ref$colors = _ref.colors,
colors = _ref$colors === void 0 ? defaultProps.colors : _ref$colors,
_ref$colorBy = _ref.colorBy,
colorBy = _ref$colorBy === void 0 ? defaultProps.colorBy : _ref$colorBy,
_ref$inheritColorFrom = _ref.inheritColorFromParent,
inheritColorFromParent = _ref$inheritColorFrom === void 0 ? defaultProps.inheritColorFromParent : _ref$inheritColorFrom,
_ref$childColor = _ref.childColor,
childColor = _ref$childColor === void 0 ? defaultProps.childColor : _ref$childColor,
_ref$borderWidth = _ref.borderWidth,
borderWidth = _ref$borderWidth === void 0 ? defaultProps.borderWidth : _ref$borderWidth,
_ref$borderColor = _ref.borderColor,
borderColor = _ref$borderColor === void 0 ? defaultProps.borderColor : _ref$borderColor,
_ref$enableLabels = _ref.enableLabels,
enableLabels = _ref$enableLabels === void 0 ? defaultProps.enableLabels : _ref$enableLabels,
_ref$label = _ref.label,
label = _ref$label === void 0 ? defaultProps.label : _ref$label,
labelsFilter = _ref.labelsFilter,
_ref$labelsSkipRadius = _ref.labelsSkipRadius,
labelsSkipRadius = _ref$labelsSkipRadius === void 0 ? defaultProps.labelsSkipRadius : _ref$labelsSkipRadius,
_ref$labelTextColor = _ref.labelTextColor,
labelTextColor = _ref$labelTextColor === void 0 ? defaultProps.labelTextColor : _ref$labelTextColor,
isInteractive = _ref.isInteractive,
onMouseMove = _ref.onMouseMove,
onClick = _ref.onClick,
_ref$tooltip = _ref.tooltip,
tooltip = _ref$tooltip === void 0 ? defaultProps.tooltip : _ref$tooltip,
zoomedId = _ref.zoomedId,
_ref$role = _ref.role,
role = _ref$role === void 0 ? defaultProps.role : _ref$role,
_ref$pixelRatio = _ref.pixelRatio,
pixelRatio = _ref$pixelRatio === void 0 ? defaultProps.pixelRatio : _ref$pixelRatio;
var canvasEl = React.useRef(null);
var theme = nivoCore.useTheme();
var _useDimensions = nivoCore.useDimensions(width, height, partialMargin),
margin = _useDimensions.margin,
innerWidth = _useDimensions.innerWidth,
innerHeight = _useDimensions.innerHeight,
outerWidth = _useDimensions.outerWidth,
outerHeight = _useDimensions.outerHeight;
var nodes = useCirclePacking({
data: data,
id: id,
value: value,
valueFormat: valueFormat,
width: innerWidth,
height: innerHeight,
padding: padding,
leavesOnly: leavesOnly,
colors: colors,
colorBy: colorBy,
inheritColorFromParent: inheritColorFromParent,
childColor: childColor
});
var zoomedNodes = useCirclePackingZoom(nodes, zoomedId, innerWidth, innerHeight);
var labels = useCirclePackingLabels({
nodes: zoomedNodes,
label: label,
filter: labelsFilter,
skipRadius: labelsSkipRadius,
textColor: labelTextColor
});
var getBorderColor = nivoColors.useInheritedColor(borderColor, theme);
React.useEffect(function () {
if (!canvasEl.current) return;
canvasEl.current.width = outerWidth * pixelRatio;
canvasEl.current.height = outerHeight * pixelRatio;
var ctx = canvasEl.current.getContext('2d');
ctx.scale(pixelRatio, pixelRatio);
ctx.fillStyle = theme.background;
ctx.fillRect(0, 0, outerWidth, outerHeight);
ctx.save();
ctx.translate(margin.left, margin.top);
zoomedNodes.forEach(function (node) {
if (borderWidth > 0) {
ctx.strokeStyle = getBorderColor(node);
ctx.lineWidth = borderWidth;
}
ctx.beginPath();
ctx.arc(node.x, node.y, node.radius, 0, 2 * Math.PI);
ctx.fillStyle = node.color;
ctx.fill();
if (borderWidth > 0) {
ctx.stroke();
}
});
if (enableLabels) {
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = "".concat(theme.labels.text.fontSize, "px ").concat(theme.labels.text.fontFamily);
labels.forEach(function (label) {
ctx.fillStyle = label.textColor;
ctx.fillText("".concat(label.label), label.node.x, label.node.y);
});
}
}, [canvasEl, innerWidth, innerHeight, outerWidth, outerHeight, margin.top, margin.left, theme, pixelRatio, zoomedNodes, enableLabels, labels, borderWidth, getBorderColor]);
var getNodeFromMouseEvent = useMouseCircleDetection({
nodes: zoomedNodes,
canvasEl: canvasEl,
margin: margin
});
var _useTooltip = nivoTooltip.useTooltip(),
showTooltipFromEvent = _useTooltip.showTooltipFromEvent,
hideTooltip = _useTooltip.hideTooltip;
var handleMouseHover = React.useCallback(function (event) {
var node = getNodeFromMouseEvent(event);
if (node) {
onMouseMove === null || onMouseMove === void 0 ? void 0 : onMouseMove(node, event);
showTooltipFromEvent(React.createElement(tooltip, node), event);
} else {
hideTooltip();
}
}, [getNodeFromMouseEvent, showTooltipFromEvent, tooltip, hideTooltip]);
var handleMouseLeave = React.useCallback(function () {
hideTooltip();
}, [hideTooltip]);
var handleClick = React.useCallback(function (event) {
if (!onClick) return;
var node = getNodeFromMouseEvent(event);
if (node) {
onClick(node, event);
}
}, [getNodeFromMouseEvent, onClick]);
return jsxRuntime.jsx("canvas", {
ref: canvasEl,
width: outerWidth * pixelRatio,
height: outerHeight * pixelRatio,
style: {
width: outerWidth,
height: outerHeight,
cursor: isInteractive ? 'auto' : 'normal'
},
role: role,
onMouseEnter: isInteractive ? handleMouseHover : undefined,
onMouseMove: isInteractive ? handleMouseHover : undefined,
onMouseLeave: isInteractive ? handleMouseLeave : undefined,
onClick: isInteractive ? handleClick : undefined
});
};
var CirclePackingCanvas = function CirclePackingCanvas(_ref2) {
var _ref2$isInteractive = _ref2.isInteractive,
isInteractive = _ref2$isInteractive === void 0 ? defaultProps.isInteractive : _ref2$isInteractive,
theme = _ref2.theme,
otherProps = _objectWithoutProperties(_ref2, ["isInteractive", "theme"]);
return jsxRuntime.jsx(nivoCore.Container, {
isInteractive: isInteractive,
theme: theme,
children: jsxRuntime.jsx(InnerCirclePackingCanvas, _objectSpread2({
isInteractive: isInteractive
}, otherProps))
});
};
var ResponsiveCirclePackingCanvas = function ResponsiveCirclePackingCanvas(props) {
return jsxRuntime.jsx(nivoCore.ResponsiveWrapper, {
children: function children(_ref) {
var width = _ref.width,
height = _ref.height;
return jsxRuntime.jsx(CirclePackingCanvas, _objectSpread2({
width: width,
height: height
}, props));
}
});
};
exports.CirclePacking = CirclePacking;
exports.CirclePackingCanvas = CirclePackingCanvas;
exports.CirclePackingHtml = CirclePackingHtml;
exports.InnerCirclePackingHtml = InnerCirclePackingHtml;
exports.ResponsiveCirclePacking = ResponsiveCirclePacking;
exports.ResponsiveCirclePackingCanvas = ResponsiveCirclePackingCanvas;
exports.ResponsiveCirclePackingHtml = ResponsiveCirclePackingHtml;
exports.defaultProps = defaultProps;
exports.useCirclePacking = useCirclePacking;
exports.useCirclePackingLabels = useCirclePackingLabels;
exports.useCirclePackingLayerContext = useCirclePackingLayerContext;
exports.useCirclePackingZoom = useCirclePackingZoom;
exports.useMouseCircleDetection = useMouseCircleDetection;
exports.useNodeMouseHandlers = useNodeMouseHandlers;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=nivo-circle-packing.umd.js.map