1+ <script setup>
2+ import { ref , computed , onMounted } from " vue" ;
3+ import { useConfig } from " ../useConfig" ;
4+ import { createUid , error , objectIsEmpty , shiftHue } from " ../lib" ;
5+ import { useNestedProp } from " ../useNestedProp" ;
6+
7+ const { vue_ui_gizmo: DEFAULT_CONFIG } = useConfig ();
8+
9+ const props = defineProps ({
10+ config: {
11+ type: Object ,
12+ default () {
13+ return {}
14+ }
15+ },
16+ dataset: {
17+ type: Number ,
18+ default: 0
19+ },
20+ });
21+
22+ const uid = ref (createUid ());
23+
24+ onMounted (() => {
25+ if (! props .dataset && props .dataset !== 0 ) {
26+ error ({
27+ componentName: ' VueUiGizmo' ,
28+ type: ' dataset'
29+ })
30+ }
31+ if (props .dataset < 0 ) {
32+ console .warn (' VueUiGizmo: dataset cannot be negative.' )
33+ }
34+ });
35+
36+ const FINAL_CONFIG = computed (() => {
37+ return useNestedProp ({
38+ userConfig: props .config ,
39+ defaultConfig: DEFAULT_CONFIG
40+ })
41+ })
42+
43+ const svg = computed (() => {
44+ const options = {
45+ battery: { width: FINAL_CONFIG .value .showPercentage ? 140 : 80 , height: 50 },
46+ gauge: { width: 80 , height: 80 },
47+ }
48+ return options[FINAL_CONFIG .value .type ];
49+ });
50+
51+ const barBody = computed (() => {
52+ const x = 70 * (props .dataset / 100 )
53+ return ` M 5 10 L 5 10 C 5 13 7 15 10 15 L ${ x} 15 C ${ x + 3 } 15 ${ x + 5 } 13 ${ x + 5 } 10 L ${ x + 5 } 10 C ${ x + 5 } 7 ${ x + 3 } 5 ${ x} 5 L 10 5 C 7 5 5 7 5 10`
54+ })
55+
56+ const gaugeBody = computed (() => {
57+ const circumference = 35 * (2 + (props .dataset / 100 > 1 ? 0 : 1 - props .dataset / 100 )) * Math .PI ;
58+ return {
59+ dasharray: ` ${ circumference} ${ circumference} ` ,
60+ dashoffset: circumference - props .dataset / 100 * circumference,
61+ }
62+ })
63+
64+ </script >
65+
66+ <template >
67+ <svg
68+ class =" vue-ui-gizmo"
69+ :viewBox =" `0 0 ${svg.width} ${svg.height}`"
70+ :width =" FINAL_CONFIG.size"
71+ :style =" {
72+ background: 'transparent',
73+ fontFamily: FINAL_CONFIG.fontFamily
74+ }"
75+ >
76+ <defs v-if =" FINAL_CONFIG.useGradient" >
77+ <linearGradient :id =" `gizmo_gradient_${uid}`" x1 =" 0%" x2 =" 100%" y1 =" 0%" y2 =" 0%" >
78+ <stop offset =" 0%" :stop-color =" FINAL_CONFIG.gradientColor" />
79+ <stop offset =" 100%" :stop-color =" FINAL_CONFIG.color" />
80+ </linearGradient >
81+ </defs >
82+
83+ <!-- BATTERY -->
84+ <template v-if =" FINAL_CONFIG .type === ' battery' " >
85+ <path
86+ d =" M 5 10 L 5 40 C 5 43 7 45 9 45 L 65 45 C 68 45 70 43 70 40 L 70 38 C 73 38 75 38 75 33 L 75 17 C 75 12 73 12 70 12 L 70 10 C 70 7 68 5 65 5 L 10 5 C 7 5 5 7 5 10"
87+ :stroke =" FINAL_CONFIG.stroke"
88+ :stroke-width =" 2"
89+ fill =" none"
90+ />
91+ <path
92+ d =" M 70 16 L 70 34"
93+ :stroke =" FINAL_CONFIG.stroke"
94+ :stroke-width =" 2"
95+ fill =" none"
96+ style =" opacity : 0.5 "
97+ />
98+ <rect
99+ :x =" 10"
100+ :y =" 10"
101+ :height =" 30"
102+ :width =" 55 * (dataset / 100)"
103+ :fill =" FINAL_CONFIG.useGradient ? `url(#gizmo_gradient_${uid})`: FINAL_CONFIG.color"
104+ :rx =" 2"
105+ />
106+ <text
107+ v-if =" FINAL_CONFIG.showPercentage"
108+ :x =" 85"
109+ :y =" 32"
110+ text-anchor =" start"
111+ font-size =" 20"
112+ :fill =" FINAL_CONFIG.textColor"
113+ >
114+ {{ Math.round(props.dataset) }}%
115+ </text >
116+ </template >
117+
118+ <!-- GAUGE -->
119+ <template v-if =" FINAL_CONFIG .type === ' gauge' " >
120+ <defs v-if =" FINAL_CONFIG.useGradient" >
121+ <filter :id =" `blur_${uid}`" x =" -50%" y =" -50%" width =" 200%" height =" 200%" >
122+ <feGaussianBlur in =" SourceGraphic" :stdDeviation =" 1" />
123+ </filter >
124+ </defs >
125+ <circle
126+ :cx =" 40"
127+ :cy =" 40"
128+ :r =" 35"
129+ :stroke =" FINAL_CONFIG.stroke"
130+ :stroke-width =" 2 * 4"
131+ fill =" none"
132+ />
133+ <circle
134+ :cx =" 40"
135+ :cy =" 40"
136+ :r =" 35"
137+ :stroke =" FINAL_CONFIG.color"
138+ :stroke-width =" 2 * 4"
139+ :stroke-dasharray =" gaugeBody.dasharray"
140+ :stroke-dashoffset =" gaugeBody.dashoffset"
141+ stroke-linecap =" round"
142+ fill =" none"
143+ style =" transform :rotate (-90deg );transform-origin : 50% 50% "
144+ />
145+ <g v-if =" FINAL_CONFIG.useGradient" :filter =" `url(#blur_${uid})`" >
146+ <circle
147+ :cx =" 40"
148+ :cy =" 40"
149+ :r =" 35"
150+ :stroke =" FINAL_CONFIG.gradientColor"
151+ :stroke-width =" 1"
152+ fill =" none"
153+ :stroke-dasharray =" gaugeBody.dasharray"
154+ :stroke-dashoffset =" gaugeBody.dashoffset"
155+ style =" transform :rotate (-90deg );transform-origin : 50% 50% "
156+ />
157+ </g >
158+ <text
159+ v-if =" FINAL_CONFIG.showPercentage"
160+ :x =" 40"
161+ :y =" 47"
162+ text-anchor =" middle"
163+ font-size =" 20"
164+ :fill =" FINAL_CONFIG.textColor"
165+ >
166+ {{ Math.round(props.dataset) }}%
167+ </text >
168+ </template >
169+ </svg >
170+ </template >
0 commit comments