Skip to content

Commit 3ef8282

Browse files
committed
new component
1 parent 495e378 commit 3ef8282

File tree

5 files changed

+241
-2
lines changed

5 files changed

+241
-2
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ so that they would be usable in web-component-designer: https://node-projects.gi
1313

1414
- node-projects-double-gauge -> a port of https://github.com/boonzaai/doublegauge
1515
- node-projects-css-gauge -> a port of https://github.com/rotvalli/css-gauge
16+
- node-projects-material-gauge -> a port of https://github.com/sathomas/material-gauge
1617
- node-projects-gauge-js -> (WIP) a port of https://github.com/bernii/gauge.js to typescript and a webcomponent
1718
- node-projects-canvas-gauges -> (WIP) a port of https://github.com/Mikhus/canvas-gauges
1819

@@ -22,6 +23,6 @@ you could import every single component explictly, or all at once.
2223

2324
# todo look if we also integrate:
2425
(maybe some only as a wraper (if they are still maintained))
25-
- https://github.com/sathomas/material-gauge
26+
2627
- https://github.com/naikus/svg-gauge ??
2728
- https://github.com/JohnrBell/Gauge_CSS

custom-elements.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,46 @@
103103
}
104104
}
105105
]
106+
},
107+
{
108+
"kind": "javascript-module",
109+
"path": "dist/material-gauge/MaterialGaugeComponent.js",
110+
"declarations": [
111+
{
112+
"kind": "class",
113+
"name": "MaterialGaugeComponent",
114+
"members": [
115+
{
116+
"kind": "field",
117+
"name": "value",
118+
"type": {
119+
"text": "number"
120+
}
121+
}
122+
],
123+
"attributes": [
124+
{
125+
"name": "value",
126+
"fieldName": "value"
127+
}
128+
],
129+
"superclass": {
130+
"name": "BaseCustomWebComponentConstructorAppend"
131+
},
132+
"tagName": "node-projects-material-gauge",
133+
"customElement": true
134+
}
135+
],
136+
"exports": [
137+
{
138+
"kind": "custom-element-definition",
139+
"name": "node-projects-material-gauge",
140+
"declaration": {
141+
"name": "MaterialGaugeComponent",
142+
"module": "dist/material-gauge/MaterialGaugeComponent.js"
143+
}
144+
}
145+
]
106146
}
107147
]
108148
}

