@opstel/modern-gauges 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -32
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +44 -42
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,6 @@ An animated half-circle SVG gauge component for React. Zero runtime dependencies
|
|
|
8
8
|
- Gradient color progression across the arc and tick marks
|
|
9
9
|
- Automatically generated minor tick marks between major labels
|
|
10
10
|
- Responsive — fills its container via SVG `viewBox`
|
|
11
|
-
- Optional card wrapper with shadow, or render bare into any layout
|
|
12
11
|
|
|
13
12
|
## Installation
|
|
14
13
|
|
|
@@ -25,7 +24,7 @@ function Dashboard() {
|
|
|
25
24
|
return (
|
|
26
25
|
<HalfGauge
|
|
27
26
|
value={72}
|
|
28
|
-
|
|
27
|
+
minMax={[0, 20, 40, 60, 80, 100]}
|
|
29
28
|
colors={['#f44336', '#ffeb3b', '#4caf50']}
|
|
30
29
|
title="CPU (%)"
|
|
31
30
|
/>
|
|
@@ -38,12 +37,9 @@ function Dashboard() {
|
|
|
38
37
|
| Prop | Type | Default | Description |
|
|
39
38
|
|---|---|---|---|
|
|
40
39
|
| `value` | `number` | — | Current value to display |
|
|
41
|
-
| `
|
|
40
|
+
| `minMax` | `number[]` | `[0, 5, 10, 15, 20]` | Ordered scale values. First = min, last = max. Labels are rendered at each value; minor ticks are inserted automatically between them. |
|
|
42
41
|
| `colors` | `string[]` | `['#f44336', '#9c27b0']` | Two or more CSS colors forming the gradient from min to max. |
|
|
43
42
|
| `title` | `string` | — | Optional label displayed below the value |
|
|
44
|
-
| `withoutBackground` | `boolean` | `false` | When `true`, renders only the gauge SVG with no card wrapper. Use this when embedding inside your own container. |
|
|
45
|
-
| `className` | `string` | — | CSS class applied to the card wrapper (ignored when `withoutBackground` is true) |
|
|
46
|
-
| `style` | `object` | — | Inline styles merged into the card wrapper (ignored when `withoutBackground` is true) |
|
|
47
43
|
|
|
48
44
|
## Examples
|
|
49
45
|
|
|
@@ -58,39 +54,15 @@ function Dashboard() {
|
|
|
58
54
|
```jsx
|
|
59
55
|
<HalfGauge
|
|
60
56
|
value={3500}
|
|
61
|
-
|
|
57
|
+
minMax={[0, 1000, 2000, 3000, 4000, 5000, 6000]}
|
|
62
58
|
colors={['#4caf50', '#ffeb3b', '#f44336']}
|
|
63
59
|
title="RPM"
|
|
64
60
|
/>
|
|
65
61
|
```
|
|
66
62
|
|
|
67
|
-
### Embedded in a custom container (no card)
|
|
68
|
-
|
|
69
|
-
```jsx
|
|
70
|
-
<div style={{ width: 200, height: 130 }}>
|
|
71
|
-
<HalfGauge
|
|
72
|
-
value={55}
|
|
73
|
-
ticks={[0, 25, 50, 75, 100]}
|
|
74
|
-
colors={['#2196f3', '#e91e63']}
|
|
75
|
-
withoutBackground
|
|
76
|
-
/>
|
|
77
|
-
</div>
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
### Custom card size via style prop
|
|
81
|
-
|
|
82
|
-
```jsx
|
|
83
|
-
<HalfGauge
|
|
84
|
-
value={8}
|
|
85
|
-
ticks={[0, 2, 4, 6, 8, 10]}
|
|
86
|
-
title="Score"
|
|
87
|
-
style={{ width: '12rem', height: '10rem', flexGrow: 0 }}
|
|
88
|
-
/>
|
|
89
|
-
```
|
|
90
|
-
|
|
91
63
|
## Tick behaviour
|
|
92
64
|
|
|
93
|
-
The `
|
|
65
|
+
The `minMax` array defines where major labels appear. Minor ticks are inserted automatically:
|
|
94
66
|
|
|
95
67
|
- **≤ 5 major ticks** → 4 minor ticks per gap
|
|
96
68
|
- **6–16 major ticks** → 2 minor ticks per gap
|
package/dist/index.cjs.js
CHANGED
|
@@ -14,4 +14,4 @@
|
|
|
14
14
|
animation: modern-gauge-fill-tick 1s ease-out forwards;
|
|
15
15
|
animation-delay: var(--mg-tick-delay, 0s);
|
|
16
16
|
}
|
|
17
|
-
`,document.head.appendChild(o)})();const
|
|
17
|
+
`,document.head.appendChild(o)})();const W=({value:m,colors:a,title:o,minMax:f})=>{const n=f||[0,5,10,15,20],h=n.at(0)??0,Y=n.at(-1)??1,g=m??h,x=y.useRef(`mg-${Math.random().toString(36).substring(2,9)}`).current,p=y.useRef(h);y.useEffect(()=>{const e=setTimeout(()=>{p.current=g},1e3);return()=>clearTimeout(e)},[g]);const j=Y-h||1,b=Math.min(1,Math.max(0,(p.current-h)/j)),v=Math.min(1,Math.max(0,(g-h)/j)),M=Math.PI*40,L=v*M,w=b*M,S=n.length>8;let c=[];if(n.length<17){const e=n.length<6?4:2,i=e+1;for(let r=0;r<n.length;r++)if(c.push({value:n[r],isMajor:!0}),r<n.length-1){const d=n[r],l=(n[r+1]-d)/i;for(let u=1;u<=e;u++)c.push({value:d+u*l,isMajor:!1})}}else c=n.map(e=>({value:e,isMajor:!0}));const F=c.filter(e=>e.isMajor),X=c.map((e,i)=>{const r=c.length-1,s=(i/r*180-180)*(Math.PI/180),l=36,u=e.isMajor?5:2.5,I=F.indexOf(e),A=e.isMajor&&(!S||I%2===0),R=50+l*Math.cos(s),T=45+l*Math.sin(s),C=50+(l-u)*Math.cos(s),E=45+(l-u)*Math.sin(s),k=l-10,G=50+k*Math.cos(s),P=45+k*Math.sin(s);return{value:e.value,innerX:C,innerY:E,outerX:R,outerY:T,labelX:G,labelY:P,showLabel:A}}),$=a&&a.length>=2?a:["#f44336","#9c27b0"];return t.jsx("div",{style:{height:"100%",width:"100%"},children:t.jsxs("div",{style:{width:"100%",height:"100%",position:"relative"},children:[t.jsxs("svg",{width:"100%",height:"100%",viewBox:"0 0 100 55",children:[t.jsx("defs",{children:t.jsx("linearGradient",{id:`gradient-${x}`,gradientUnits:"userSpaceOnUse",x1:10,y1:45,x2:90,y2:45,children:$.map((e,i)=>t.jsx("stop",{offset:`${i/($.length-1)*100}%`,stopColor:e},i))})}),t.jsx("path",{stroke:"#9e9e9e",strokeWidth:"3",strokeLinecap:"round",fill:"none",d:"M 10 45 A 40 40 0 1 1 90 45"}),t.jsx("path",{className:"modern-gauge-arc",fill:"none",strokeWidth:"3",stroke:`url(#gradient-${x})`,strokeLinecap:"round",strokeDashoffset:"0",style:{"--mg-initial-dash":`${w}`,"--mg-final-dash":`${L}`},d:"M 10 45 A 40 40 0 1 1 90 45"}),X.map((e,i)=>{const r=i/(X.length-1),d=r<=v,s=r;return t.jsxs("g",{children:[t.jsx("line",{x1:e.innerX,y1:e.innerY,x2:e.outerX,y2:e.outerY,strokeWidth:"1",strokeLinecap:"round",stroke:"#9e9e9e"}),t.jsx("line",{className:"modern-gauge-tick",x1:e.innerX,y1:e.innerY,x2:e.outerX,y2:e.outerY,strokeWidth:"1",strokeLinecap:"round",style:{"--mg-tick-color":`url(#gradient-${x})`,"--mg-tick-delay":d?`${s}s`:"0s",animationPlayState:d?"running":"paused"}}),e.showLabel&&t.jsx("text",{x:e.labelX,y:e.labelY,textAnchor:"middle",dominantBaseline:"middle",fontSize:"5",fill:"#9e9e9e",fontFamily:"sans-serif",children:e.value})]},e.value)}),t.jsx("text",{x:50,y:40,textAnchor:"middle",dominantBaseline:"middle",fontSize:"14",fontWeight:"500",fill:"currentColor",fontFamily:"sans-serif",children:m})]}),o&&t.jsx("div",{style:{position:"absolute",bottom:0,width:"100%",textAlign:"center",fontSize:"0.9rem",color:"#9e9e9e",pointerEvents:"none"},children:o})]},g)})},B=({value:m,colors:a,title:o,minMax:f})=>t.jsx(W,{value:m,colors:a,title:o,minMax:f});exports.HalfGauge=B;
|
package/dist/index.es.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { jsx as t, jsxs as
|
|
2
|
-
import { useRef as
|
|
1
|
+
import { jsx as t, jsxs as x } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as b, useEffect as R } from "react";
|
|
3
3
|
(function() {
|
|
4
4
|
if (typeof document > "u") return;
|
|
5
5
|
const o = "__modern-half-gauge-styles__";
|
|
@@ -23,21 +23,21 @@ import { useRef as j, useEffect as V } from "react";
|
|
|
23
23
|
}
|
|
24
24
|
`, document.head.appendChild(s);
|
|
25
25
|
})();
|
|
26
|
-
const
|
|
27
|
-
const n =
|
|
28
|
-
|
|
26
|
+
const V = ({ value: m, colors: o, title: s, minMax: f }) => {
|
|
27
|
+
const n = f || [0, 5, 10, 15, 20], h = n.at(0) ?? 0, j = n.at(-1) ?? 1, g = m ?? h, y = b(`mg-${Math.random().toString(36).substring(2, 9)}`).current, p = b(h);
|
|
28
|
+
R(() => {
|
|
29
29
|
const e = setTimeout(() => {
|
|
30
|
-
|
|
30
|
+
p.current = g;
|
|
31
31
|
}, 1e3);
|
|
32
32
|
return () => clearTimeout(e);
|
|
33
33
|
}, [g]);
|
|
34
|
-
const v =
|
|
34
|
+
const v = j - h || 1, L = Math.min(
|
|
35
35
|
1,
|
|
36
|
-
Math.max(0, (
|
|
36
|
+
Math.max(0, (p.current - h) / v)
|
|
37
37
|
), M = Math.min(
|
|
38
38
|
1,
|
|
39
39
|
Math.max(0, (g - h) / v)
|
|
40
|
-
), X = Math.PI * 40, w = M * X,
|
|
40
|
+
), X = Math.PI * 40, w = M * X, F = L * X, I = n.length > 8;
|
|
41
41
|
let c = [];
|
|
42
42
|
if (n.length < 17) {
|
|
43
43
|
const e = n.length < 6 ? 4 : 2, i = e + 1;
|
|
@@ -49,25 +49,25 @@ const _ = ({ value: m, colors: o, title: s, minMax: p }) => {
|
|
|
49
49
|
}
|
|
50
50
|
} else
|
|
51
51
|
c = n.map((e) => ({ value: e, isMajor: !0 }));
|
|
52
|
-
const
|
|
53
|
-
const r = c.length - 1, a = (i / r * 180 - 180) * (Math.PI / 180), l = 36, u = e.isMajor ? 5 : 2.5,
|
|
52
|
+
const S = c.filter((e) => e.isMajor), $ = c.map((e, i) => {
|
|
53
|
+
const r = c.length - 1, a = (i / r * 180 - 180) * (Math.PI / 180), l = 36, u = e.isMajor ? 5 : 2.5, A = S.indexOf(e), C = e.isMajor && (!I || A % 2 === 0), E = 50 + l * Math.cos(a), T = 45 + l * Math.sin(a), W = 50 + (l - u) * Math.cos(a), B = 45 + (l - u) * Math.sin(a), Y = l - 10, G = 50 + Y * Math.cos(a), P = 45 + Y * Math.sin(a);
|
|
54
54
|
return {
|
|
55
55
|
value: e.value,
|
|
56
|
-
innerX:
|
|
57
|
-
innerY:
|
|
56
|
+
innerX: W,
|
|
57
|
+
innerY: B,
|
|
58
58
|
outerX: E,
|
|
59
|
-
outerY:
|
|
60
|
-
labelX:
|
|
61
|
-
labelY:
|
|
62
|
-
showLabel:
|
|
59
|
+
outerY: T,
|
|
60
|
+
labelX: G,
|
|
61
|
+
labelY: P,
|
|
62
|
+
showLabel: C
|
|
63
63
|
};
|
|
64
64
|
}), k = o && o.length >= 2 ? o : ["#f44336", "#9c27b0"];
|
|
65
|
-
return /* @__PURE__ */ t("div", { style: { height: "100%", width: "100%" }, children: /* @__PURE__ */
|
|
65
|
+
return /* @__PURE__ */ t("div", { style: { height: "100%", width: "100%" }, children: /* @__PURE__ */ x(
|
|
66
66
|
"div",
|
|
67
67
|
{
|
|
68
68
|
style: { width: "100%", height: "100%", position: "relative" },
|
|
69
69
|
children: [
|
|
70
|
-
/* @__PURE__ */
|
|
70
|
+
/* @__PURE__ */ x("svg", { width: "100%", height: "100%", viewBox: "0 0 100 55", children: [
|
|
71
71
|
/* @__PURE__ */ t("defs", { children: /* @__PURE__ */ t(
|
|
72
72
|
"linearGradient",
|
|
73
73
|
{
|
|
@@ -107,7 +107,7 @@ const _ = ({ value: m, colors: o, title: s, minMax: p }) => {
|
|
|
107
107
|
strokeLinecap: "round",
|
|
108
108
|
strokeDashoffset: "0",
|
|
109
109
|
style: {
|
|
110
|
-
"--mg-initial-dash": `${
|
|
110
|
+
"--mg-initial-dash": `${F}`,
|
|
111
111
|
"--mg-final-dash": `${w}`
|
|
112
112
|
},
|
|
113
113
|
d: "M 10 45 A 40 40 0 1 1 90 45"
|
|
@@ -115,7 +115,7 @@ const _ = ({ value: m, colors: o, title: s, minMax: p }) => {
|
|
|
115
115
|
),
|
|
116
116
|
$.map((e, i) => {
|
|
117
117
|
const r = i / ($.length - 1), d = r <= M, a = r;
|
|
118
|
-
return /* @__PURE__ */
|
|
118
|
+
return /* @__PURE__ */ x("g", { children: [
|
|
119
119
|
/* @__PURE__ */ t(
|
|
120
120
|
"line",
|
|
121
121
|
{
|
|
@@ -159,40 +159,42 @@ const _ = ({ value: m, colors: o, title: s, minMax: p }) => {
|
|
|
159
159
|
}
|
|
160
160
|
)
|
|
161
161
|
] }, e.value);
|
|
162
|
-
})
|
|
162
|
+
}),
|
|
163
|
+
/* @__PURE__ */ t(
|
|
164
|
+
"text",
|
|
165
|
+
{
|
|
166
|
+
x: 50,
|
|
167
|
+
y: 40,
|
|
168
|
+
textAnchor: "middle",
|
|
169
|
+
dominantBaseline: "middle",
|
|
170
|
+
fontSize: "14",
|
|
171
|
+
fontWeight: "500",
|
|
172
|
+
fill: "currentColor",
|
|
173
|
+
fontFamily: "sans-serif",
|
|
174
|
+
children: m
|
|
175
|
+
}
|
|
176
|
+
)
|
|
163
177
|
] }),
|
|
164
|
-
/* @__PURE__ */
|
|
178
|
+
s && /* @__PURE__ */ t(
|
|
165
179
|
"div",
|
|
166
180
|
{
|
|
167
181
|
style: {
|
|
168
182
|
position: "absolute",
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
transform: "translate(-50%, -50%)",
|
|
183
|
+
bottom: 0,
|
|
184
|
+
width: "100%",
|
|
172
185
|
textAlign: "center",
|
|
173
|
-
|
|
174
|
-
|
|
186
|
+
fontSize: "0.9rem",
|
|
187
|
+
color: "#9e9e9e",
|
|
188
|
+
pointerEvents: "none"
|
|
175
189
|
},
|
|
176
|
-
children:
|
|
177
|
-
/* @__PURE__ */ t("div", { style: { fontSize: "3rem", fontWeight: 500, lineHeight: 1.2 }, children: m }),
|
|
178
|
-
s && /* @__PURE__ */ t(
|
|
179
|
-
"div",
|
|
180
|
-
{
|
|
181
|
-
style: {
|
|
182
|
-
fontSize: "0.9rem",
|
|
183
|
-
marginTop: "4px"
|
|
184
|
-
},
|
|
185
|
-
children: s
|
|
186
|
-
}
|
|
187
|
-
)
|
|
188
|
-
]
|
|
190
|
+
children: s
|
|
189
191
|
}
|
|
190
192
|
)
|
|
191
193
|
]
|
|
192
194
|
},
|
|
193
195
|
g
|
|
194
196
|
) });
|
|
195
|
-
}, q = ({ value: m, colors: o, title: s, minMax:
|
|
197
|
+
}, q = ({ value: m, colors: o, title: s, minMax: f }) => /* @__PURE__ */ t(V, { value: m, colors: o, title: s, minMax: f });
|
|
196
198
|
export {
|
|
197
199
|
q as HalfGauge
|
|
198
200
|
};
|