decentraland-ui
Version:
Decentraland's UI components and styles
226 lines (225 loc) • 12.9 kB
JavaScript
;
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;