Files
Andrej Ocenas fdd6620d0a NodeGraph: Exploration mode (#33623)
* Add exploration option to node layout

* Add hidden node count

* Add grid layout option

* Fix panning bounds calculation

* Add legend with sorting

* Allow sorting on any stats or arc value

* Fix merge

* Make sorting better

* Reset focused node on layout change

* Refactor limit hook a bit

* Disable selected layout button

* Don't show markers if only 1 node is hidden

* Move legend to the bottom

* Fix text backgrounds

* Add show in graph layout action in grid layout

* Center view on the focused node, fix perf issue when expanding big graph

* Limit the node counting

* Comment and linting fixes

* Bit of code cleanup and comments

* Add state for computing layout

* Prevent computing map with partial data

* Add rollup plugin for worker

* Add rollup plugin for worker

* Enhance data from worker

* Fix perf issues with reduce and object creation

* Improve comment

* Fix tests

* Css fixes

* Remove worker plugin

* Add comments

* Fix test

* Add test for exploration

* Add test switching to grid layout

* Apply suggestions from code review

Co-authored-by: Zoltán Bedi <zoltan.bedi@gmail.com>

* Remove unused plugin

* Fix function name

* Remove unused rollup plugin

* Review fixes

* Fix context menu shown on layout change

* Make buttons bigger

* Moved NodeGraph to core grafana

Co-authored-by: Zoltán Bedi <zoltan.bedi@gmail.com>
2021-05-12 16:04:21 +02:00

117 lines
3.0 KiB
TypeScript

import React from 'react';
import { VizLegendBaseProps, VizLegendItem } from './types';
import { InlineList } from '../List/InlineList';
import { List } from '../List/List';
import { css, cx } from '@emotion/css';
import { useStyles } from '../../themes';
import { GrafanaTheme } from '@grafana/data';
import { VizLegendListItem } from './VizLegendListItem';
export interface Props<T> extends VizLegendBaseProps<T> {}
/**
* @internal
*/
export const VizLegendList = <T extends unknown>({
items,
itemRenderer,
onLabelMouseEnter,
onLabelMouseOut,
onLabelClick,
placement,
className,
}: Props<T>) => {
const styles = useStyles(getStyles);
if (!itemRenderer) {
/* eslint-disable-next-line react/display-name */
itemRenderer = (item) => (
<VizLegendListItem
item={item}
onLabelClick={onLabelClick}
onLabelMouseEnter={onLabelMouseEnter}
onLabelMouseOut={onLabelMouseOut}
/>
);
}
const getItemKey = (item: VizLegendItem<T>) => `${item.getItemKey ? item.getItemKey() : item.label}`;
switch (placement) {
case 'right': {
const renderItem = (item: VizLegendItem<T>, index: number) => {
return <span className={styles.itemRight}>{itemRenderer!(item, index)}</span>;
};
return (
<div className={cx(styles.rightWrapper, className)}>
<List items={items} renderItem={renderItem} getItemKey={getItemKey} />
</div>
);
}
case 'bottom':
default: {
const renderItem = (item: VizLegendItem<T>, index: number) => {
return <span className={styles.itemBottom}>{itemRenderer!(item, index)}</span>;
};
return (
<div className={cx(styles.bottomWrapper, className)}>
<div className={styles.section}>
<InlineList
items={items.filter((item) => item.yAxis === 1)}
renderItem={renderItem}
getItemKey={getItemKey}
/>
</div>
<div className={cx(styles.section, styles.sectionRight)}>
<InlineList
items={items.filter((item) => item.yAxis !== 1)}
renderItem={renderItem}
getItemKey={getItemKey}
/>
</div>
</div>
);
}
}
};
VizLegendList.displayName = 'VizLegendList';
const getStyles = (theme: GrafanaTheme) => {
const itemStyles = css`
padding-right: 10px;
display: flex;
font-size: ${theme.typography.size.sm};
white-space: nowrap;
`;
return {
itemBottom: itemStyles,
itemRight: cx(
itemStyles,
css`
margin-bottom: ${theme.spacing.xs};
`
),
rightWrapper: css`
padding-left: ${theme.spacing.sm};
`,
bottomWrapper: css`
display: flex;
flex-wrap: wrap;
justify-content: space-between;
width: 100%;
padding-left: ${theme.spacing.md};
`,
section: css`
display: flex;
`,
sectionRight: css`
justify-content: flex-end;
flex-grow: 1;
`,
};
};