UNPKG

rumble-charts

Version:

Truly declarative React charts components

120 lines (117 loc) 6.32 kB
import { __assign } from './external/tslib/tslib.es6.js'; import React, { useState, useEffect } from 'react'; import { scaleLinear } from 'd3-scale'; import cloud from 'd3-cloud'; import { colorFunc, defaultSchemeName } from './helpers/colorFunc.js'; import 'd3-shape'; import 'd3-ease'; import { isUndefined } from './helpers/isUndefined.js'; import { value } from './helpers/value.js'; /** * Renders cloud of tags/keywords. Uses [d3-cloud](https://www.npmjs.com/package/d3-cloud) for calculations. * Please notice, `series` data points should have `label` attribute. See example below. */ function Cloud(props) { var _a; var className = props.className, layerWidth = props.layerWidth, layerHeight = props.layerHeight, _b = props.colors, colors = _b === void 0 ? defaultSchemeName : _b; var _c = useState({ labels: [], series: [] }), state = _c[0], setState = _c[1]; useEffect(function () { var layerWidth = props.layerWidth, layerHeight = props.layerHeight, series = props.series, minY = props.minY, maxY = props.maxY, canvas = props.canvas, _a = props.font, font = _a === void 0 ? 'serif' : _a, _b = props.minFontSize, minFontSize = _b === void 0 ? 10 : _b, _c = props.maxFontSize, maxFontSize = _c === void 0 ? 100 : _c, _d = props.timeInterval, timeInterval = _d === void 0 ? 15 : _d, _e = props.fontStyle, fontStyle = _e === void 0 ? 'normal' : _e, _f = props.fontWeight, fontWeight = _f === void 0 ? 'normal' : _f, rotate = props.rotate, _g = props.spiral, spiral = _g === void 0 ? 'archimedean' : _g, _h = props.padding, padding = _h === void 0 ? 1 : _h, random = props.random; var scale = scaleLinear() .range([minFontSize, maxFontSize]) .domain([minY, maxY]); var words = (series === null || series === void 0 ? void 0 : series.reduce(function (words, _a, seriesIndex) { var data = _a.data; data.forEach(function (point, pointIndex) { words.push(__assign(__assign({}, point), { text: point.label, size: point.y, seriesIndex: seriesIndex, pointIndex: pointIndex })); }); return words; }, [])) || []; var cl = cloud() .size([layerWidth, layerHeight]) .words(words) .font(font) .fontStyle(fontStyle) .fontWeight(fontWeight) .spiral(spiral) .padding(padding) .timeInterval(timeInterval) .fontSize(function (p) { return scale(p.size); }); if (!isUndefined(rotate)) { cl.rotate(rotate); } if (random) { cl.random(random); } if (canvas) { cl.canvas(canvas); } cl.on('end', function (cloudLabels) { var labels = cloudLabels.reduce(function (labels, label) { labels[label.seriesIndex] = labels[label.seriesIndex] || []; labels[label.seriesIndex][label.pointIndex] = label; return labels; }, []); setState({ series: series, labels: labels }); }); cl.start(); }, [ setState, layerWidth, layerHeight, props.series, props.minY, props.maxY, props.canvas, props.timeInterval, props.font, props.minFontSize, props.maxFontSize, props.fontStyle, props.fontWeight, props.rotate, props.spiral, props.padding, props.random ]); var color = colorFunc(colors); return React.createElement("g", { className: className, style: props.style, opacity: props.opacity, transform: 'translate(' + (layerWidth / 2) + ',' + (layerHeight / 2) + ')' }, (_a = state.series) === null || _a === void 0 ? void 0 : _a.map(function (series, seriesIndex) { if ('seriesVisible' in props) { var seriesVisible = value(props.seriesVisible, { seriesIndex: seriesIndex, series: series, props: props }); if (!seriesVisible) { return; } } var seriesAttributes = value(props.seriesAttributes, { seriesIndex: seriesIndex, series: series, props: props }); var seriesStyle = value(props.seriesStyle, { seriesIndex: seriesIndex, series: series, props: props }); return React.createElement("g", __assign({ key: seriesIndex, className: className && (className + '-series ' + className + '-series-' + seriesIndex), style: seriesStyle, opacity: series.opacity }, seriesAttributes), series.data.map(function (point, pointIndex) { var _a, _b; var label = (_b = (_a = state.labels) === null || _a === void 0 ? void 0 : _a[seriesIndex]) === null || _b === void 0 ? void 0 : _b[pointIndex]; if (!label) { return; } if ('labelVisible' in props) { var labelVisible = value(props.labelVisible, { seriesIndex: seriesIndex, pointIndex: pointIndex, point: point, label: label, series: series, props: props }); if (!labelVisible) { return; } } var labelAttributes = value(props.labelAttributes, { seriesIndex: seriesIndex, pointIndex: pointIndex, point: point, label: label, series: series, props: props }); var labelStyle = value([point.style, series.style, props.labelStyle], { seriesIndex: seriesIndex, pointIndex: pointIndex, point: point, label: label, series: series, props: props }); return React.createElement("g", { key: pointIndex, className: className && (className + '-label ' + className + '-label-' + +pointIndex), style: { fontSize: label.size + 'px', fontFamily: label.font } }, React.createElement("text", __assign({ transform: 'translate(' + label.x + ',' + label.y + '),rotate(' + label.rotate + ')', fill: point.color || series.color || color(seriesIndex), fillOpacity: point.opacity, textAnchor: 'middle', style: labelStyle }, labelAttributes), label.text)); })); })); } export { Cloud };