Browse Source

Merge branch 'master' into develop/3.2

pull/3477/head
Igor Kulikov 6 years ago
parent
commit
8c98f271fa
  1. 2
      application/src/main/resources/logback.xml
  2. 4
      application/src/main/resources/thingsboard.yml
  3. 15
      common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryStorage.java
  4. 2
      common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryTbQueueProducer.java
  5. 9
      common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java
  6. 2
      ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts
  7. 4
      ui-ngx/src/app/modules/home/components/widget/lib/analogue-compass.models.ts
  8. 2
      ui-ngx/src/app/modules/home/components/widget/lib/analogue-compass.ts
  9. 32
      ui-ngx/src/app/modules/home/components/widget/lib/analogue-gauge.models.ts
  10. 2
      ui-ngx/src/app/modules/home/components/widget/lib/analogue-linear-gauge.ts
  11. 2
      ui-ngx/src/app/modules/home/components/widget/lib/analogue-radial-gauge.ts
  12. 136
      ui-ngx/src/app/modules/home/components/widget/lib/canvas-digital-gauge.ts
  13. 8
      ui-ngx/src/app/modules/home/components/widget/lib/digital-gauge.models.ts
  14. 52
      ui-ngx/src/app/modules/home/components/widget/lib/digital-gauge.ts
  15. 4
      ui-ngx/src/app/modules/home/models/services.map.ts
  16. 2
      ui-ngx/src/app/modules/home/models/widget-component.models.ts
  17. 6
      ui-ngx/src/app/shared/models/ace/service-completion.models.ts

2
application/src/main/resources/logback.xml

@ -29,6 +29,8 @@
<!-- <logger name="org.thingsboard.server.service.queue" level="TRACE" />-->
<!-- <logger name="org.thingsboard.server.service.transport" level="TRACE" />-->
<!-- <logger name="org.thingsboard.server.queue.memory.InMemoryStorage" level="DEBUG" />-->
<!-- <logger name="org.thingsboard.server.service.subscription" level="TRACE"/>-->
<!-- <logger name="org.thingsboard.server.service.telemetry" level="TRACE"/>-->

4
application/src/main/resources/thingsboard.yml

@ -615,6 +615,10 @@ swagger:
queue:
type: "${TB_QUEUE_TYPE:in-memory}" # in-memory or kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ)
in_memory:
stats:
# For debug lvl
print-interval-ms: "${TB_QUEUE_IN_MEMORY_STATS_PRINT_INTERVAL_MS:60000}"
kafka:
bootstrap.servers: "${TB_KAFKA_SERVERS:localhost:9092}"
acks: "${TB_KAFKA_ACKS:all}"

15
common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryStorage.java

@ -23,27 +23,21 @@ import java.util.Collections;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Slf4j
public final class InMemoryStorage {
private static InMemoryStorage instance;
private final ConcurrentHashMap<String, BlockingQueue<TbQueueMsg>> storage;
private static ScheduledExecutorService statExecutor;
private InMemoryStorage() {
storage = new ConcurrentHashMap<>();
statExecutor = Executors.newSingleThreadScheduledExecutor();
statExecutor.scheduleAtFixedRate(this::printStats, 60, 60, TimeUnit.SECONDS);
}
private void printStats() {
public void printStats() {
storage.forEach((topic, queue) -> {
if (queue.size() > 0) {
log.debug("Topic: [{}], Queue size: [{}]", topic, queue.size());
log.debug("[{}] Queue Size [{}]", topic, queue.size());
}
});
}
@ -90,9 +84,4 @@ public final class InMemoryStorage {
storage.clear();
}
public void destroy() {
if (statExecutor != null) {
statExecutor.shutdownNow();
}
}
}

2
common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryTbQueueProducer.java

@ -53,6 +53,6 @@ public class InMemoryTbQueueProducer<T extends TbQueueMsg> implements TbQueuePro
@Override
public void stop() {
storage.destroy();
}
}

9
common/queue/src/main/java/org/thingsboard/server/queue/provider/InMemoryMonolithQueueFactory.java

