UNPKG

@gooddata/react-components

Version:

GoodData.UI - A powerful JavaScript library for building analytical applications

263 lines • 11.7 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); // (C) 2007-2020 GoodData Corporation var React = require("react"); var cx = require("classnames"); var cloneDeep = require("lodash/cloneDeep"); var get = require("lodash/get"); var set = require("lodash/set"); var isEqual = require("lodash/isEqual"); var noop = require("lodash/noop"); var partial = require("lodash/partial"); var throttle = require("lodash/throttle"); var isNil = require("lodash/isNil"); var Chart_1 = require("./Chart"); var Legend_1 = require("./legend/Legend"); var PositionTypes_1 = require("./legend/PositionTypes"); var common_1 = require("../utils/common"); var visualizationTypes_1 = require("../../../constants/visualizationTypes"); var helpers_1 = require("./highcharts/helpers"); var utils_1 = require("../../../helpers/utils"); function renderChart(props) { return React.createElement(Chart_1.default, __assign({}, props)); } exports.renderChart = renderChart; function renderLegend(props) { return React.createElement(Legend_1.default, __assign({}, props)); } exports.renderLegend = renderLegend; function updateAxisTitleStyle(axis) { set(axis, "title.style", __assign({}, get(axis, "title.style", {}), { textOverflow: "ellipsis", overflow: "hidden" })); } var HighChartsRenderer = /** @class */ (function (_super) { __extends(HighChartsRenderer, _super); function HighChartsRenderer(props) { var _this = _super.call(this, props) || this; _this.validateOverHeight = function (legendRect) { var legend = _this.props.legend; if (!_this.isBottomLegend(legend)) { return; } var containerRect = _this.highchartsRendererRef.current.getBoundingClientRect(); var chartHeight = _this.chartRef.getChart().chartHeight; var isLegendOverHeight = legendRect.height > containerRect.height - chartHeight; if (isLegendOverHeight) { var hcContainer = _this.chartRef.getHighchartRef(); set(hcContainer, "style", "flex: 1 0 auto; position: relative;"); _this.chartRef.getChart().update({ chart: { height: containerRect.height, }, }, false, false, false); } }; _this.highchartsRendererRef = React.createRef(); _this.state = { legendItemsEnabled: [], showFluidLegend: utils_1.shouldShowFluid(_this.props.documentObj), }; _this.setChartRef = _this.setChartRef.bind(_this); _this.onLegendItemClick = _this.onLegendItemClick.bind(_this); _this.throttledOnWindowResize = throttle(_this.onWindowResize.bind(_this), 100); return _this; } HighChartsRenderer.prototype.onWindowResize = function () { var documentObj = this.props.documentObj; this.setState({ showFluidLegend: utils_1.shouldShowFluid(documentObj), }); this.realignPieOrDonutChart(); }; HighChartsRenderer.prototype.componentWillMount = function () { this.resetLegendState(this.props); }; HighChartsRenderer.prototype.componentDidMount = function () { var _this = this; // http://stackoverflow.com/questions/18240254/highcharts-width-exceeds-container-div-on-first-load setTimeout(function () { if (_this.chartRef) { var chart = _this.chartRef.getChart(); if (chart.container && chart.container.style) { chart.container.style.height = (_this.props.height && String(_this.props.height)) || "100%"; chart.container.style.position = _this.props.height ? "relative" : "absolute"; chart.reflow(); } } }, 0); this.props.onLegendReady({ legendItems: this.getItems(this.props.legend.items), }); window.addEventListener("resize", this.throttledOnWindowResize); }; HighChartsRenderer.prototype.componentWillUnmount = function () { this.throttledOnWindowResize.cancel(); window.removeEventListener("resize", this.throttledOnWindowResize); }; HighChartsRenderer.prototype.componentWillReceiveProps = function (nextProps) { var thisLegendItems = get(this.props, "legend.items", []); var nextLegendItems = get(nextProps, "legend.items", []); var hasLegendChanged = !isEqual(thisLegendItems, nextLegendItems); if (hasLegendChanged) { this.resetLegendState(nextProps); } if (!isEqual(this.props.legend.items, nextProps.legend.items)) { this.props.onLegendReady({ legendItems: this.getItems(nextProps.legend.items), }); } }; HighChartsRenderer.prototype.onLegendItemClick = function (item) { this.setState({ legendItemsEnabled: set(this.state.legendItemsEnabled.slice(), item.legendIndex, !this.state.legendItemsEnabled[item.legendIndex]), }); }; HighChartsRenderer.prototype.setChartRef = function (chartRef) { this.chartRef = chartRef; }; HighChartsRenderer.prototype.getFlexDirection = function () { var legend = this.props.legend; if (legend.position === PositionTypes_1.TOP || legend.position === PositionTypes_1.BOTTOM) { return "column"; } return "row"; }; HighChartsRenderer.prototype.getItems = function (items) { var _this = this; return items.map(function (i) { return { name: i.name, color: i.color, onClick: partial(_this.onLegendItemClick, i), }; }); }; HighChartsRenderer.prototype.resetLegendState = function (props) { var legendItemsCount = get(props, "legend.items.length", 0); this.setState({ legendItemsEnabled: new Array(legendItemsCount).fill(true), }); }; HighChartsRenderer.prototype.createChartConfig = function (chartConfig, legendItemsEnabled) { var config = cloneDeep(chartConfig); var yAxis = config.yAxis; yAxis.forEach(function (axis) { return updateAxisTitleStyle(axis); }); if (this.props.height) { // fixed chart height is used in Dashboard mobile view // with minHeight of the container (legend overlaps) config.chart.height = this.props.height; } // render chart with disabled visibility based on legendItemsEnabled var firstSeriesTypes = [ visualizationTypes_1.VisualizationTypes.PIE, visualizationTypes_1.VisualizationTypes.DONUT, visualizationTypes_1.VisualizationTypes.TREEMAP, ]; var itemsPath = common_1.isOneOfTypes(config.chart.type, firstSeriesTypes) ? "series[0].data" : "series"; var items = get(config, itemsPath); set(config, itemsPath, items.map(function (item, itemIndex) { var visible = legendItemsEnabled[itemIndex] !== undefined ? legendItemsEnabled[itemIndex] : true; return __assign({}, item, { visible: isNil(item.visible) ? visible : item.visible }); })); return config; }; HighChartsRenderer.prototype.renderLegend = function () { var _a = this.props, chartOptions = _a.chartOptions, legend = _a.legend, height = _a.height, legendRenderer = _a.legendRenderer, locale = _a.locale; var items = legend.items, format = legend.format; var showFluidLegend = this.state.showFluidLegend; if (!legend.enabled) { return null; } var type = chartOptions.type; if (common_1.isPieOrDonutChart(type)) { type = visualizationTypes_1.VisualizationTypes.PIE; } var legendProps = { position: legend.position, responsive: legend.responsive, chartType: type, series: items, onItemClick: this.onLegendItemClick, legendItemsEnabled: this.state.legendItemsEnabled, height: height, format: format, locale: locale, showFluidLegend: showFluidLegend, validateOverHeight: this.validateOverHeight, }; return legendRenderer(legendProps); }; HighChartsRenderer.prototype.renderHighcharts = function () { var style = { flex: "1 1 auto", position: "relative" }; // shrink chart to give space to legend items var chartProps = { domProps: { className: "viz-react-highchart-wrap gd-viz-highchart-wrap", style: style }, ref: this.setChartRef, config: this.createChartConfig(this.props.hcOptions, this.state.legendItemsEnabled), callback: this.props.afterRender, }; return this.props.chartRenderer(chartProps); }; HighChartsRenderer.prototype.render = function () { var _a; var legend = this.props.legend; var showFluidLegend = this.state.showFluidLegend; var classes = cx("viz-line-family-chart-wrap", "s-viz-line-family-chart-wrap", legend.responsive ? "responsive-legend" : "non-responsive-legend", (_a = {}, _a["flex-direction-" + this.getFlexDirection()] = true, _a["legend-position-bottom"] = this.isBottomLegend(legend), _a)); var isLegendRenderedFirst = legend.position === PositionTypes_1.TOP || legend.position === PositionTypes_1.LEFT || showFluidLegend; return (React.createElement("div", { className: classes, ref: this.highchartsRendererRef }, isLegendRenderedFirst && this.renderLegend(), this.renderHighcharts(), !isLegendRenderedFirst && this.renderLegend())); }; HighChartsRenderer.prototype.realignPieOrDonutChart = function () { var type = this.props.chartOptions.type; var chartRef = this.chartRef; if (common_1.isPieOrDonutChart(type) && chartRef) { helpers_1.alignChart(chartRef.getChart()); } }; HighChartsRenderer.prototype.isBottomLegend = function (legend) { return legend.position === PositionTypes_1.BOTTOM; }; HighChartsRenderer.defaultProps = { afterRender: noop, height: null, legend: { enabled: true, responsive: false, position: PositionTypes_1.RIGHT, }, chartRenderer: renderChart, legendRenderer: renderLegend, onLegendReady: noop, documentObj: document, }; return HighChartsRenderer; }(React.PureComponent)); exports.default = HighChartsRenderer; //# sourceMappingURL=HighChartsRenderer.js.map