IconPanel.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import React, { Component } from 'react';
  2. import { PanelProps } from '@grafana/data';
  3. import { HorizontalConstraint, VerticalConstraint } from 'app/features/canvas';
  4. import { iconItem } from 'app/features/canvas/elements/icon';
  5. import { ElementState } from 'app/features/canvas/runtime/element';
  6. import {
  7. ColorDimensionConfig,
  8. DimensionContext,
  9. getColorDimensionFromData,
  10. getResourceDimensionFromData,
  11. getScalarDimensionFromData,
  12. getScaleDimensionFromData,
  13. getTextDimensionFromData,
  14. ResourceDimensionConfig,
  15. ScalarDimensionConfig,
  16. ScaleDimensionConfig,
  17. TextDimensionConfig,
  18. } from 'app/features/dimensions';
  19. import { PanelOptions } from './models.gen';
  20. interface Props extends PanelProps<PanelOptions> {}
  21. export class IconPanel extends Component<Props> {
  22. private element: ElementState;
  23. constructor(props: Props) {
  24. super(props);
  25. this.element = this.initElement(props);
  26. }
  27. initElement = (props: Props) => {
  28. this.element = new ElementState(iconItem, props.options.root as any);
  29. this.updateSize(props);
  30. this.element.updateData(this.dims);
  31. return this.element;
  32. };
  33. updateSize = (props: Props) => {
  34. const { width, height } = props;
  35. this.element.options.constraint = {
  36. vertical: VerticalConstraint.Top,
  37. horizontal: HorizontalConstraint.Left,
  38. };
  39. this.element.options.placement = {
  40. left: 0,
  41. top: 0,
  42. width,
  43. height,
  44. };
  45. };
  46. dims: DimensionContext = {
  47. getColor: (color: ColorDimensionConfig) => getColorDimensionFromData(this.props.data, color),
  48. getScale: (scale: ScaleDimensionConfig) => getScaleDimensionFromData(this.props.data, scale),
  49. getScalar: (scalar: ScalarDimensionConfig) => getScalarDimensionFromData(this.props.data, scalar),
  50. getText: (text: TextDimensionConfig) => getTextDimensionFromData(this.props.data, text),
  51. getResource: (res: ResourceDimensionConfig) => getResourceDimensionFromData(this.props.data, res),
  52. };
  53. shouldComponentUpdate(nextProps: Props) {
  54. const { width, height, data } = this.props;
  55. let changed = false;
  56. if (width !== nextProps.width || height !== nextProps.height) {
  57. this.updateSize(nextProps);
  58. changed = true;
  59. }
  60. if (data !== nextProps.data) {
  61. this.element.updateData(this.dims);
  62. changed = true;
  63. }
  64. // Reload the element when options change
  65. if (this.props.options?.root !== nextProps.options?.root) {
  66. this.initElement(nextProps);
  67. changed = true;
  68. }
  69. return changed;
  70. }
  71. render() {
  72. const { width, height } = this.props;
  73. return <div style={{ width, height, overflow: 'hidden', position: 'relative' }}>{this.element.render()}</div>;
  74. }
  75. }