sample/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<node-projects-css-gauge value="50" display-value="75" style="width: 300px; height: 300px;"></node-projects-css-gauge>
2525
<node-projects-css-gauge type="glossy" value="80" display-value="30" style="width: 300px; height: 300px;"></node-projects-css-gauge>
2626
<node-projects-double-gauge left-value="50" right-value="25" style="width: 300px; height: 300px;"></node-projects-double-gauge>
27+
<node-projects-material-gauge style="width: 300px; height: 300px;"></node-projects-material-gauge>
2728
</div>
2829
</body>
2930
</html>

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './gauge-js/GaugeJsComponent.js'
22
export * from './css-gauge/CssGaugeComponent.js'
3-
export * from './double-gauge/DoubleGaugeComponent.js'
3+
export * from './double-gauge/DoubleGaugeComponent.js'
4+
export * from './material-gauge/MaterialGaugeComponent.js'
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
import { BaseCustomWebComponentConstructorAppend, css, html } from "@node-projects/base-custom-webcomponent";
2+
3+
export class MaterialGaugeComponent extends BaseCustomWebComponentConstructorAppend {
4+
5+
static override readonly style = css`
6+
.gauge {
7+
position: relative;
8+
}
9+
10+
.gauge__container {
11+
margin: 0;
12+
padding: 0;
13+
position: absolute;
14+
left: 50%;
15+
overflow: hidden;
16+
text-align: center;
17+
transform: translateX(-50%);
18+
}
19+
20+
.gauge__background {
21+
z-index: 0;
22+
position: absolute;
23+
background-color: #C5CAE9;
24+
top: 0;
25+
border-radius: 300px 300px 0 0;
26+
}
27+
28+
.gauge__data {
29+
z-index: 1;
30+
position: absolute;
31+
background-color: #3F51B5;
32+
margin-left: auto;
33+
margin-right: auto;
34+
border-radius: 300px 300px 0 0;
35+
transform-origin: center bottom;
36+
}
37+
38+
.gauge__center {
39+
z-index: 2;
40+
position: absolute;
41+
background-color: #fff;
42+
margin-right: auto;
43+
border-radius: 300px 300px 0 0;
44+
}
45+
46+
.gauge__marker {
47+
z-index: 3;
48+
background-color: #fff;
49+
position: absolute;
50+
width: 1px;
51+
}
52+
53+
.gauge__needle {
54+
z-index: 4;
55+
background-color: #E91E63;
56+
height: 3px;
57+
position: absolute;
58+
transform-origin: left center;
59+
}
60+
61+
.gauge__labels {
62+
display: table;
63+
margin: 0 auto;
64+
position: relative;
65+
}
66+
67+
.gauge__label--low {
68+
display: table-cell;
69+
text-align: center;
70+
}
71+
72+
.gauge__label--spacer {
73+
display: table-cell;
74+
}
75+
76+
.gauge__label--high {
77+
display: table-cell;
78+
text-align: center;
79+
}
80+
81+
/*
82+
* Now define the rules that depend on the size of
83+
* the gauge. We start with sizing for a small mobile
84+
* device.
85+
*/
86+
87+
.gauge { height: calc(120px + 3em); }
88+
.gauge__container { width: 240px; height: 120px; }
89+
.gauge__marker { height: 120px; left: 119.5px; }
90+
.gauge__background { width: 240px; height: 120px; }
91+
.gauge__center { width: 144px; height: 72px; top: 48px; margin-left: 48px; }
92+
.gauge__data { width: 240px; height: 120px; }
93+
.gauge__needle { left: 120px; top: 117px; width: 120px; }
94+
.gauge__labels { top: 120px; width: 240px; }
95+
.gauge__label--low { width: 48px; }
96+
.gauge__label--spacer { width: 144px; }
97+
.gauge__label--high { width: 48px; }
98+
99+
/*
100+
* Increase the gauge size slightly on larger viewports.
101+
*/
102+
103+
@media only screen and (min-width: 400px) {
104+
.gauge { height: calc(150px + 3em); }
105+
.gauge__container { width: 300px; height: 150px; }
106+
.gauge__marker { height: 150px; left: 149.5px; }
107+
.gauge__background { width: 300px; height: 150px; }
108+
.gauge__center { width: 180px; height: 90px; top: 60px; margin-left: 60px; }
109+
.gauge__data { width: 300px; height: 150px; }
110+
.gauge__needle { left: 150px; top: 147px; width: 150px; }
111+
.gauge__labels { top: 150px; width: 300px; }
112+
.gauge__label--low { width: 60px; }
113+
.gauge__label--spacer { width: 180px; }
114+
.gauge__label--high { width: 60px; }
115+
}
116+
117+
/*
118+
* As an option, the 'gauge--liveupdate' class can be added
119+
* to the main gauge element. When this class is present,
120+
* we add a transition that animates any changes to the gauge
121+
* value. Currently, the app does not use this option because
122+
* all the inputs that can change gauge values are present
123+
* on tab panels that are different from the gauge itself.
124+
* Therefore, users won't be able to see any gauge changes
125+
* when they make input changes. The code is available, though,
126+
* should this change.
127+
*/
128+
129+
.gauge--liveupdate .gauge__data,
130+
.gauge--liveupdate .gauge__needle {
131+
transition: all 1s ease-in-out;
132+
}
133+
134+
/*
135+
* For a given gauge value, x, ranging from 0.0 to 1.0, set
136+
* the 'transform: rotate()' property according to the
137+
* following equation: '-0.5 + 0.5x turns' The default
138+
* properties below represent an x value of 0.
139+
*/
140+
141+
.gauge__data {
142+
transform: rotate(-.50turn);
143+
}
144+
.gauge__needle {
145+
-transform: rotate(-.50turn);
146+
}`;
147+
148+
static override readonly template = html`
149+
<div class="gauge gauge--liveupdate" id="gauge">
150+
<div class="gauge__container">
151+
<div class="gauge__marker"></div>
152+
<div class="gauge__background"></div>
153+
<div class="gauge__center"></div>
154+
<div id="gauge__data" class="gauge__data"></div>
155+
<div id="gauge__needle" class="gauge__needle"></div>
156+
</div>
157+
<div class="gauge__labels mdl-typography__headline">
158+
<span class="gauge__label--low">No</span>
159+
<span class="gauge__label--spacer"></span>
160+
<span class="gauge__label--high">Yes</span>
161+
</div>
162+
</div>`;
163+
164+
static readonly is = "node-projects-material-gauge";
165+
166+
static readonly properties = {
167+
value: Number
168+
}
169+
170+
private _data: HTMLDivElement;
171+
private _needle: HTMLDivElement;
172+
173+
constructor() {
174+
super();
175+
this._restoreCachedInititalValues();
176+
this._data = this._getDomElement<HTMLDivElement>('gauge__data');
177+
this._needle = this._getDomElement<HTMLDivElement>('gauge__needle');
178+
}
179+
180+
ready() {
181+
this._parseAttributesToProperties();
182+
this.refresh();
183+
}
184+
185+
private _value: number = 0.0;
186+
get value() { return this._value; }
187+
set value(value: number) { this._value = value; this.refresh(); }
188+
189+
refresh() {
190+
const turns = -0.5 + (this._value * 0.5);
191+
this._data.style.transform = "rotate(" + turns + "turn)";
192+
this._needle.style.transform = "rotate(" + turns + "turn)";
193+
}
194+
}
195+
196+
customElements.define(MaterialGaugeComponent.is, MaterialGaugeComponent);

0 commit comments

Comments
 (0)