UNPKG

decentraland-ui

Version:

Decentraland's UI components and styles

226 lines (225 loc) 12.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.BarChart = void 0; var React = __importStar(require("react")); var react_1 = require("react"); var classnames_1 = __importDefault(require("classnames")); var recharts_1 = require("recharts"); var network_1 = require("@dcl/schemas/dist/dapps/network"); var RangeField_1 = require("../RangeField"); var SliderField_1 = require("../SliderField/SliderField"); var Mana_1 = require("../Mana/Mana"); var Loader_1 = require("../Loader/Loader"); var utils_1 = require("./utils"); var BarChartTooltip_1 = require("./BarChartTooltip"); require("./BarChart.css"); var DEFAULT_SLIDER_STEP = 0.1; var BarChart = function (_a) { var _b = _a.height, height = _b === void 0 ? 150 : _b, _c = _a.width, width = _c === void 0 ? '100%' : _c, data = _a.data, upperBound = _a.upperBound, loading = _a.loading, onChange = _a.onChange, min = _a.min, max = _a.max, minLabel = _a.minLabel, maxLabel = _a.maxLabel, _d = _a.isMana, isMana = _d === void 0 ? false : _d, _e = _a.network, network = _e === void 0 ? network_1.Network.ETHEREUM : _e, _f = _a.sliderStep, sliderStep = _f === void 0 ? DEFAULT_SLIDER_STEP : _f, errorMessage = _a.errorMessage, _g = _a.rangeDecimals, rangeDecimals = _g === void 0 ? 2 : _g, _h = _a.id, id = _h === void 0 ? 'bar-chart' : _h; var _j = (0, react_1.useState)([min, max]), value = _j[0], setValue = _j[1]; var _k = (0, react_1.useState)(), ranges = _k[0], setRanges = _k[1]; var _l = (0, react_1.useState)(), activeBar = _l[0], setActiveBar = _l[1]; var _m = (0, react_1.useState)(), rangeMax = _m[0], setRangeMax = _m[1]; var _o = (0, react_1.useState)(), rangeMin = _o[0], setRangeMin = _o[1]; var timeout = (0, react_1.useRef)(null); (0, react_1.useEffect)(function () { return setValue([min, max]); }, [min, max]); // clear the timeout if needed (0, react_1.useEffect)(function () { return function () { if (timeout.current) { clearTimeout(timeout.current); } }; }, []); (0, react_1.useEffect)(function () { if (data) { try { var formattedValues = Object.keys(data).map(function (key) { return Number(key); }); var maxValueFromDataset = Math.max.apply(Math, formattedValues); var maxValue = upperBound ? upperBound < maxValueFromDataset ? upperBound : maxValueFromDataset : maxValueFromDataset; var minValue = Math.min.apply(Math, formattedValues); setRangeMax(maxValue); setRangeMin(minValue); setRanges((0, utils_1.getBarChartRanges)(data, minValue, maxValue, upperBound, rangeDecimals)); } catch (error) { console.error('error: ', error); } } }, [data, upperBound]); var inputMaxRangeValue = (0, react_1.useMemo)(function () { return (rangeMax !== undefined ? (0, utils_1.inverseScale)(rangeMax) : undefined); }, [rangeMax]); var inputMinRangeValue = (0, react_1.useMemo)(function () { return (rangeMin !== undefined ? (0, utils_1.inverseScale)(rangeMin) : undefined); }, [rangeMin]); var valueFromForRangeInput = (0, react_1.useMemo)(function () { var scaledValue = value[0] ? (0, utils_1.inverseScale)(Number(value[0])) : Number(inputMinRangeValue); // value lower than input min if (scaledValue < inputMinRangeValue) { return inputMinRangeValue; } // value higher or equal value max if (scaledValue > inputMaxRangeValue) { return inputMaxRangeValue; } return scaledValue; }, [inputMinRangeValue, value, inputMaxRangeValue]); var valueToForRangeInput = (0, react_1.useMemo)(function () { var scaledValue = value[1] ? (0, utils_1.inverseScale)(Number(value[1])) : Number(inputMaxRangeValue); // value higher than input max if (scaledValue > inputMaxRangeValue) { return inputMaxRangeValue; } // value lower or equal than current min value in range if (scaledValue < valueFromForRangeInput) { return valueFromForRangeInput; } return scaledValue; }, [inputMaxRangeValue, value, inputMinRangeValue, valueFromForRangeInput]); var showMaxError = (0, react_1.useMemo)(function () { return value[0] && value[1] && Number(value[1]) <= Number(value[0]); }, [value]); // Slider variables to display var sliderMinLabel = (0, react_1.useMemo)(function () { var min = value[0] ? Number(value[0]) : rangeMin ? rangeMin : ''; return utils_1.numberFormatter.format(Number(min)); }, [rangeMin, value]); var sliderMaxLabel = (0, react_1.useMemo)(function () { if (data) { var datasetMax = (0, utils_1.getDatasetBounds)(data).max; var currentMax = Number(value[1] || rangeMax); var isInputAtMaxValue = currentMax === rangeMax; return "".concat(utils_1.numberFormatter.format(Number(currentMax))).concat(isInputAtMaxValue && upperBound && upperBound < datasetMax ? '+' : ''); } }, [data, rangeMax, upperBound, value]); // Component handlers var handleChange = (0, react_1.useCallback)(function (newValue, _, source) { var from = (0, utils_1.fixedNumber)(newValue[0], rangeDecimals); var to = (0, utils_1.fixedNumber)(newValue[1], rangeDecimals); setValue([from, to]); if (timeout.current) { clearTimeout(timeout.current); } timeout.current = setTimeout(function () { return onChange([from, to], source ? source : 'input'); }, 500); }, [setValue, onChange]); var handleRangeChange = (0, react_1.useCallback)(function (_, _a) { var min = _a[0], max = _a[1]; if (rangeMax !== undefined && rangeMin !== undefined && inputMaxRangeValue) { // it can happend that the slider doesn't go all the way to the max because there's no room for other step. // So we compare the diff to the input step. If it's lower, we programmatically move it to the max var remainingToMax = inputMaxRangeValue - max; var isTheMaxValue = (0, utils_1.getFlooredFixed)(max, 1) === (0, utils_1.getFlooredFixed)(Number(inputMaxRangeValue), 1) || remainingToMax <= sliderStep; var formattedMin = Math.pow(utils_1.CHART_LOG_SCALE, min); var formattedMax = isTheMaxValue ? rangeMax : Math.pow(utils_1.CHART_LOG_SCALE, max); var newValue = [ (0, utils_1.roundNumber)(formattedMin, rangeDecimals).toString(), (0, utils_1.roundNumber)(formattedMax, rangeDecimals).toString() ]; setValue(newValue); handleChange(newValue, null, 'slider'); } }, [handleChange, inputMaxRangeValue, rangeMax, rangeMin, sliderStep]); // Bar chart handlers var handleBarChartMouseMove = (0, react_1.useCallback)(function (e) { setActiveBar(e.activeTooltipIndex); }, []); var handleBarChartMouseLeave = (0, react_1.useCallback)(function () { setActiveBar(undefined); }, []); var handleBarChartClick = (0, react_1.useCallback)(function (_a) { var activePayload = _a.activePayload; var values = activePayload[0].payload.values; var isUpperBoundRange = values[0] === values[1]; handleChange(isUpperBoundRange ? [values[0].toString(), ''] : (0, utils_1.roundRange)(activePayload[0].payload.values), null, 'chart'); }, [handleChange]); var renderBarCell = (0, react_1.useCallback)(function (entry, index) { var isActiveRange = (0, utils_1.isValuesInCurrentRange)(entry.values, Number(value[0] || rangeMin), Number(value[1] || rangeMax)); return (React.createElement(recharts_1.Cell, { key: "cell-".concat(index), fill: activeBar === index ? utils_1.HOVERED_BAR_COLOR : loading ? utils_1.LOADING_BAR_COLOR : isActiveRange ? utils_1.ACTIVE_BAR_COLOR : utils_1.NON_ACTIVE_BAR_COLOR })); }, [activeBar, loading, rangeMax, rangeMin, value]); // disables the behavior of chanhing value while scrolling on top of the input var onRangeWheel = (0, react_1.useCallback)(function (e) { // Prevent the input value change e.target.blur(); // Prevent the page/container scrolling e.stopPropagation(); timeout.current = setTimeout(function () { e.target.focus(); }, 0); }, []); var handleBlur = (0, react_1.useCallback)(function () { if (Number.parseFloat(value[0]) > Number.parseFloat(value[1])) { var swappedRange = [value[1], value[0]]; setValue(swappedRange); onChange(swappedRange, 'input'); } }, [onChange, setValue, value]); function getLabel(value) { return isMana ? (React.createElement(Mana_1.Mana, { network: network, className: "slider-label" }, value)) : (React.createElement("span", { className: "slider-label" }, value)); } return (React.createElement("div", { className: "bar-chart" }, React.createElement(RangeField_1.RangeField, { minLabel: minLabel, maxLabel: maxLabel, id: "".concat(id, "-range-field"), minProps: { icon: isMana ? React.createElement(Mana_1.Mana, { network: network }) : null, iconPosition: 'left', placeholder: 0, onWheel: onRangeWheel }, maxProps: { icon: isMana ? React.createElement(Mana_1.Mana, { network: network }) : null, iconPosition: 'left', placeholder: 1000, onWheel: onRangeWheel }, onChange: handleChange, onBlur: handleBlur, value: value }), loading ? (React.createElement("div", { className: (0, classnames_1.default)('loader-container', !data && 'no-data-loading-layer') }, React.createElement("div", { className: "loading-layer" }), React.createElement(Loader_1.Loader, { active: true }))) : null, !!data && !!ranges && !!inputMaxRangeValue && (React.createElement(React.Fragment, null, React.createElement(recharts_1.ResponsiveContainer, { width: width, height: height }, React.createElement(recharts_1.BarChart, { data: ranges, margin: { top: 20, right: 12, left: 12 }, onMouseMove: handleBarChartMouseMove, onMouseLeave: handleBarChartMouseLeave, onClick: handleBarChartClick }, React.createElement(recharts_1.Tooltip, { cursor: false, content: React.createElement(BarChartTooltip_1.BarChartTooltip, { network: network, isMana: isMana }), position: { y: 25 } }), React.createElement(recharts_1.Bar, { dataKey: "amount", barSize: 8 }, ranges === null || ranges === void 0 ? void 0 : ranges.map(renderBarCell)))), React.createElement(SliderField_1.SliderField, { header: "", range: true, valueFrom: valueFromForRangeInput, valueTo: valueToForRangeInput, min: inputMinRangeValue, max: inputMaxRangeValue, step: sliderStep, onChange: handleRangeChange, labelFrom: getLabel(sliderMinLabel), labelTo: getLabel(sliderMaxLabel) }), errorMessage && showMaxError ? (React.createElement("span", { className: "bar-chart-error" }, errorMessage)) : null)))); }; exports.BarChart = BarChart;