Skip to content

Commit

Permalink
feat: allow overriding ChartLegend, its style and LegendGroup style (#…
Browse files Browse the repository at this point in the history
…112)

* feat: support overriding maximum legend height and legend item alignment

* feat: allow overriding ChartLegend, its style and LegendGroup style
  • Loading branch information
kristw authored and zhaoyongjie committed Nov 26, 2021
1 parent a19137c commit d7a5d8a
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import { WithLegend } from '@superset-ui/chart-composition';
import { createSelector } from 'reselect';
import Encoder, { ChannelTypes, Encoding, Outputs } from './Encoder';
import { Dataset, PlainObject } from '../encodeable/types/Data';
import ChartLegend, { Hooks as LegendHooks } from '../components/legend/ChartLegend';
import ChartLegend, {
Props as LegendProps,
Hooks as LegendHooks,
} from '../components/legend/ChartLegend';
import { PartialSpec } from '../encodeable/types/Specification';
import DefaultTooltipRenderer from './DefaultTooltipRenderer';
import createMarginSelector, { DEFAULT_MARGIN } from '../utils/selectors/createMarginSelector';
Expand All @@ -38,6 +41,7 @@ const defaultProps = {
className: '',
margin: DEFAULT_MARGIN,
theme: chartTheme,
LegendRenderer: ChartLegend,
TooltipRenderer: DefaultTooltipRenderer,
};

Expand All @@ -48,6 +52,7 @@ export type FormDataProps = {
} & PartialSpec<Encoding>;

export type HookProps = {
LegendRenderer?: React.ComponentType<LegendProps<Encoder, ChannelTypes>>;
TooltipRenderer?: React.ComponentType<TooltipProps>;
} & LegendHooks<ChannelTypes>;

Expand Down Expand Up @@ -281,6 +286,7 @@ export default class LineChart extends PureComponent<Props> {
renderLegend() {
const {
data,
LegendRenderer,
LegendGroupRenderer,
LegendItemRenderer,
LegendItemLabelRenderer,
Expand All @@ -290,7 +296,7 @@ export default class LineChart extends PureComponent<Props> {
const encoder = this.createEncoder(this.props);

return (
<ChartLegend<ChannelTypes, Outputs, Encoding>
<LegendRenderer
data={data}
encoder={encoder}
LegendGroupRenderer={LegendGroupRenderer}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ import {
import DefaultLegendGroup from './DefaultLegendGroup';

const LEGEND_CONTAINER_STYLE: CSSProperties = {
display: 'flex',
flexBasis: 'auto',
flexGrow: 1,
flexShrink: 1,
maxHeight: 100,
overflowY: 'auto',
paddingLeft: 14,
paddingTop: 6,
padding: 8,
position: 'relative',
};

Expand All @@ -31,6 +34,7 @@ export type Hooks<ChannelTypes> = {
export type Props<Encoder, ChannelTypes> = {
data: Dataset;
encoder: Encoder;
style?: CSSProperties;
} & Hooks<ChannelTypes>;

export default class ChartLegend<
Expand All @@ -53,13 +57,18 @@ export default class ChartLegend<
LegendItemRenderer,
LegendItemMarkRenderer,
LegendItemLabelRenderer,
style,
} = this.props;

const LegendGroup =
typeof LegendGroupRenderer === 'undefined' ? DefaultLegendGroup : LegendGroupRenderer;
const combinedStyle =
typeof style === 'undefined'
? LEGEND_CONTAINER_STYLE
: { ...LEGEND_CONTAINER_STYLE, ...style };

return (
<div style={LEGEND_CONTAINER_STYLE}>
<div style={combinedStyle}>
{encoder.getLegendInfos(data).map(items => (
<LegendGroup
key={items[0].field}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,29 @@ import DefaultLegendItem from './DefaultLegendItem';

const LEGEND_GROUP_STYLE: CSSProperties = {
display: 'flex',
flexBasis: 'auto',
flexDirection: 'row',
flexGrow: 1,
flexShrink: 1,
flexWrap: 'wrap',
fontSize: '0.8em',
justifyContent: 'flex-end',
};

export default function DefaultLegendGroupRenderer<ChannelTypes>({
items,
ItemRenderer,
ItemMarkRenderer,
ItemLabelRenderer,
style,
}: LegendGroupRendererProps<ChannelTypes>) {
const LegendItem = typeof ItemRenderer === 'undefined' ? DefaultLegendItem : ItemRenderer;

const combinedStyle =
typeof style === 'undefined' ? LEGEND_GROUP_STYLE : { ...LEGEND_GROUP_STYLE, ...style };

return (
<div style={LEGEND_GROUP_STYLE}>
<div style={combinedStyle}>
{items.map(item => (
<LegendItem
key={`legend-item-${item.field}-${item.value}`}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Value } from 'vega-lite/build/src/channeldef';
import { CSSProperties } from 'react';
import { ObjectWithKeysFromAndValueType } from '../../encodeable/types/Base';
import { ChannelInput } from '../../encodeable/types/Channel';

Expand Down Expand Up @@ -31,6 +32,7 @@ export type LegendGroupRendererProps<ChannelTypes> = {
ItemRenderer?: LegendItemRendererType<ChannelTypes>;
ItemMarkRenderer?: LegendItemMarkRendererType<ChannelTypes>;
ItemLabelRenderer?: LegendItemLabelRendererType<ChannelTypes>;
style?: CSSProperties;
};

export type LegendGroupRendererType<ChannelTypes> = React.ComponentType<
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createSelector } from 'reselect';
import { Margin } from '@superset-ui/dimension';

export const DEFAULT_MARGIN = { bottom: 20, left: 20, right: 20, top: 20 };
export const DEFAULT_MARGIN = { bottom: 16, left: 16, right: 16, top: 16 };

export default function createMarginSelector(defaultMargin: Margin = DEFAULT_MARGIN) {
return createSelector(
Expand Down

0 comments on commit d7a5d8a

Please sign in to comment.