mirror of
https://github.com/apache/superset.git
synced 2024-09-19 12:09:42 -04:00
154 lines
4.1 KiB
JavaScript
154 lines
4.1 KiB
JavaScript
/**
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
/* eslint-disable react/sort-prop-types, react/jsx-sort-default-props */
|
|
import React from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import { ParentSize } from '@vx/responsive';
|
|
|
|
const propTypes = {
|
|
className: PropTypes.string,
|
|
width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
|
renderChart: PropTypes.func.isRequired,
|
|
renderLegend: PropTypes.func.isRequired,
|
|
position: PropTypes.oneOf(['top', 'left', 'bottom', 'right']),
|
|
legendJustifyContent: PropTypes.oneOf(['center', 'flex-start', 'flex-end']),
|
|
};
|
|
const defaultProps = {
|
|
className: '',
|
|
width: 'auto',
|
|
height: 'auto',
|
|
position: 'top',
|
|
legendJustifyContent: undefined,
|
|
};
|
|
|
|
const LEGEND_STYLE_BASE = {
|
|
display: 'flex',
|
|
flexGrow: 0,
|
|
flexShrink: 0,
|
|
order: -1,
|
|
paddingTop: '5px',
|
|
fontSize: '0.9em',
|
|
};
|
|
|
|
const CHART_STYLE_BASE = {
|
|
flexGrow: 1,
|
|
flexShrink: 1,
|
|
flexBasis: 'auto',
|
|
position: 'relative',
|
|
};
|
|
|
|
class WithLegend extends React.Component {
|
|
getContainerDirection() {
|
|
const { position } = this.props;
|
|
switch (position) {
|
|
case 'left':
|
|
return 'row';
|
|
case 'right':
|
|
return 'row-reverse';
|
|
case 'bottom':
|
|
return 'column-reverse';
|
|
default:
|
|
case 'top':
|
|
return 'column';
|
|
}
|
|
}
|
|
|
|
getLegendJustifyContent() {
|
|
const { legendJustifyContent, position } = this.props;
|
|
if (legendJustifyContent) {
|
|
return legendJustifyContent;
|
|
}
|
|
switch (position) {
|
|
case 'left':
|
|
return 'flex-start';
|
|
case 'right':
|
|
return 'flex-start';
|
|
case 'bottom':
|
|
return 'flex-end';
|
|
default:
|
|
case 'top':
|
|
return 'flex-end';
|
|
}
|
|
}
|
|
|
|
render() {
|
|
const { className, width, height, position, renderChart, renderLegend } =
|
|
this.props;
|
|
|
|
const isHorizontal = position === 'left' || position === 'right';
|
|
|
|
const style = {
|
|
display: 'flex',
|
|
flexDirection: this.getContainerDirection(),
|
|
};
|
|
if (width) {
|
|
style.width = width;
|
|
}
|
|
if (height) {
|
|
style.height = height;
|
|
}
|
|
|
|
const chartStyle = { ...CHART_STYLE_BASE };
|
|
if (isHorizontal) {
|
|
chartStyle.width = 0;
|
|
} else {
|
|
chartStyle.height = 0;
|
|
}
|
|
|
|
const legendDirection = isHorizontal ? 'column' : 'row';
|
|
const legendStyle = {
|
|
...LEGEND_STYLE_BASE,
|
|
flexDirection: legendDirection,
|
|
justifyContent: this.getLegendJustifyContent(),
|
|
};
|
|
const legendContainerStyle = {
|
|
flexWrap: 'wrap',
|
|
display: 'flex',
|
|
flexDirection: legendDirection,
|
|
};
|
|
return (
|
|
<div className={`with-legend ${className}`} style={style}>
|
|
<div className="legend-container" style={legendStyle}>
|
|
{renderLegend({
|
|
// Pass flexDirection for @vx/legend to arrange legend items
|
|
direction: legendDirection,
|
|
style: legendContainerStyle,
|
|
})}
|
|
</div>
|
|
<div className="main-container" style={chartStyle}>
|
|
<ParentSize>
|
|
{parent =>
|
|
parent.width > 0 && parent.height > 0
|
|
? // Only render when necessary
|
|
renderChart(parent)
|
|
: null
|
|
}
|
|
</ParentSize>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
|
|
WithLegend.propTypes = propTypes;
|
|
WithLegend.defaultProps = defaultProps;
|
|
|
|
export default WithLegend;
|