@ -17,6 +17,7 @@ package org.thingsboard.server.queue.provider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.msg.queue.ServiceType;
import org.thingsboard.server.gen.js.JsInvokeProtos;
@ -28,6 +29,7 @@ import org.thingsboard.server.queue.common.TbProtoJsQueueMsg;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.memory.InMemoryStorage;
import org.thingsboard.server.queue.memory.InMemoryTbQueueConsumer;
import org.thingsboard.server.queue.memory.InMemoryTbQueueProducer;
import org.thingsboard.server.queue.settings.TbQueueCoreSettings;
@ -47,6 +49,7 @@ public class InMemoryMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE
private final TbQueueRuleEngineSettings ruleEngineSettings;
private final TbQueueTransportApiSettings transportApiSettings;
private final TbQueueTransportNotificationSettings transportNotificationSettings;
private final InMemoryStorage storage;
public InMemoryMonolithQueueFactory(PartitionService partitionService, TbQueueCoreSettings coreSettings,
TbQueueRuleEngineSettings ruleEngineSettings,
@ -59,6 +62,7 @@ public class InMemoryMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE
this.ruleEngineSettings = ruleEngineSettings;
this.transportApiSettings = transportApiSettings;
this.transportNotificationSettings = transportNotificationSettings;
this.storage = InMemoryStorage.getInstance();
}
@Override
@ -120,4 +124,9 @@ public class InMemoryMonolithQueueFactory implements TbCoreQueueFactory, TbRuleE
public TbQueueRequestTemplate<TbProtoJsQueueMsg<JsInvokeProtos.RemoteJsRequest>, TbProtoQueueMsg<JsInvokeProtos.RemoteJsResponse>> createRemoteJsRequestTemplate() {
return null;
}
@Scheduled(fixedRateString = "${queue.in_memory.stats.print-interval-ms:60000}")
private void printInMemoryStats() {
storage.printStats();
}
}

2
ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts

