123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- import { css } from '@emotion/css';
- import React from 'react';
- import { connect, ConnectedProps } from 'react-redux';
- import { useToggle } from 'react-use';
- import { applyFieldOverrides, DataFrame, GrafanaTheme2 } from '@grafana/data';
- import { reportInteraction } from '@grafana/runtime';
- import { Badge, Collapse, useStyles2, useTheme2 } from '@grafana/ui';
- import { NodeGraph } from '../../plugins/panel/nodeGraph';
- import { useCategorizeFrames } from '../../plugins/panel/nodeGraph/useCategorizeFrames';
- import { ExploreId, StoreState } from '../../types';
- import { splitOpen } from './state/main';
- import { useLinks } from './utils/links';
- const getStyles = (theme: GrafanaTheme2) => ({
- warningText: css`
- label: warningText;
- font-size: ${theme.typography.bodySmall.fontSize};
- color: ${theme.colors.text.secondary};
- `,
- });
- interface OwnProps {
- // Edges and Nodes are separate frames
- dataFrames: DataFrame[];
- exploreId: ExploreId;
- // When showing the node graph together with trace view we do some changes so it works better.
- withTraceView?: boolean;
- datasourceType: string;
- }
- type Props = OwnProps & ConnectedProps<typeof connector>;
- export function UnconnectedNodeGraphContainer(props: Props) {
- const { dataFrames, range, splitOpen, withTraceView, datasourceType } = props;
- const getLinks = useLinks(range, splitOpen);
- const theme = useTheme2();
- const styles = useStyles2(getStyles);
- // This is implicit dependency that is needed for links to work. At some point when replacing variables in the link
- // it requires field to have a display property which is added by the overrides even though we don't add any field
- // overrides in explore.
- const frames = applyFieldOverrides({
- fieldConfig: {
- defaults: {},
- overrides: [],
- },
- data: dataFrames,
- // We don't need proper replace here as it is only used in getLinks and we use getFieldLinks
- replaceVariables: (value) => value,
- theme,
- });
- const { nodes } = useCategorizeFrames(frames);
- const [open, toggleOpen] = useToggle(false);
- const toggled = () => {
- toggleOpen();
- reportInteraction('grafana_traces_node_graph_panel_clicked', {
- datasourceType: datasourceType,
- expanded: !open,
- });
- };
- const countWarning =
- withTraceView && nodes[0]?.length > 1000 ? (
- <span className={styles.warningText}> ({nodes[0].length} nodes, can be slow to load)</span>
- ) : null;
- return (
- <Collapse
- label={
- <span>
- Node graph{countWarning}{' '}
- <Badge text={'Beta'} color={'blue'} icon={'rocket'} tooltip={'This visualization is in beta'} />
- </span>
- }
- collapsible={withTraceView}
- // We allow collapsing this only when it is shown together with trace view.
- isOpen={withTraceView ? open : true}
- onToggle={withTraceView ? () => toggled() : undefined}
- >
- <div style={{ height: withTraceView ? 500 : 600 }}>
- <NodeGraph dataFrames={frames} getLinks={getLinks} />
- </div>
- </Collapse>
- );
- }
- function mapStateToProps(state: StoreState, { exploreId }: OwnProps) {
- return {
- range: state.explore[exploreId]!.range,
- };
- }
- const mapDispatchToProps = {
- splitOpen,
- };
- const connector = connect(mapStateToProps, mapDispatchToProps);
- export const NodeGraphContainer = connector(UnconnectedNodeGraphContainer);
|