-
Notifications
You must be signed in to change notification settings - Fork 11.7k
/
windTurbine.tsx
135 lines (117 loc) · 4.61 KB
/
windTurbine.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import { css } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2, LinkModel } from '@grafana/data';
import { ScalarDimensionConfig } from '@grafana/schema';
import { useStyles2 } from '@grafana/ui';
import { DimensionContext } from 'app/features/dimensions';
import { ScalarDimensionEditor } from 'app/features/dimensions/editors';
import { getDataLinks } from 'app/plugins/panel/canvas/utils';
import { CanvasElementItem, CanvasElementOptions, CanvasElementProps, defaultBgColor } from '../element';
interface WindTurbineData {
rpm?: number;
links?: LinkModel[];
}
interface WindTurbineConfig {
rpm?: ScalarDimensionConfig;
}
const WindTurbineDisplay = ({ data }: CanvasElementProps<WindTurbineConfig, WindTurbineData>) => {
const styles = useStyles2(getStyles);
const windTurbineAnimation = `spin ${data?.rpm ? 60 / Math.abs(data.rpm) : 0}s linear infinite`;
return (
<svg viewBox="0 0 189.326 283.989" preserveAspectRatio="xMidYMid meet" style={{ fill: defaultBgColor }}>
<symbol id="blade">
<path
fill="#e6e6e6"
id="blade-front"
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"
/>
<path
fill="#d0d6d7"
id="blade-side"
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"
/>
</symbol>
<g>
<g id="structure" transform="translate(58.123, 82.664)" fillRule="nonzero">
<polygon id="tower" fill="#e6e6e6" points="33.111,10.984 39.965,10.984 44.28,196.176 28.796,196.176" />
<path
id="yaw"
fill="rgba(0,0,0,0.25)"
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"
/>
<path
id="base"
fill="#d0d6d7"
transform="translate(0 42)"
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"
/>
<circle id="nacelle" fill="#e6e6e6" cx="36.54" cy="12" r="11.93" />
<circle id="gearbox" fill="none" stroke="#d0d6d7" strokeWidth="2.75" cx="36.538" cy="11.999" r="5.8" />
</g>
<g className={styles.blade} style={{ animation: windTurbineAnimation }}>
<use id="blade1" href="#blade" x="83.24" y="0" />
<use id="blade2" href="#blade" x="83.24" y="0" transform="rotate(120 94.663 94.663)" />
<use id="blade3" href="#blade" x="83.24" y="0" transform="rotate(-120 94.663 94.663)" />
</g>
</g>
</svg>
);
};
export const windTurbineItem: CanvasElementItem = {
id: 'windTurbine',
name: 'Wind Turbine',
description: 'Spinny spinny',
display: WindTurbineDisplay,
defaultSize: {
width: 100,
height: 155,
},
getNewOptions: (options) => ({
...options,
background: {
color: {
fixed: 'transparent',
},
},
placement: {
width: options?.placement?.width ?? 100,
height: options?.placement?.height ?? 155,
top: options?.placement?.top,
left: options?.placement?.left,
rotation: options?.placement?.rotation ?? 0,
},
}),
// Called when data changes
prepareData: (dimensionContext: DimensionContext, elementOptions: CanvasElementOptions<WindTurbineConfig>) => {
const windTurbineConfig = elementOptions.config;
const data: WindTurbineData = {
rpm: windTurbineConfig?.rpm ? dimensionContext.getScalar(windTurbineConfig.rpm).value() : 0,
};
data.links = getDataLinks(dimensionContext, elementOptions, `${data.rpm}`);
return data;
},
registerOptionsUI: (builder) => {
const category = ['Wind Turbine'];
builder.addCustomEditor({
category,
id: 'rpm',
path: 'config.rpm',
name: 'RPM',
editor: ScalarDimensionEditor,
});
},
};
const getStyles = (theme: GrafanaTheme2) => ({
blade: css({
transformOrigin: '94.663px 94.663px',
transform: 'rotate(15deg)',
'@keyframes spin': {
from: {
transform: 'rotate(0deg)',
},
to: {
transform: 'rotate(360deg)',
},
},
}),
});