EdgeLabel.tsx 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. import { css } from '@emotion/css';
  2. import React, { memo } from 'react';
  3. import { GrafanaTheme2 } from '@grafana/data';
  4. import { useStyles2 } from '@grafana/ui';
  5. import { EdgeDatum, NodeDatum } from './types';
  6. import { shortenLine } from './utils';
  7. const getStyles = (theme: GrafanaTheme2) => {
  8. return {
  9. mainGroup: css`
  10. pointer-events: none;
  11. font-size: 8px;
  12. `,
  13. background: css`
  14. fill: ${theme.components.tooltip.background};
  15. `,
  16. text: css`
  17. fill: ${theme.components.tooltip.text};
  18. `,
  19. };
  20. };
  21. interface Props {
  22. edge: EdgeDatum;
  23. }
  24. export const EdgeLabel = memo(function EdgeLabel(props: Props) {
  25. const { edge } = props;
  26. // Not great typing but after we do layout these properties are full objects not just references
  27. const { source, target } = edge as { source: NodeDatum; target: NodeDatum };
  28. // As the nodes have some radius we want edges to end outside of the node circle.
  29. const line = shortenLine(
  30. {
  31. x1: source.x!,
  32. y1: source.y!,
  33. x2: target.x!,
  34. y2: target.y!,
  35. },
  36. 90
  37. );
  38. const middle = {
  39. x: line.x1 + (line.x2 - line.x1) / 2,
  40. y: line.y1 + (line.y2 - line.y1) / 2,
  41. };
  42. const styles = useStyles2(getStyles);
  43. return (
  44. <g className={styles.mainGroup}>
  45. <rect className={styles.background} x={middle.x - 40} y={middle.y - 15} width="80" height="30" rx="5" />
  46. <text className={styles.text} x={middle.x} y={middle.y - 5} textAnchor={'middle'}>
  47. {edge.mainStat}
  48. </text>
  49. <text className={styles.text} x={middle.x} y={middle.y + 10} textAnchor={'middle'}>
  50. {edge.secondaryStat}
  51. </text>
  52. </g>
  53. );
  54. });