UNPKG

synapse-react-client

Version:

[![Build Status](https://travis-ci.com/Sage-Bionetworks/Synapse-React-Client.svg?branch=main)](https://travis-ci.com/Sage-Bionetworks/Synapse-React-Client) [![npm version](https://badge.fury.io/js/synapse-react-client.svg)](https://badge.fury.io/js/synaps

229 lines 13.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NEXT_CLICK = exports.PREVIOUS_ITEM_CLICK = void 0; var tslib_1 = require("tslib"); var fontawesome_svg_core_1 = require("@fortawesome/fontawesome-svg-core"); var free_solid_svg_icons_1 = require("@fortawesome/free-solid-svg-icons"); var react_fontawesome_1 = require("@fortawesome/react-fontawesome"); var React = (0, tslib_1.__importStar)(require("react")); var react_measure_1 = (0, tslib_1.__importDefault)(require("react-measure")); var react_tooltip_1 = (0, tslib_1.__importDefault)(require("react-tooltip")); var ColorGradient_1 = require("./ColorGradient"); var facetUtils_1 = require("../utils/functions/facetUtils"); var unCamelCase_1 = require("../utils/functions/unCamelCase"); var LoadingScreen_1 = (0, tslib_1.__importDefault)(require("./LoadingScreen")); var utils_1 = require("../utils"); fontawesome_svg_core_1.library.add(free_solid_svg_icons_1.faAngleLeft); fontawesome_svg_core_1.library.add(free_solid_svg_icons_1.faAngleRight); exports.PREVIOUS_ITEM_CLICK = 'left click'; exports.NEXT_CLICK = 'right click'; /** * Make a simple stacked bar chart * * @class StackedBarChart * @extends {React.Component} */ var StackedBarChart = /** @class */ (function (_super) { (0, tslib_1.__extends)(StackedBarChart, _super); function StackedBarChart(props) { var _this = _super.call(this, props) || this; /** * Handle column click event */ _this.handleClick = function (dict) { return function (_event) { // https://medium.freecodecamp.org/reactjs-pass-parameters-to-event-handlers-ca1f5c422b9 _this.props.updateParentState({ chartSelectionIndex: dict.index }); }; }; _this.handleArrowClick = function (direction) { return function (_event) { var _a = _this.props.chartSelectionIndex, chartSelectionIndex = _a === void 0 ? 0 : _a; var dict = _this.extractPropsData(_this.props.data); var length = Object.keys(dict).length; if (direction === exports.PREVIOUS_ITEM_CLICK) { chartSelectionIndex -= 1; // if its at zero then we want to wrap around to the end chartSelectionIndex = chartSelectionIndex < 0 ? length - 1 : chartSelectionIndex; } else { chartSelectionIndex += 1; } chartSelectionIndex = chartSelectionIndex % length; dict = dict[chartSelectionIndex]; _this.props.updateParentState({ chartSelectionIndex: chartSelectionIndex }); // return is only for testing purposes return chartSelectionIndex; }; }; _this.handleHover = _this.handleHover.bind(_this); _this.handleExit = _this.handleExit.bind(_this); _this.handleClick = _this.handleClick.bind(_this); _this.handleArrowClick = _this.handleArrowClick.bind(_this); _this.getTextForChartSelection = _this.getTextForChartSelection.bind(_this); _this.onMeasureResize = _this.onMeasureResize.bind(_this); // the text currently under the cursor _this.state = { // the dimensions of the bar chart itself dimensions: { bounds: { height: 1, width: 1, top: 0, left: 0, right: 0, bottom: 0 }, }, // the text of the current slice // the count of this facet value occurence selectedFacets: {}, }; _this.extractPropsData = _this.extractPropsData.bind(_this); return _this; } /** * Updates the hover text and update the view * * @memberof StackedBarChart */ StackedBarChart.prototype.handleHover = function (event) { // add box shadow event.currentTarget.style.boxShadow = '25px 20px'; }; /** * Update the hover text and the view * * @param {*} event * @memberof StackedBarChart */ StackedBarChart.prototype.handleExit = function (event) { // remove box shadow event.currentTarget.style.boxShadow = ''; }; StackedBarChart.prototype.getTextForChartSelection = function (xData) { var _a = this.props.chartSelectionIndex, chartSelectionIndex = _a === void 0 ? 0 : _a; var _b = this.props, _c = _b.facetAliases, facetAliases = _c === void 0 ? {} : _c, facet = _b.facet; var facetValueDisplay = xData[chartSelectionIndex] && xData[chartSelectionIndex].value; var filterDisplay = facetAliases[facet] || (0, unCamelCase_1.unCamelCase)(facet); return (React.createElement("span", null, React.createElement("span", { className: "SRC-text-title SRC-filter-display" }, filterDisplay), ":", React.createElement("span", { className: "SRC-facet-view SRC-text-title" }, facetValueDisplay === utils_1.SynapseConstants.VALUE_NOT_SET ? utils_1.SynapseConstants.FRIENDLY_VALUE_NOT_SET : facetValueDisplay))); }; StackedBarChart.prototype.getFileCount = function (xData) { var _a = this.props.chartSelectionIndex, chartSelectionIndex = _a === void 0 ? 1 : _a; return xData[chartSelectionIndex] && xData[chartSelectionIndex].count; }; StackedBarChart.prototype.render = function () { var _this = this; var _a = this.props, data = _a.data, isLoadingNewData = _a.isLoadingNewData, rgbIndex = _a.rgbIndex, _b = _a.facet, facet = _b === void 0 ? '' : _b, unitDescription = _a.unitDescription, isLoading = _a.isLoading, lastFacetSelection = _a.lastFacetSelection, isAllFilterSelectedForFacet = _a.isAllFilterSelectedForFacet, chartSelectionIndex = _a.chartSelectionIndex, asyncJobStatus = _a.asyncJobStatus; // while loading if (isLoadingNewData) { return (React.createElement("div", { className: "SRC-loadingContainer SRC-centerContentColumn" }, LoadingScreen_1.default, React.createElement("div", null, asyncJobStatus && asyncJobStatus.progressMessage))); } var xData = this.extractPropsData(data); var total = 0; var width = this.state.dimensions.bounds.width; // sum up the counts of data for (var key in xData) { if (xData.hasOwnProperty(key)) { total += xData[key].count; } } var _c = (0, ColorGradient_1.getColorPalette)(rgbIndex, xData.length), colorPalette = _c.colorPalette, textColors = _c.textColors; var originalColor = colorPalette[0]; return (React.createElement(React.Fragment, null, React.createElement("div", { className: "SRC-bar-border SRC-bar-marginTop SRC-bar-border-top", "data-testid": 'StackedBarChart' }, React.createElement(react_measure_1.default, { bounds: true, onResize: function (contentRect) { _this.setState({ dimensions: contentRect }); } }, function (_a) { var measureRef = _a.measureRef; return (React.createElement("div", { className: "SRC-flex", ref: measureRef }, xData.map(function (obj, index) { var textColor = textColors[index]; var rgbColor = colorPalette[index]; var rectStyle; var isValueSelected = isAllFilterSelectedForFacet[facet] ? true : (0, facetUtils_1.getIsValueSelected)({ isLoading: isLoading, lastFacetSelection: lastFacetSelection, columnName: facet, curFacetSelection: obj, }); if (isValueSelected) { rectStyle = { fill: rgbColor, }; } else { rectStyle = { fill: '#C4C4C4', }; } var svgHeight = 80; var svgWidth = (obj.count / total) * width; var style = {}; if (chartSelectionIndex === index) { style.filter = 'drop-shadow(5px 5px 5px rgba(0,0,0,0.5))'; } var label = facet + ": " + obj.value + " - " + obj.count + " " + unitDescription; // there was one bug where a new line character was in the obj.value, making data-for // break because its a special character, below we remove that var tooltipId = obj.value.replace(/(\r\n|\n|\r)/gm, ''); // basic heuristic to calculate the number of pixels needed to show the value on the bar chart var value = obj.count; var numCharsInValue = value.toString().length * 4.5; // represents width of a character return ( // each svg represents one of the bars // will need to change this to be responsive React.createElement(React.Fragment, { key: label }, React.createElement("span", { "data-for": tooltipId, "data-tip": label }, React.createElement("svg", { className: "SRC-hoverBox", height: svgHeight + 15, width: svgWidth, style: style, onClick: _this.handleClick((0, tslib_1.__assign)((0, tslib_1.__assign)({}, obj), { index: index })) }, React.createElement("rect", { onMouseEnter: _this.handleHover, onMouseLeave: _this.handleExit, height: svgHeight, width: svgWidth, className: "SRC-chart-rect-style", // can't remove inline style due to dynamic fill style: rectStyle }), index < 3 && svgWidth > numCharsInValue && (React.createElement("text", { textAnchor: "middle", className: "SRC-text-title", fontFamily: 'bold sans-serif', fill: textColor, x: '50%', y: '50%' }, obj.count)), chartSelectionIndex === index && (React.createElement("text", { fill: originalColor, x: 0, y: svgHeight + 15, className: "SRC-text-shadow SRC-text-large" }, '\u25CF')))), React.createElement(react_tooltip_1.default, { delayShow: 1000, id: tooltipId }))); }))); })), React.createElement("div", { className: "SRC-bar-border SRC-bar-border-bottom" }, React.createElement("p", { className: "SRC-noMargin SRC-padding-chart SRC-text-title" }, React.createElement("strong", null, this.getTextForChartSelection(xData))), React.createElement("p", { id: "fileCount", className: "SRC-noMargin SRC-padding-chart SRC-text-chart" }, this.getFileCount(xData), " ", unitDescription), this.props.link && (React.createElement("div", { className: "SRC-chart-link" }, React.createElement("a", { href: "/" + this.props.link }, " ", this.props.linkText, " ")))), React.createElement("div", { className: "SRC-chart-nav SRC-center-text" }, React.createElement("button", { className: "SRC-chart-btn SRC-floatRight", type: "button", onClick: this.handleArrowClick(exports.NEXT_CLICK) }, React.createElement(react_fontawesome_1.FontAwesomeIcon, { style: { fontSize: '11px' }, className: "SRC-primary-text-color", icon: "angle-right" })), React.createElement("button", { className: "SRC-chart-btn SRC-floatRight", type: "button", onClick: this.handleArrowClick(exports.PREVIOUS_ITEM_CLICK) }, React.createElement(react_fontawesome_1.FontAwesomeIcon, { style: { fontSize: '11px' }, className: "SRC-primary-text-color", icon: "angle-left" }))))); }; StackedBarChart.prototype.extractPropsData = function (data) { var _a; var xData = []; var facet = this.props.facet; // pull out the data corresponding to the filter in question (_a = data === null || data === void 0 ? void 0 : data.facets) === null || _a === void 0 ? void 0 : _a.forEach(function (item) { if (item.facetType === 'enumeration' && item.columnName === facet) { item.facetValues.forEach(function (facetValue) { if (item.columnName) { xData.push((0, tslib_1.__assign)({ columnName: item.columnName }, facetValue)); } }); } }); // sort the data so that the largest bars are at the front xData.sort(function (a, b) { return b.count - a.count; }); return xData; }; StackedBarChart.prototype.onMeasureResize = function (contentRect) { this.setState({ dimensions: contentRect }); }; return StackedBarChart; }(React.Component)); exports.default = StackedBarChart; //# sourceMappingURL=StackedBarChart.js.map