windTurbine.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { css } from '@emotion/css';
  2. import React, { FC } from 'react';
  3. import { GrafanaTheme2 } from '@grafana/data';
  4. import { useStyles2 } from '@grafana/ui';
  5. import { DimensionContext, ScalarDimensionConfig } from 'app/features/dimensions';
  6. import { ScalarDimensionEditor } from 'app/features/dimensions/editors';
  7. import { CanvasElementItem, CanvasElementProps } from '../element';
  8. interface WindTurbineData {
  9. rpm?: number;
  10. }
  11. interface WindTurbineConfig {
  12. rpm?: ScalarDimensionConfig;
  13. }
  14. const WindTurbineDisplay: FC<CanvasElementProps<WindTurbineConfig, WindTurbineData>> = (props) => {
  15. const styles = useStyles2(getStyles);
  16. const { data } = props;
  17. const windTurbineAnimation = `spin ${data?.rpm ? 60 / Math.abs(data.rpm) : 0}s linear infinite`;
  18. return (
  19. <svg viewBox="0 0 189.326 283.989" preserveAspectRatio="xMidYMid meet">
  20. <symbol id="blade">
  21. <path
  22. fill="#e6e6e6"
  23. id="blade-front"
  24. d="M14.6491879,1.85011601 C14.2684455,-0.0535962877 10.7150812,-0.815081206 9.06473318,3.37308585 L0.434338747,70.7658933 L8.93805104,91.9607889 L15.4106729,90.437819 L17.5684455,78.3807425 L14.5218097,1.97679814 L14.6491879,1.85011601 Z"
  25. />
  26. <path
  27. fill="#d0d6d7"
  28. id="blade-side"
  29. d="M11.0951276,0.581206497 C10.3336427,0.961948956 9.57215777,1.85011601 8.93735499,3.24640371 L0.306960557,70.6392111 L8.81067285,91.8341067 L3.35359629,70.0044084 L11.0951276,0.581206497 Z"
  30. />
  31. </symbol>
  32. <g>
  33. <g id="structure" transform="translate(58.123, 82.664)" fillRule="nonzero">
  34. <polygon id="tower" fill="#e6e6e6" points="33.111,10.984 39.965,10.984 44.28,196.176 28.796,196.176" />
  35. <path
  36. id="yaw"
  37. fill="rgba(0,0,0,0.25)"
  38. d="M40.3454756,23.2948956 L40.7262181,34.8445476 C38.8225058,35.0986079 35.7765661,35.0986079 32.349884,34.337123 L32.7306265,23.2955916 L40.3454756,23.2955916 L40.3454756,23.2948956 Z"
  39. />
  40. <path
  41. id="base"
  42. fill="#d0d6d7"
  43. transform="translate(0 42)"
  44. d="M26.3846868,150.591647 L46.5640371,150.591647 C48.8484919,150.591647 50.7522042,152.49536 50.7522042,154.779814 L50.7522042,158.967981 L22.0691415,158.967981 L22.0691415,154.779814 C22.0691415,152.49536 23.9728538,150.591647 26.2573086,150.591647 L26.3846868,150.591647 Z"
  45. />
  46. <circle id="nacelle" fill="#e6e6e6" cx="36.54" cy="12" r="11.93" />
  47. <circle id="gearbox" fill="none" stroke="#d0d6d7" strokeWidth="2.75" cx="36.538" cy="11.999" r="5.8" />
  48. </g>
  49. <g className={styles.blade} style={{ animation: windTurbineAnimation }}>
  50. <use id="blade1" href="#blade" x="83.24" y="0" />
  51. <use id="blade2" href="#blade" x="83.24" y="0" transform="rotate(120 94.663 94.663)" />
  52. <use id="blade3" href="#blade" x="83.24" y="0" transform="rotate(-120 94.663 94.663)" />
  53. </g>
  54. </g>
  55. </svg>
  56. );
  57. };
  58. export const windTurbineItem: CanvasElementItem<any, any> = {
  59. id: 'windTurbine',
  60. name: 'Wind Turbine',
  61. description: 'Spinny spinny',
  62. display: WindTurbineDisplay,
  63. defaultSize: {
  64. width: 100,
  65. height: 100,
  66. },
  67. getNewOptions: (options) => ({
  68. ...options,
  69. }),
  70. // Called when data changes
  71. prepareData: (ctx: DimensionContext, cfg: WindTurbineConfig) => {
  72. const data: WindTurbineData = {
  73. rpm: cfg?.rpm ? ctx.getScalar(cfg.rpm).value() : 0,
  74. };
  75. return data;
  76. },
  77. registerOptionsUI: (builder) => {
  78. const category = ['Wind Turbine'];
  79. builder.addCustomEditor({
  80. category,
  81. id: 'rpm',
  82. path: 'config.rpm',
  83. name: 'RPM',
  84. editor: ScalarDimensionEditor,
  85. });
  86. },
  87. };
  88. const getStyles = (theme: GrafanaTheme2) => ({
  89. blade: css`
  90. @keyframes spin {
  91. from {
  92. transform: rotate(0deg);
  93. }
  94. to {
  95. transform: rotate(360deg);
  96. }
  97. }
  98. transform-origin: 94.663px 94.663px;
  99. transform: rotate(15deg);
  100. `,
  101. });