@ -41,6 +41,7 @@ import { CustomDialogService } from '@home/components/widget/dialog/custom-dialo
import { DatePipe } from '@angular/common';
import { TranslateService } from '@ngx-translate/core';
import { DomSanitizer } from '@angular/platform-browser';
import { Router } from '@angular/router';
@Directive()
export class DynamicWidgetComponent extends PageComponent implements IDynamicWidgetComponent, OnInit, OnDestroy {
@ -77,6 +78,7 @@ export class DynamicWidgetComponent extends PageComponent implements IDynamicWid
this.ctx.translate = $injector.get(TranslateService);
this.ctx.http = $injector.get(HttpClient);
this.ctx.sanitizer = $injector.get(DomSanitizer);
this.ctx.router = $injector.get(Router);
this.ctx.$scope = this;
if (this.ctx.defaultSubscription) {

4
ui-ngx/src/app/modules/home/components/widget/lib/analogue-compass.models.ts

@ -163,7 +163,7 @@ export const analogueCompassSettingsSchema: JsonSettingsSchema = {
form: [
{
key: 'majorTicks',
items:[
items: [
'majorTicks[]'
]
},
@ -267,7 +267,7 @@ export const analogueCompassSettingsSchema: JsonSettingsSchema = {
},
{
value: '700',
label: '800'
label: '700'
},
{
value: '800',

2
ui-ngx/src/app/modules/home/components/widget/lib/analogue-compass.ts

@ -43,7 +43,7 @@ export class TbAnalogueCompass extends TbBaseGauge<AnalogueCompassSettings, Radi
protected createGaugeOptions(gaugeElement: HTMLElement, settings: AnalogueCompassSettings): RadialGaugeOptions {
const majorTicks = (settings.majorTicks && settings.majorTicks.length > 0) ? deepClone(settings.majorTicks) :
['N','NE','E','SE','S','SW','W','NW'];
['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'];
majorTicks.push(majorTicks[0]);
return {

32
ui-ngx/src/app/modules/home/components/widget/lib/analogue-gauge.models.ts

@ -492,7 +492,7 @@ export const analogueGaugeSettingsSchema: JsonSettingsSchema = {
},
{
value: '700',
label: '800'
label: '700'
},
{
value: '800',
@ -581,7 +581,7 @@ export const analogueGaugeSettingsSchema: JsonSettingsSchema = {
},
{
value: '700',
label: '800'
label: '700'
},
{
value: '800',
@ -670,7 +670,7 @@ export const analogueGaugeSettingsSchema: JsonSettingsSchema = {
},
{
value: '700',
label: '800'
label: '700'
},
{
value: '800',
@ -759,7 +759,7 @@ export const analogueGaugeSettingsSchema: JsonSettingsSchema = {
},
{
value: '700',
label: '800'
label: '700'
},
{
value: '800',
@ -842,7 +842,7 @@ export abstract class TbBaseGauge<S, O extends GenericOptions> {
private gauge: BaseGauge;
protected constructor(protected ctx: WidgetContext, canvasId: string) {
const gaugeElement = $('#'+canvasId, ctx.$container)[0];
const gaugeElement = $('#' + canvasId, ctx.$container)[0];
const settings: S = ctx.settings;
const gaugeData: O = this.createGaugeOptions(gaugeElement, settings);
this.gauge = this.createGauge(gaugeData as O).draw();
@ -859,7 +859,7 @@ export abstract class TbBaseGauge<S, O extends GenericOptions> {
const tvPair = cellData.data[cellData.data.length -
1];
const value = tvPair[1];
if(value !== this.gauge.value) {
if (value !== this.gauge.value) {
this.gauge.value = value;
}
}
@ -876,10 +876,10 @@ export abstract class TbBaseGauge<S, O extends GenericOptions> {
}
}
export abstract class TbAnalogueGauge<S extends AnalogueGaugeSettings, O extends GenericOptions> extends TbBaseGauge<S,O> {
export abstract class TbAnalogueGauge<S extends AnalogueGaugeSettings, O extends GenericOptions> extends TbBaseGauge<S, O> {
protected constructor(ctx: WidgetContext, canvasId: string) {
super(ctx,canvasId);
super(ctx, canvasId);
}
protected createGaugeOptions(gaugeElement: HTMLElement, settings: S): O {
@ -891,26 +891,26 @@ export abstract class TbAnalogueGauge<S extends AnalogueGaugeSettings, O extends
const keyColor = settings.defaultColor || dataKey.color;
const majorTicksCount = settings.majorTicksCount || 10;
const total = maxValue-minValue;
let step = (total/majorTicksCount);
const total = maxValue - minValue;
let step = (total / majorTicksCount);
const valueInt = settings.valueInt || 3;
const valueDec = getValueDec(this.ctx, settings);
step = parseFloat(parseFloat(step+'').toFixed(valueDec));
step = parseFloat(parseFloat(step + '').toFixed(valueDec));
const majorTicks: number[] = [];
const highlights: Highlight[] = [];
let tick = minValue;
while(tick<=maxValue) {
while (tick <= maxValue) {
majorTicks.push(tick);
let nextTick = tick+step;
nextTick = parseFloat(parseFloat(nextTick+'').toFixed(valueDec));
if (tick<maxValue) {
let nextTick = tick + step;
nextTick = parseFloat(parseFloat(nextTick + '').toFixed(valueDec));
if (tick < maxValue) {
const highlightColor = tinycolor(keyColor);
const percent = (tick-minValue)/total;
const percent = (tick - minValue) / total;
highlightColor.setAlpha(percent);
const highlight: Highlight = {
from: tick,

2
ui-ngx/src/app/modules/home/components/widget/lib/analogue-linear-gauge.ts

@ -32,7 +32,7 @@ const tinycolor = tinycolor_;
const analogueLinearGaugeSettingsSchemaValue = getAnalogueLinearGaugeSettingsSchema();
export class TbAnalogueLinearGauge extends TbAnalogueGauge<AnalogueLinearGaugeSettings,LinearGaugeOptions>{
export class TbAnalogueLinearGauge extends TbAnalogueGauge<AnalogueLinearGaugeSettings, LinearGaugeOptions>{
static get settingsSchema(): JsonSettingsSchema {
return analogueLinearGaugeSettingsSchemaValue;

2
ui-ngx/src/app/modules/home/components/widget/lib/analogue-radial-gauge.ts

@ -28,7 +28,7 @@ import BaseGauge = CanvasGauges.BaseGauge;
const analogueRadialGaugeSettingsSchemaValue = getAnalogueRadialGaugeSettingsSchema();
export class TbAnalogueRadialGauge extends TbAnalogueGauge<AnalogueRadialGaugeSettings,RadialGaugeOptions>{
export class TbAnalogueRadialGauge extends TbAnalogueGauge<AnalogueRadialGaugeSettings, RadialGaugeOptions>{
static get settingsSchema(): JsonSettingsSchema {
return analogueRadialGaugeSettingsSchemaValue;

136
ui-ngx/src/app/modules/home/components/widget/lib/canvas-digital-gauge.ts

@ -18,7 +18,7 @@ import * as CanvasGauges from 'canvas-gauges';
import { FontStyle, FontWeight } from '@home/components/widget/lib/settings.models';
import * as tinycolor_ from 'tinycolor2';
import { ColorFormats } from 'tinycolor2';
import { isDefined, isString, isUndefined, padValue } from '@core/utils';
import { isDefined, isDefinedAndNotNull, isString, isUndefined, padValue } from '@core/utils';
import GenericOptions = CanvasGauges.GenericOptions;
import BaseGauge = CanvasGauges.BaseGauge;
@ -220,7 +220,7 @@ export class CanvasDigitalGauge extends BaseGauge {
public _value: number;
constructor(options: CanvasDigitalGaugeOptions) {
options = {...defaultDigitalGaugeOptions,...(options || {})};
options = {...defaultDigitalGaugeOptions, ...(options || {})};
super(CanvasDigitalGauge.configure(options));
this.initValueClone();
}
@ -236,10 +236,10 @@ export class CanvasDigitalGauge extends BaseGauge {
}
if (options.gaugeType === 'donut') {
if (!options.donutStartAngle) {
if (!isDefinedAndNotNull(options.donutStartAngle)) {
options.donutStartAngle = 1.5 * Math.PI;
}
if (!options.donutEndAngle) {
if (!isDefinedAndNotNull(options.donutEndAngle)) {
options.donutEndAngle = options.donutStartAngle + 2 * Math.PI;
}
}
@ -255,7 +255,7 @@ export class CanvasDigitalGauge extends BaseGauge {
const levelColor: any = options.levelColors[i];
if (levelColor !== null) {
let percentage: number;
if(isColorProperty){
if (isColorProperty) {
percentage = inc * i;
} else {
percentage = CanvasDigitalGauge.normalizeValue(levelColor.value, options.minValue, options.maxValue);
@ -280,7 +280,7 @@ export class CanvasDigitalGauge extends BaseGauge {
options.ticksValue = [];
for (const tick of options.ticks) {
if (tick !== null) {
options.ticksValue.push(CanvasDigitalGauge.normalizeValue(tick, options.minValue, options.maxValue))
options.ticksValue.push(CanvasDigitalGauge.normalizeValue(tick, options.minValue, options.maxValue));
}
}
@ -294,7 +294,7 @@ export class CanvasDigitalGauge extends BaseGauge {
return options;
}
static normalizeValue (value: number, min: number, max: number): number {
static normalizeValue(value: number, min: number, max: number): number {
const normalValue = (value - min) / (max - min);
if (normalValue <= 0) {
return 0;
@ -539,8 +539,8 @@ function barDimensions(context: DigitalGaugeCanvasRenderingContext2D,
titleOffset += bd.fontSizeFactor * 2;
bd.titleY = bd.baseY + titleOffset;
titleOffset += bd.fontSizeFactor * 2;
bd.Cy += titleOffset/2;
bd.Ro -= titleOffset/2;
bd.Cy += titleOffset / 2;
bd.Ro -= titleOffset / 2;
}
bd.Ri = bd.Ro - bd.width / 6.666666666666667 * gws * 1.2;
bd.Cx = bd.baseX + bd.width / 2;
@ -575,8 +575,8 @@ function barDimensions(context: DigitalGaugeCanvasRenderingContext2D,
const valueHeight = determineFontHeight(options, 'Value', bd.fontSizeFactor).height;
const labelHeight = determineFontHeight(options, 'Label', bd.fontSizeFactor).height;
const total = valueHeight + labelHeight;
bd.labelY = bd.Cy + total/2;
bd.valueY = bd.Cy - total/2 + valueHeight/2;
bd.labelY = bd.Cy + total / 2;
bd.valueY = bd.Cy - total / 2 + valueHeight / 2;
} else {
bd.valueY = bd.Cy;
}
@ -586,8 +586,8 @@ function barDimensions(context: DigitalGaugeCanvasRenderingContext2D,
bd.labelY = bd.Cy + (8 + options.fontLabelSize) * bd.fontSizeFactor;
bd.minY = bd.maxY = bd.labelY;
if (options.roundedLineCap) {
bd.minY += bd.strokeWidth/2;
bd.maxY += bd.strokeWidth/2;
bd.minY += bd.strokeWidth / 2;
bd.maxY += bd.strokeWidth / 2;
}
bd.minX = bd.Cx - bd.Rm;
bd.maxX = bd.Cx + bd.Rm;
@ -604,15 +604,15 @@ function barDimensions(context: DigitalGaugeCanvasRenderingContext2D,
if (options.hideMinMax && options.label === '') {
bd.labelY = bd.barBottom;
bd.barLeft = bd.origBaseX + options.fontMinMaxSize/3 * bd.fontSizeFactor;
bd.barRight = bd.origBaseX + w + /*bd.width*/ - options.fontMinMaxSize/3 * bd.fontSizeFactor;
bd.barLeft = bd.origBaseX + options.fontMinMaxSize / 3 * bd.fontSizeFactor;
bd.barRight = bd.origBaseX + w + /*bd.width*/ -options.fontMinMaxSize / 3 * bd.fontSizeFactor;
} else {
context.font = Drawings.font(options, 'MinMax', bd.fontSizeFactor);
const minTextWidth = context.measureText(options.minValue+'').width;
const maxTextWidth = context.measureText(options.maxValue+'').width;
const minTextWidth = context.measureText(options.minValue + '').width;
const maxTextWidth = context.measureText(options.maxValue + '').width;
const maxW = Math.max(minTextWidth, maxTextWidth);
bd.minX = bd.origBaseX + maxW/2 + options.fontMinMaxSize/3 * bd.fontSizeFactor;
bd.maxX = bd.origBaseX + w + /*bd.width*/ - maxW/2 - options.fontMinMaxSize/3 * bd.fontSizeFactor;
bd.minX = bd.origBaseX + maxW / 2 + options.fontMinMaxSize / 3 * bd.fontSizeFactor;
bd.maxX = bd.origBaseX + w + /*bd.width*/ -maxW / 2 - options.fontMinMaxSize / 3 * bd.fontSizeFactor;
bd.barLeft = bd.minX;
bd.barRight = bd.maxX;
bd.labelY = bd.barBottom + (8 + options.fontLabelSize) * bd.fontSizeFactor;
@ -632,7 +632,7 @@ function barDimensions(context: DigitalGaugeCanvasRenderingContext2D,
bd.barBottom = bd.labelY - (8 + options.fontLabelSize) * bd.fontSizeFactor;
}
bd.minX = bd.maxX =
bd.baseX + bd.width/2 + bd.strokeWidth/2 + options.fontMinMaxSize/3 * bd.fontSizeFactor;
bd.baseX + bd.width / 2 + bd.strokeWidth / 2 + options.fontMinMaxSize / 3 * bd.fontSizeFactor;
bd.minY = bd.barBottom;
bd.maxY = bd.barTop;
bd.fontMinMaxBaseline = 'middle';
@ -658,13 +658,13 @@ function barDimensions(context: DigitalGaugeCanvasRenderingContext2D,
// tslint:disable-next-line:no-bitwise
dashCount = (dashCount - 1) | 1;
}
bd.dashLength = Math.ceil(circumference/dashCount);
bd.dashLength = Math.ceil(circumference / dashCount);
}
return bd;
}
function determineFontHeight (options: CanvasDigitalGaugeOptions, target: string, baseSize: number): FontHeightInfo {
function determineFontHeight(options: CanvasDigitalGaugeOptions, target: string, baseSize: number): FontHeightInfo {
const fontStyleStr = 'font-style:' + options['font' + target + 'Style'] + ';font-weight:' +
options['font' + target + 'Weight'] + ';font-size:' +
options['font' + target + 'Size'] * baseSize + 'px;font-family:' +
@ -688,9 +688,9 @@ function determineFontHeight (options: CanvasDigitalGaugeOptions, target: string
try {
result = {};
block.css({ verticalAlign: 'baseline' });
block.css({verticalAlign: 'baseline'});
result.ascent = block.offset().top - text.offset().top;
block.css({ verticalAlign: 'bottom' });
block.css({verticalAlign: 'bottom'});
result.height = block.offset().top - text.offset().top;
result.descent = result.height - result.ascent;
} finally {
@ -720,15 +720,15 @@ function drawBackground(context: DigitalGaugeCanvasRenderingContext2D, options:
context.stroke();
} else if (options.gaugeType === 'arc') {
context.arc(context.barDimensions.Cx, context.barDimensions.Cy,
context.barDimensions.Rm, Math.PI, 2*Math.PI);
context.barDimensions.Rm, Math.PI, 2 * Math.PI);
context.stroke();
} else if (options.gaugeType === 'horizontalBar') {
context.moveTo(barLeft,barTop + strokeWidth/2);
context.lineTo(barRight,barTop + strokeWidth/2);
context.moveTo(barLeft, barTop + strokeWidth / 2);
context.lineTo(barRight, barTop + strokeWidth / 2);
context.stroke();
} else if (options.gaugeType === 'verticalBar') {
context.moveTo(baseX + width/2, barBottom);
context.lineTo(baseX + width/2, barTop);
context.moveTo(baseX + width / 2, barBottom);
context.lineTo(baseX + width / 2, barTop);
context.stroke();
}
}
@ -740,7 +740,9 @@ function drawText(context: DigitalGaugeCanvasRenderingContext2D, options: Canvas
}
function drawDigitalTitle(context: DigitalGaugeCanvasRenderingContext2D, options: CanvasDigitalGaugeOptions) {
if (!options.title || typeof options.title !== 'string') return;
if (!options.title || typeof options.title !== 'string') {
return;
}
const {titleY, width, baseX, fontSizeFactor} =
context.barDimensions;
@ -756,7 +758,9 @@ function drawDigitalTitle(context: DigitalGaugeCanvasRenderingContext2D, options
}
function drawDigitalLabel(context: DigitalGaugeCanvasRenderingContext2D, options: CanvasDigitalGaugeOptions) {
if (!options.label || options.label === '') return;
if (!options.label || options.label === '') {
return;
}
const {labelY, baseX, width, fontSizeFactor} =
context.barDimensions;
@ -772,7 +776,9 @@ function drawDigitalLabel(context: DigitalGaugeCanvasRenderingContext2D, options
}
function drawDigitalMinMax(context: DigitalGaugeCanvasRenderingContext2D, options: CanvasDigitalGaugeOptions) {
if (options.hideMinMax || options.gaugeType === 'donut') return;
if (options.hideMinMax || options.gaugeType === 'donut') {
return;
}
const {minY, maxY, minX, maxX, fontSizeFactor, fontMinMaxAlign, fontMinMaxBaseline} =
context.barDimensions;
@ -782,12 +788,14 @@ function drawDigitalMinMax(context: DigitalGaugeCanvasRenderingContext2D, option
context.textBaseline = fontMinMaxBaseline;
context.font = Drawings.font(options, 'MinMax', fontSizeFactor);
context.lineWidth = 0;
drawText(context, options, 'MinMax', options.minValue+'', minX, minY);
drawText(context, options, 'MinMax', options.maxValue+'', maxX, maxY);
drawText(context, options, 'MinMax', options.minValue + '', minX, minY);
drawText(context, options, 'MinMax', options.maxValue + '', maxX, maxY);
}
function drawDigitalValue(context: DigitalGaugeCanvasRenderingContext2D, options: CanvasDigitalGaugeOptions, value: any) {
if (options.hideValue) return;
if (options.hideValue) {
return;
}
const {valueY, baseX, width, fontSizeFactor, fontValueBaseline} =
context.barDimensions;
@ -837,16 +845,16 @@ function drawArcGlow(context: DigitalGaugeCanvasRenderingContext2D,
context.setLineDash([]);
const strokeWidth = Ro - Ri;
const blur = 0.55;
const edge = strokeWidth*blur;
context.lineWidth = strokeWidth+edge;
const stop = blur/(2*blur+2);
const glowGradient = context.createRadialGradient(Cx,Cy,Ri-edge/2,Cx,Cy,Ro+edge/2);
const edge = strokeWidth * blur;
context.lineWidth = strokeWidth + edge;
const stop = blur / (2 * blur + 2);
const glowGradient = context.createRadialGradient(Cx, Cy, Ri - edge / 2, Cx, Cy, Ro + edge / 2);
const color1 = tinycolor(color).setAlpha(0.5).toRgbString();
const color2 = tinycolor(color).setAlpha(0).toRgbString();
glowGradient.addColorStop(0,color2);
glowGradient.addColorStop(stop,color1);
glowGradient.addColorStop(1.0-stop,color1);
glowGradient.addColorStop(1,color2);
glowGradient.addColorStop(0, color2);
glowGradient.addColorStop(stop, color1);
glowGradient.addColorStop(1.0 - stop, color1);
glowGradient.addColorStop(1, color2);
context.strokeStyle = glowGradient;
context.beginPath();
const e = 0.01 * Math.PI;
@ -863,21 +871,21 @@ function drawBarGlow(context: DigitalGaugeCanvasRenderingContext2D, startX: numb
endX: number, endY: number, color: string, strokeWidth: number, isVertical: boolean) {
context.setLineDash([]);
const blur = 0.55;
const edge = strokeWidth*blur;
context.lineWidth = strokeWidth+edge;
const stop = blur/(2*blur+2);
const gradientStartX = isVertical ? startX - context.lineWidth/2 : 0;
const gradientStartY = isVertical ? 0 : startY - context.lineWidth/2;
const gradientStopX = isVertical ? startX + context.lineWidth/2 : 0;
const gradientStopY = isVertical ? 0 : startY + context.lineWidth/2;
const glowGradient = context.createLinearGradient(gradientStartX,gradientStartY,gradientStopX,gradientStopY);
const edge = strokeWidth * blur;
context.lineWidth = strokeWidth + edge;
const stop = blur / (2 * blur + 2);
const gradientStartX = isVertical ? startX - context.lineWidth / 2 : 0;
const gradientStartY = isVertical ? 0 : startY - context.lineWidth / 2;
const gradientStopX = isVertical ? startX + context.lineWidth / 2 : 0;
const gradientStopY = isVertical ? 0 : startY + context.lineWidth / 2;
const glowGradient = context.createLinearGradient(gradientStartX, gradientStartY, gradientStopX, gradientStopY);
const color1 = tinycolor(color).setAlpha(0.5).toRgbString();
const color2 = tinycolor(color).setAlpha(0).toRgbString();
glowGradient.addColorStop(0,color2);
glowGradient.addColorStop(stop,color1);
glowGradient.addColorStop(1.0-stop,color1);
glowGradient.addColorStop(1,color2);
glowGradient.addColorStop(0, color2);
glowGradient.addColorStop(stop, color1);
glowGradient.addColorStop(1.0 - stop, color1);
glowGradient.addColorStop(1, color2);
context.strokeStyle = glowGradient;
const dx = isVertical ? 0 : 0.05 * context.lineWidth;
const dy = isVertical ? 0.05 * context.lineWidth : 0;
@ -984,12 +992,12 @@ function drawProgress(context: DigitalGaugeCanvasRenderingContext2D,
context.strokeStyle = neonColor;
}
context.beginPath();
context.moveTo(barLeft,barTop + strokeWidth/2);
context.lineTo(barLeft + (barRight-barLeft)*progress, barTop + strokeWidth/2);
context.moveTo(barLeft, barTop + strokeWidth / 2);
context.lineTo(barLeft + (barRight - barLeft) * progress, barTop + strokeWidth / 2);
context.stroke();
if (options.neonGlowBrightness && !options.isMobile) {
drawBarGlow(context, barLeft, barTop + strokeWidth/2,
barLeft + (barRight-barLeft)*progress, barTop + strokeWidth/2,
drawBarGlow(context, barLeft, barTop + strokeWidth / 2,
barLeft + (barRight - barLeft) * progress, barTop + strokeWidth / 2,
neonColor, strokeWidth, false);
}
drawTickBar(context, options.ticksValue, barLeft, barTop, barRight - barLeft, strokeWidth,
@ -999,12 +1007,12 @@ function drawProgress(context: DigitalGaugeCanvasRenderingContext2D,
context.strokeStyle = neonColor;
}
context.beginPath();
context.moveTo(baseX + width/2, barBottom);
context.lineTo(baseX + width/2, barBottom - (barBottom-barTop)*progress);
context.moveTo(baseX + width / 2, barBottom);
context.lineTo(baseX + width / 2, barBottom - (barBottom - barTop) * progress);
context.stroke();
if (options.neonGlowBrightness && !options.isMobile) {
drawBarGlow(context, baseX + width/2, barBottom,
baseX + width/2, barBottom - (barBottom-barTop)*progress,
drawBarGlow(context, baseX + width / 2, barBottom,
baseX + width / 2, barBottom - (barBottom - barTop) * progress,
neonColor, strokeWidth, true);
}
drawTickBar(context, options.ticksValue, baseX + width / 2, barTop, barTop - barBottom, strokeWidth,

8
ui-ngx/src/app/modules/home/components/widget/lib/digital-gauge.models.ts

@ -694,7 +694,7 @@ export const digitalGaugeSettingsSchema: JsonSettingsSchema = {
},
{
value: '700',
label: '800'
label: '700'
},
{
value: '800',
@ -783,7 +783,7 @@ export const digitalGaugeSettingsSchema: JsonSettingsSchema = {
},
{
value: '700',
label: '800'
label: '700'
},
{
value: '800',
@ -872,7 +872,7 @@ export const digitalGaugeSettingsSchema: JsonSettingsSchema = {
},
{
value: '700',
label: '800'
label: '700'
},
{
value: '800',
@ -961,7 +961,7 @@ export const digitalGaugeSettingsSchema: JsonSettingsSchema = {
},
{
value: '700',
label: '800'
label: '700'
},
{
value: '800',

52
ui-ngx/src/app/modules/home/components/widget/lib/digital-gauge.ts

@ -25,7 +25,7 @@ import {
FixedLevelColors
} from '@home/components/widget/lib/digital-gauge.models';
import * as tinycolor_ from 'tinycolor2';
import { isDefined } from '@core/utils';
import { isDefined, isDefinedAndNotNull } from '@core/utils';
import { prepareFontSettings } from '@home/components/widget/lib/settings.models';
import { CanvasDigitalGauge, CanvasDigitalGaugeOptions } from '@home/components/widget/lib/canvas-digital-gauge';
import { DatePipe } from '@angular/common';
@ -53,7 +53,7 @@ export class TbCanvasDigitalGauge {
}
constructor(protected ctx: WidgetContext, canvasId: string) {
const gaugeElement = $('#'+canvasId, ctx.$container)[0];
const gaugeElement = $('#' + canvasId, ctx.$container)[0];
const settings: DigitalGaugeSettings = ctx.settings;
this.localSettings = {};
@ -80,7 +80,7 @@ export class TbCanvasDigitalGauge {
this.localSettings.useFixedLevelColor = settings.useFixedLevelColor || false;
if (!settings.useFixedLevelColor) {
if (!settings.levelColors || settings.levelColors.length <= 0) {
if (!settings.levelColors || settings.levelColors.length === 0) {
this.localSettings.levelColors = [keyColor];
} else {
this.localSettings.levelColors = settings.levelColors.slice();
@ -97,14 +97,15 @@ export class TbCanvasDigitalGauge {
this.localSettings.colorTicks = settings.colorTicks || '#666';
this.localSettings.decimals = isDefined(dataKey.decimals) ? dataKey.decimals :
((isDefined(settings.decimals) && settings.decimals !== null)
? settings.decimals : ctx.decimals);
(isDefinedAndNotNull(settings.decimals) ? settings.decimals : ctx.decimals);
this.localSettings.units = dataKey.units && dataKey.units.length ? dataKey.units :
(isDefined(settings.units) && settings.units.length > 0 ? settings.units : ctx.units);
this.localSettings.hideValue = settings.showValue !== true;
this.localSettings.hideMinMax = settings.showMinMax !== true;
this.localSettings.donutStartAngle = isDefinedAndNotNull(settings.donutStartAngle) ?
-TbCanvasDigitalGauge.toRadians(settings.donutStartAngle) : null;
this.localSettings.title = ((settings.showTitle === true) ?
(settings.title && settings.title.length > 0 ?
@ -191,14 +192,15 @@ export class TbCanvasDigitalGauge {
hideValue: this.localSettings.hideValue,
hideMinMax: this.localSettings.hideMinMax,
donutStartAngle: this.localSettings.donutStartAngle,
valueDec: this.localSettings.decimals,
neonGlowBrightness: this.localSettings.neonGlowBrightness,
// animations
animation: settings.animation !== false && !ctx.isMobile,
animationDuration: (isDefined(settings.animationDuration) && settings.animationDuration !== null)
? settings.animationDuration : 500,
animationDuration: isDefinedAndNotNull(settings.animationDuration) ? settings.animationDuration : 500,
animationRule: settings.animationRule || 'linear',
isMobile: ctx.isMobile
@ -241,7 +243,7 @@ export class TbCanvasDigitalGauge {
if (findDataKey) {
findDataKey.settings.push(settings);
} else {
datasource.dataKeys.push(dataKey)
datasource.dataKeys.push(dataKey);
}
} else {
const datasourceAttribute: Datasource = {
@ -257,17 +259,23 @@ export class TbCanvasDigitalGauge {
return datasources;
}
private static toRadians(angle: number): number {
return angle * (Math.PI / 180);
}
init() {
if (this.localSettings.useFixedLevelColor) {
if (this.localSettings.fixedLevelColors && this.localSettings.fixedLevelColors.length > 0) {
this.localSettings.levelColors = this.settingLevelColorsSubscribe(this.localSettings.fixedLevelColors);
}
let updateSetting = false;
if (this.localSettings.showTicks) {
if (this.localSettings.ticksValue && this.localSettings.ticksValue.length) {
this.localSettings.ticks = this.settingTicksSubscribe(this.localSettings.ticksValue);
}
}
if (this.localSettings.useFixedLevelColor && this.localSettings.fixedLevelColors?.length > 0) {
this.localSettings.levelColors = this.settingLevelColorsSubscribe(this.localSettings.fixedLevelColors);
updateSetting = true;
}
if (this.localSettings.showTicks && this.localSettings.ticksValue?.length) {
this.localSettings.ticks = this.settingTicksSubscribe(this.localSettings.ticksValue);
updateSetting = true;
}
if (updateSetting) {
this.updateSetting();
}
}
@ -281,7 +289,7 @@ export class TbCanvasDigitalGauge {
predefineLevelColors.push({
value: levelSetting.value,
color
})
});
} else if (levelSetting.entityAlias && levelSetting.attribute) {
try {
levelColorsDatasource = TbCanvasDigitalGauge.generateDatasource(this.ctx, levelColorsDatasource,
@ -293,7 +301,7 @@ export class TbCanvasDigitalGauge {
}
}
for(const levelColor of options){
for (const levelColor of options) {
if (levelColor.from) {
setLevelColor.call(this, levelColor.from, levelColor.color);
}
@ -313,9 +321,9 @@ export class TbCanvasDigitalGauge {
let ticksDatasource: Datasource[] = [];
const predefineTicks: number[] = [];
for(const tick of options){
for (const tick of options) {
if (tick.valueSource === 'predefinedValue' && isFinite(tick.value)) {
predefineTicks.push(tick.value)
predefineTicks.push(tick.value);
} else if (tick.entityAlias && tick.attribute) {
try {
ticksDatasource = TbCanvasDigitalGauge
@ -398,7 +406,7 @@ export class TbCanvasDigitalGauge {
filter.transform(timestamp, this.localSettings.timestampFormat);
}
const value = tvPair[1];
if(value !== this.gauge.value) {
if (value !== this.gauge.value) {
if (!this.gauge.options.animation) {
this.gauge._value = value;
}

4
ui-ngx/src/app/modules/home/models/services.map.ts

@ -31,6 +31,7 @@ import { CustomerService } from '@core/http/customer.service';
import { DashboardService } from '@core/http/dashboard.service';
import { UserService } from '@core/http/user.service';
import { AlarmService } from '@core/http/alarm.service';
import { Router } from '@angular/router';
export const ServicesMap = new Map<string, Type<any>>(
[
@ -49,6 +50,7 @@ export const ServicesMap = new Map<string, Type<any>>(
['date', DatePipe],
['utils', UtilsService],
['translate', TranslateService],
['http', HttpClient]
['http', HttpClient],
['router', Router]
]
);

2
ui-ngx/src/app/modules/home/models/widget-component.models.ts

@ -76,6 +76,7 @@ import { TranslateService } from '@ngx-translate/core';
import { PageLink } from '@shared/models/page/page-link';
import { SortOrder } from '@shared/models/page/sort-order';
import { DomSanitizer } from '@angular/platform-browser';
import { Router } from '@angular/router';
export interface IWidgetAction {
name: string;
@ -157,6 +158,7 @@ export class WidgetContext {
translate: TranslateService;
http: HttpClient;
sanitizer: DomSanitizer;
router: Router;
private changeDetectorValue: ChangeDetectorRef;

6
ui-ngx/src/app/shared/models/ace/service-completion.models.ts

@ -1379,5 +1379,11 @@ export const serviceCompletions: TbEditorCompletions = {
'See <a href="https://angular.io/api/platform-browser/DomSanitizer">DomSanitizer</a> for API reference.',
meta: 'service',
type: '<a href="https://angular.io/api/platform-browser/DomSanitizer">DomSanitizer</a>'
},
router: {
description: 'Router Service<br>' +
'See <a href="https://angular.io/api/router/Router">Router</a> for API reference.',
meta: 'service',
type: '<a href="https://angular.io/api/router/Router">Router</a>'
}
};

Loading…
Cancel
Save