diff --git a/example/generator/plugin.js b/example/generator/plugin.js index 21f5a40d9e..8f820e16fd 100644 --- a/example/generator/plugin.js +++ b/example/generator/plugin.js @@ -81,7 +81,7 @@ define([ { name: "Amplitude", control: "numberfield", - cssClass: "l-input-sm l-numeric", + cssClass: "l-numeric", key: "amplitude", required: true, property: [ @@ -92,7 +92,7 @@ define([ { name: "Offset", control: "numberfield", - cssClass: "l-input-sm l-numeric", + cssClass: "l-numeric", key: "offset", required: true, property: [ diff --git a/src/plugins/gauge/GaugePluginSpec.js b/src/plugins/gauge/GaugePluginSpec.js index 0c6b3d7a1f..601c2bc7ff 100644 --- a/src/plugins/gauge/GaugePluginSpec.js +++ b/src/plugins/gauge/GaugePluginSpec.js @@ -472,7 +472,7 @@ describe('Gauge plugin', () => { it('renders major elements', () => { const wrapperElement = gaugeHolder.querySelector('.js-gauge-wrapper'); const rangeElement = gaugeHolder.querySelector('.js-gauge-meter-range'); - const valueElement = gaugeHolder.querySelector('.js-meter-current-value'); + const valueElement = gaugeHolder.querySelector('.js-gauge-current-value'); const hasMajorElements = Boolean(wrapperElement && rangeElement && valueElement); @@ -485,7 +485,7 @@ describe('Gauge plugin', () => { it('renders correct current value', (done) => { function WatchUpdateValue() { - const textElement = gaugeHolder.querySelector('.js-meter-current-value'); + const textElement = gaugeHolder.querySelector('.js-gauge-current-value'); expect(Number(textElement.textContent).toFixed(gaugeViewObject.configuration.gaugeController.precision)).toBe(randomValue.toFixed(gaugeViewObject.configuration.gaugeController.precision)); done(); } @@ -570,7 +570,7 @@ describe('Gauge plugin', () => { it('renders major elements', () => { const wrapperElement = gaugeHolder.querySelector('.js-gauge-wrapper'); const rangeElement = gaugeHolder.querySelector('.js-gauge-meter-range'); - const valueElement = gaugeHolder.querySelector('.js-meter-current-value'); + const valueElement = gaugeHolder.querySelector('.js-gauge-current-value'); const hasMajorElements = Boolean(wrapperElement && rangeElement && valueElement); diff --git a/src/plugins/gauge/components/Gauge.vue b/src/plugins/gauge/components/Gauge.vue index 5c1ed0f503..a9a1061068 100644 --- a/src/plugins/gauge/components/Gauge.vue +++ b/src/plugins/gauge/components/Gauge.vue @@ -23,189 +23,217 @@
@@ -219,9 +247,22 @@
{{ rangeLow }}
+
+ +
@@ -343,14 +390,28 @@ export default { dialLowLimitDeg() { return this.percentToDegrees(this.valToPercent(this.limitLow)); }, + meterOutOfRangeIndicatorAspectRatio() { + return this.typeMeterVertical ? 'xMidYMax meet' : 'xMinYMid meet'; + }, + meterTextBaseline() { + return this.typeMeterVertical ? 'auto' : 'middle'; + }, curValViewBox() { - const DIGITS_RATIO = 10; - const VIEWBOX_STR = '0 0 X 15'; + const DIGITS_RATIO = 3; + const VIEWBOX_STR = '0 0 X 10'; return VIEWBOX_STR.replace('X', this.digits * DIGITS_RATIO); }, + rangeFontSize() { + const CHAR_THRESHOLD = 3; + const START_PERC = 8.5; + const REDUCE_PERC = 0.8; + const RANGE_CHARS_MAX = Math.max(this.rangeLow.toString().length, this.rangeHigh.toString().length); + + return this.fontSizeFromChars(RANGE_CHARS_MAX, CHAR_THRESHOLD, START_PERC, REDUCE_PERC); + }, isDialLowLimit() { - return this.limitLow.length > 0 && this.dialLowLimitDeg < getLimitDegree('low', 'max'); + return this.limitLow.toString().length > 0 && this.dialLowLimitDeg < getLimitDegree('low', 'max'); }, isDialLowLimitLow() { return this.dialLowLimitDeg >= getLimitDegree('low', 'q1'); @@ -362,7 +423,7 @@ export default { return this.dialLowLimitDeg >= getLimitDegree('low', 'q3'); }, isDialHighLimit() { - return this.limitHigh.length > 0 && this.dialHighLimitDeg < getLimitDegree('high', 'max'); + return this.limitHigh.toString().length > 0 && this.dialHighLimitDeg < getLimitDegree('high', 'max'); }, isDialHighLimitLow() { return this.dialHighLimitDeg <= getLimitDegree('high', 'max'); @@ -383,10 +444,13 @@ export default { return this.degValue >= getLimitDegree('low', 'q3'); }, isMeterLimitHigh() { - return this.limitHigh.length > 0 && this.meterHighLimitPerc > 0; + return this.limitHigh.toString().length > 0 && this.meterHighLimitPerc > 0; }, isMeterLimitLow() { - return this.limitLow.length > 0 && this.meterLowLimitPerc > 0; + return this.limitLow.toString().length > 0 && this.meterLowLimitPerc > 0; + }, + gaugeTitle() { + return this.valueInBounds ? 'Gauge' : 'Value is currently out of range and cannot be graphically displayed'; }, typeDial() { return this.matchGaugeType('dial'); @@ -409,15 +473,25 @@ export default { typeMeterInverted() { return this.matchGaugeType('inverted'); }, + typeFilledMeter() { + return true; // Stubbing in for future capability + }, + typeNeedleMeter() { + return false; // Stubbing in for future capability + }, meterValueToPerc() { const meterDirection = (this.typeMeterInverted) ? -1 : 1; - if (this.curVal <= this.rangeLow) { - return meterDirection * 100; - } + if (this.typeFilledMeter) { + // Filled meter is a filled rectangle that is transformed along a vertical or horizontal axis + // So never move it below the low range more than 100%, or above the high range more than 0% + if (this.curVal <= this.rangeLow) { + return meterDirection * 100; + } - if (this.curVal >= this.rangeHigh) { - return 0; + if (this.curVal >= this.rangeHigh) { + return 0; + } } return this.valToPercentMeter(this.curVal) * meterDirection; @@ -428,6 +502,13 @@ export default { meterLowLimitPerc() { return 100 - this.valToPercentMeter(this.limitLow); }, + valueExpected() { + if (this.curVal === undefined || Object.is(this.curVal, 'null')) { + return false; + } + + return this.curVal.toString().indexOf(DEFAULT_CURRENT_VALUE) === -1; + }, valueInBounds() { return (this.curVal >= this.rangeLow && this.curVal <= this.rangeHigh); }, @@ -504,6 +585,11 @@ export default { ] }); }, + fontSizeFromChars(charNum, charThreshold, startPerc, reducePerc) { + const fs = (charNum <= charThreshold) ? startPerc : (startPerc - ((charNum - charThreshold) * reducePerc)); + + return fs.toString() + "%"; + }, matchGaugeType(str) { return this.gaugeType.indexOf(str) !== -1; }, diff --git a/src/plugins/gauge/gauge.scss b/src/plugins/gauge/gauge.scss index 3ce533a033..96b9efbbd3 100644 --- a/src/plugins/gauge/gauge.scss +++ b/src/plugins/gauge/gauge.scss @@ -1,3 +1,8 @@ +$meterNeedlePerc: 1%; +$meterNeedleMinPx: 4px; +$meterNeedleMaxPx: 20px; +$meterNeedleBorderRadius: 5px; + .is-object-type-gauge { overflow: hidden; } @@ -28,63 +33,64 @@ @include abs(); overflow: hidden; } + + &__current-value-text-wrapper { + // SVG + position: absolute; + height: 100%; + width: 100%; + } +} + +.c-dial__value-oor-indicator, +.c-meter__value-oor-indicator { + fill: $colorGaugeRange; + opacity: 0.5; } /********************************************** DIAL GAUGE */ -svg[class*='c-dial'] { +.c-dial { max-height: 100%; max-width: 100%; - position: absolute; - g { - transform-origin: center; - } -} - -.c-dial { &__bg { - background: $colorGaugeBg; - clip-path: url(#gaugeBgMask); + fill: $colorGaugeBg; } - - &__limit-high rect { fill: $colorGaugeLimitHigh; } - &__limit-low rect { fill: $colorGaugeLimitLow; } - - &__filled-value-wrapper { - clip-path: url(#gaugeValueMask); + &__limit-high rect { + fill: $colorGaugeLimitHigh; } - - &__needle-value-wrapper { - clip-path: url(#gaugeValueMask); + &__limit-low rect { + fill: $colorGaugeLimitLow; + } + &__filled-value, + &__range-msg-text { + fill: $colorGaugeValue; } - - &__filled-value { fill: $colorGaugeValue; } - &__needle-value { fill: $colorGaugeValue; - transition: transform $transitionTimeGauge; } - - &__current-value-text, - &__units-text { + &__current-value-text { fill: $colorGaugeTextValue; font-family: $heroFont; } + + &__units-text, + &__range-text { + fill: $colorGaugeRange; + } + + &__graphics g { + transform-origin: center; + } } /********************************************** METER GAUGE */ .c-meter { // Common styles for c-meter + $meterOutOfRangeIndicatorMaxSize: 50%; @include abs(); display: flex; - svg { - // current-value-text - position: absolute; - height: 100%; - width: 100%; - } - &__range { display: flex; flex: 0 0 auto; @@ -102,10 +108,42 @@ svg[class*='c-dial'] { // Filled area position: absolute; background: $colorGaugeValue; - transition: transform $transitionTimeGauge; z-index: 1; } + &__value-needle { + background: none !important; + &:before { + @include abs(); + content: ''; + display: block; + background: $colorGaugeValue; + } + } + + &__value-oor-indicator { + $mxPx: 50px; + $wh: 50%; + position: absolute; + height: $wh; + width: $wh; + max-height: $mxPx; + max-width: $mxPx; + + svg { + position: absolute; + width: 100%; + height: 100%; + max-height: 100%; + max-width: 100%; + } + } + + &__current-value-text { + fill: $colorGaugeTextValue; + font-family: $heroFont; + } + .c-gauge__curval { fill: $colorGaugeMeterTextValue !important; } @@ -142,10 +180,28 @@ svg[class*='c-dial'] { bottom: 0; } + &__value-needle { + right: 0; + + &:before { + border-bottom-left-radius: $meterNeedleBorderRadius; + border-top-left-radius: $meterNeedleBorderRadius; + height: $meterNeedlePerc; + min-height: $meterNeedleMinPx; + max-height: $meterNeedleMaxPx; + } + } + [class*='limit'] { left: 0; right: 0; } + + .c-meter__value-oor-indicator { + bottom: 10%; + left: 50%; + transform: translateX(-50%); + } } .c-gauge--meter-vertical & { @@ -156,6 +212,13 @@ svg[class*='c-dial'] { &__limit-high { top: 0; } + + &__value-needle { + &:before { + bottom: auto; + transform: translateY(-50%); + } + } } .c-gauge--meter-vertical-inverted & { @@ -174,6 +237,13 @@ svg[class*='c-dial'] { &__range__high { order: 2; } + + &__value-needle { + &:before { + top: auto; + transform: translateY(50%); + } + } } .c-gauge--meter-horizontal & { @@ -207,6 +277,20 @@ svg[class*='c-dial'] { right: 0; } + &__value-needle { + top: 0; + + &:before { + border-bottom-left-radius: $meterNeedleBorderRadius; + border-bottom-right-radius: $meterNeedleBorderRadius; + left: auto; + width: $meterNeedlePerc; + min-width: $meterNeedleMinPx; + max-width: $meterNeedleMaxPx; + transform: translateX(50%); + } + } + [class*='limit'] { top: 0; bottom: 0; @@ -219,5 +303,16 @@ svg[class*='c-dial'] { &__limit-high { right: 0; } + + .c-meter__value-oor-indicator { + // Horizontal meter + left: 2%; + top: 50%; + transform: translateY(-50%); + } } } +.svg-viewbox-debug { + fill: rgba(deeppink, 0.5); + display: none; +}