node-red-contrib-prib-functions 0.19.2 → 0.20.4

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.
Files changed (75) hide show
  1. package/.github/workflows/codeql-analysis.yml +3 -3
  2. package/.github/workflows/npmpublish.yml +6 -6
  3. package/.vs/VSWorkspaceState.json +7 -0
  4. package/.vs/node-red-contrib-prib-functions/v17/.wsuo +0 -0
  5. package/README.md +6 -2
  6. package/arima/index.js +18 -0
  7. package/dataAnalysis/arrayAllRowsSwap.js +15 -0
  8. package/dataAnalysis/arrayCompareToPrecision.js +34 -0
  9. package/dataAnalysis/arrayDifference.js +14 -0
  10. package/dataAnalysis/arrayDifferenceSeasonal.js +15 -0
  11. package/dataAnalysis/arrayDifferenceSeasonalSecondOrder.js +20 -0
  12. package/dataAnalysis/arrayDifferenceSecondOrder.js +14 -0
  13. package/dataAnalysis/arrayForEachRange.js +38 -0
  14. package/dataAnalysis/arrayOverlay.js +13 -0
  15. package/dataAnalysis/arrayProduct.js +11 -0
  16. package/dataAnalysis/arrayRandom.js +14 -0
  17. package/dataAnalysis/arrayReduceRange.js +11 -0
  18. package/dataAnalysis/arrayScale.js +11 -0
  19. package/dataAnalysis/arraySum.js +11 -0
  20. package/dataAnalysis/arraySumSquared.js +11 -0
  21. package/dataAnalysis/arraySwap.js +11 -0
  22. package/dataAnalysis/dataAnalysis.html +31 -14
  23. package/dataAnalysis/dataAnalysis.js +10 -1
  24. package/dataAnalysis/generateMatrixFunction.js +89 -0
  25. package/dataAnalysis/generateVectorFunction.js +25 -0
  26. package/dataAnalysis/pca.js +472 -325
  27. package/dataAnalysis/svd.js +239 -0
  28. package/echart/echart.html +68 -0
  29. package/echart/echart.js +85 -0
  30. package/echart/icons/chart-671.png +0 -0
  31. package/echart/lib/echarts.js +95886 -0
  32. package/lib/Chart.js +177 -0
  33. package/lib/Column.js +99 -0
  34. package/lib/GraphDB.js +14 -0
  35. package/lib/Table.js +185 -0
  36. package/lib/objectExtensions.js +361 -0
  37. package/matrix/matrix.js +2 -48
  38. package/monitor/BarGauge.js +8 -0
  39. package/monitor/Dataset.js +29 -0
  40. package/monitor/DialGauge.js +109 -0
  41. package/monitor/DialNeedle.js +36 -0
  42. package/monitor/Format.js +74 -0
  43. package/monitor/centerElement.js +14 -0
  44. package/monitor/compareElements.js +95 -0
  45. package/monitor/defs.js +23 -0
  46. package/monitor/extensions.js +906 -0
  47. package/monitor/functions.js +36 -0
  48. package/monitor/json2xml.js +103 -0
  49. package/monitor/monitorSystem.html +198 -0
  50. package/monitor/monitorSystem.js +322 -0
  51. package/monitor/svgHTML.js +179 -0
  52. package/monitor/svgObjects.js +64 -0
  53. package/package.json +18 -6
  54. package/test/00-objectExtensions.js +94 -0
  55. package/test/04-tables.js +33 -0
  56. package/test/data/.config.nodes.json +608 -0
  57. package/test/data/.config.nodes.json.backup +608 -0
  58. package/test/data/.config.runtime.json +4 -0
  59. package/test/data/.config.runtime.json.backup +3 -0
  60. package/test/data/.config.users.json +21 -0
  61. package/test/data/.config.users.json.backup +21 -0
  62. package/test/data/.flow.json.backup +2448 -2207
  63. package/test/data/float32vector10.npy +0 -0
  64. package/test/data/flow.json +2412 -2191
  65. package/test/data/int2matrix2x3.npy +0 -0
  66. package/test/data/package-lock.json +158 -0
  67. package/test/data/package.json +11 -0
  68. package/test/dataAnalysisExtensions.js +472 -0
  69. package/test/dataAnalysisPCA.js +54 -0
  70. package/test/dataAnalysisSVD.js +31 -0
  71. package/test/euclideanDistance.js +2 -2
  72. package/test/transformNumPy.js +132 -0
  73. package/transform/NumPy.js +303 -0
  74. package/transform/transform.html +12 -0
  75. package/transform/transform.js +34 -2
@@ -0,0 +1,361 @@
1
+ if(!Array.prototype.move)
2
+ Array.prototype.move = function(from, to) {
3
+ if(from<to) to--;
4
+ this.splice(to, 0, this.splice(from, 1)[0]);
5
+ };
6
+ if(!Number.prototype.between)
7
+ Number.prototype.between = function (min, max) {
8
+ return !(this < min || this > max);
9
+ };
10
+ if(!String.prototype.in)
11
+ String.prototype.in = function (str) {
12
+ for (var i = 0; i < arguments.length; i++)
13
+ if(this==arguments[i]) return true;
14
+ return false;
15
+ };
16
+ if(!String.prototype.startsWith)
17
+ String.prototype.startsWith = function (str) {
18
+ return this.slice(0, str.length) == str;
19
+ };
20
+ if(!String.prototype.toTitle)
21
+ String.prototype.toTitle = function () {
22
+ var title=this.substr(0,1).toUpperCase()
23
+ ,lastLowerCase=false;
24
+ for(var i=1 ; i<this.length; i++ ) {
25
+ char=this.substr(i,1);
26
+ if(char==char.toUpperCase()) {
27
+ if(lastLowerCase) title+=' ';
28
+ lastLowerCase=false;
29
+ if(char=='_') continue;
30
+ if(char==' ') continue;
31
+ } else lastLowerCase=true;
32
+ title+=char;
33
+ }
34
+ return title;
35
+ };
36
+ if(!String.prototype.to)
37
+ String.prototype.to = function (type) {
38
+ if (this==null) return null;
39
+ if (type==null) return value;
40
+ return this['to'+type.capitalize()];
41
+ }
42
+ if(!String.prototype.toReal)
43
+ String.prototype.toReal = function () {
44
+ return parseFloat(this);
45
+ };
46
+ if(!String.prototype.toInt)
47
+ String.prototype.toInt = function () {
48
+ return parseInt(this);
49
+ };
50
+ if(!String.prototype.toTimestamp)
51
+ String.prototype.toTimestamp = function () {
52
+ return Date.parse(this.substr(0,4)+'/'+this.substr(5,2)+'/'+this.substr(8,11))
53
+ + parseInt(this.substr(21,3));
54
+ };
55
+ if(!String.prototype.toTime)
56
+ String.prototype.toTime = function () {
57
+ return Date.parse(this);
58
+ };
59
+ if(!String.prototype.toDatetime)
60
+ String.prototype.toDatetime = String.prototype.toTime;
61
+ if(!String.prototype.toDate)
62
+ String.prototype.toDate = String.prototype.toTime;
63
+ if(!String.prototype.CRLF2BR)
64
+ String.prototype.CRLF2BR = function () {
65
+ return this.replace("\n\r","<br/>").replace("\n","<br/>");
66
+ };
67
+
68
+ Array.prototype.findSorted = function(searchElement,minIndex = 0,maxIndex = this.length - 1) {
69
+ let currentIndex, currentElement
70
+ while(minIndex <= maxIndex) {
71
+ currentIndex = (minIndex + maxIndex) / 2 | 0
72
+ currentElement = this[currentIndex]
73
+ if(currentElement < searchElement) {
74
+ minIndex = currentIndex + 1;
75
+ } else if(currentElement > searchElement) {
76
+ maxIndex = currentIndex - 1;
77
+ } else return currentIndex
78
+ }
79
+ return -minIndex
80
+ }
81
+ Array.prototype.addSorted = function(element) {
82
+ if(this.length){
83
+ const position = -this.findSorted(element)
84
+ if(position<0 ) return -position
85
+ this.splice(position, 0, element)
86
+ return position
87
+ }
88
+ this.push(element)
89
+ return 0
90
+ }
91
+ Object.prototype.addList = function(property,object) {
92
+ try{
93
+ this[property].push(object)
94
+ } catch(ex) {
95
+ this[property]=[object]
96
+ }
97
+ }
98
+ Object.prototype.addErrorFunctions = function(){
99
+ this.onError=function(call){
100
+ if(this.errorStack) this.errorStack.push(call)
101
+ else this.errorStack=[this.call]
102
+ return this
103
+ }
104
+ this.error=function(ex="no error message"){
105
+ if(this.errorStack){
106
+ this.errorStack.forEach((callFunction)=>{
107
+ try{
108
+ callFunction(ex)
109
+ }catch(ex) {}
110
+ })
111
+ return
112
+ }
113
+ if(typeof ex == "string") throw Error(ex)
114
+ throw ex
115
+ }
116
+ }
117
+ if(!colourSmallList) var colourSmallList={
118
+ "Red":'#FF0000',
119
+ "Turquoise":'#00FFFF',
120
+ "Grass Green":'#408080',
121
+ "Dark Blue":'#0000A0',
122
+ "Orange":'#FF8040',
123
+ "Yellow":'#FFFF00',
124
+ "Burgundy":'#800000',
125
+ "Dark Purple":'#800080',
126
+ "Brown":'#804000',
127
+ "Pastel Green":'#00FF00',
128
+ "Pink":'#FF00FF',
129
+ "Light Grey":'#C0C0C0',
130
+ "Forest Green":'#808000',
131
+ "Light Blue":'#0000FF',
132
+ "Light Purple":'#FF0080',
133
+ "Dark Grey":'#808080'
134
+ }
135
+ if(!colours) var colours ={
136
+ AliceBlue: '#F0F8FF',
137
+ AntiqueWhite: '#FAEBD7',
138
+ Aqua: '#00FFFF',
139
+ Aquamarine: '#7FFFD4',
140
+ Azure: '#F0FFFF',
141
+ Beige: '#F5F5DC',
142
+ Bisque: '#FFE4C4',
143
+ Black: '#000000',
144
+ BlanchedAlmond: '#FFEBCD',
145
+ Blue: '#0000FF',
146
+ BlueViolet: '#8A2BE2',
147
+ Brown: '#A52A2A',
148
+ BurlyWood: '#DEB887',
149
+ CadetBlue: '#5F9EA0',
150
+ Chartreuse: '#7FFF00',
151
+ Chocolate: '#D2691E',
152
+ Coral: '#FF7F50',
153
+ CornflowerBlue: '#6495ED',
154
+ Cornsilk: '#FFF8DC',
155
+ Crimson: '#DC143C',
156
+ Cyan: '#00FFFF',
157
+ DarkBlue: '#00008B',
158
+ DarkCyan: '#008B8B',
159
+ DarkGoldenRod: '#B8860B',
160
+ DarkGray: '#A9A9A9',
161
+ DarkGrey: '#A9A9A9',
162
+ DarkGreen: '#006400',
163
+ DarkKhaki: '#BDB76B',
164
+ DarkMagenta: '#8B008B',
165
+ DarkOliveGreen: '#556B2F',
166
+ DarkOrange: '#FF8C00',
167
+ DarkOrchid: '#9932CC',
168
+ DarkRed: '#8B0000',
169
+ DarkSalmon: '#E9967A',
170
+ DarkSeaGreen: '#8FBC8F',
171
+ DarkSlateBlue: '#483D8B',
172
+ DarkSlateGray: '#2F4F4F',
173
+ DarkSlateGrey: '#2F4F4F',
174
+ DarkTurquoise: '#00CED1',
175
+ DarkViolet: '#9400D3',
176
+ DeepPink: '#FF1493',
177
+ DeepSkyBlue: '#00BFFF',
178
+ DimGray: '#696969',
179
+ DimGrey: '#696969',
180
+ DodgerBlue: '#1E90FF',
181
+ FireBrick: '#B22222',
182
+ FloralWhite: '#FFFAF0',
183
+ ForestGreen: '#228B22',
184
+ Fuchsia: '#FF00FF',
185
+ Gainsboro: '#DCDCDC',
186
+ GhostWhite: '#F8F8FF',
187
+ Gold: '#FFD700',
188
+ GoldenRod: '#DAA520',
189
+ Gray: '#808080',
190
+ Grey: '#808080',
191
+ Green: '#008000',
192
+ GreenYellow: '#ADFF2F',
193
+ HoneyDew: '#F0FFF0',
194
+ HotPink: '#FF69B4',
195
+ IndianRed: '#CD5C5C',
196
+ Indigo: '#4B0082',
197
+ Ivory: '#FFFFF0',
198
+ Khaki: '#F0E68C',
199
+ Lavender: '#E6E6FA',
200
+ LavenderBlush: '#FFF0F5',
201
+ LawnGreen: '#7CFC00',
202
+ LemonChiffon: '#FFFACD',
203
+ LightBlue: '#ADD8E6',
204
+ LightCoral: '#F08080',
205
+ LightCyan: '#E0FFFF',
206
+ LightGoldenRodYellow: '#FAFAD2',
207
+ LightGray: '#D3D3D3',
208
+ LightGrey: '#D3D3D3',
209
+ LightGreen: '#90EE90',
210
+ LightPink: '#FFB6C1',
211
+ LightSalmon: '#FFA07A',
212
+ LightSeaGreen: '#20B2AA',
213
+ LightSkyBlue: '#87CEFA',
214
+ LightSlateGray: '#778899',
215
+ LightSlateGrey: '#778899',
216
+ LightSteelBlue: '#B0C4DE',
217
+ LightYellow: '#FFFFE0',
218
+ Lime: '#00FF00',
219
+ LimeGreen: '#32CD32',
220
+ Linen: '#FAF0E6',
221
+ Magenta: '#FF00FF',
222
+ Maroon: '#800000',
223
+ MediumAquaMarine: '#66CDAA',
224
+ MediumBlue: '#0000CD',
225
+ MediumOrchid: '#BA55D3',
226
+ MediumPurple: '#9370DB',
227
+ MediumSeaGreen: '#3CB371',
228
+ MediumSlateBlue: '#7B68EE',
229
+ MediumSpringGreen: '#00FA9A',
230
+ MediumTurquoise: '#48D1CC',
231
+ MediumVioletRed: '#C71585',
232
+ MidnightBlue: '#191970',
233
+ MintCream: '#F5FFFA',
234
+ MistyRose: '#FFE4E1',
235
+ Moccasin: '#FFE4B5',
236
+ NavajoWhite: '#FFDEAD',
237
+ Navy: '#000080',
238
+ OldLace: '#FDF5E6',
239
+ Olive: '#808000',
240
+ OliveDrab: '#6B8E23',
241
+ Orange: '#FFA500',
242
+ OrangeRed: '#FF4500',
243
+ Orchid: '#DA70D6',
244
+ PaleGoldenRod: '#EEE8AA',
245
+ PaleGreen: '#98FB98',
246
+ PaleTurquoise: '#AFEEEE',
247
+ PaleVioletRed: '#DB7093',
248
+ PapayaWhip: '#FFEFD5',
249
+ PeachPuff: '#FFDAB9',
250
+ Peru: '#CD853F',
251
+ Pink: '#FFC0CB',
252
+ Plum: '#DDA0DD',
253
+ PowderBlue: '#B0E0E6',
254
+ Purple: '#800080',
255
+ RebeccaPurple: '#663399',
256
+ Red: '#FF0000',
257
+ RosyBrown: '#BC8F8F',
258
+ RoyalBlue: '#4169E1',
259
+ SaddleBrown: '#8B4513',
260
+ Salmon: '#FA8072',
261
+ SandyBrown: '#F4A460',
262
+ SeaGreen: '#2E8B57',
263
+ SeaShell: '#FFF5EE',
264
+ Sienna: '#A0522D',
265
+ Silver: '#C0C0C0',
266
+ SkyBlue: '#87CEEB',
267
+ SlateBlue: '#6A5ACD',
268
+ SlateGray: '#708090',
269
+ SlateGrey: '#708090',
270
+ Snow: '#FFFAFA',
271
+ SpringGreen: '#00FF7F',
272
+ SteelBlue: '#4682B4',
273
+ Tan: '#D2B48C',
274
+ Teal: '#008080',
275
+ Thistle: '#D8BFD8',
276
+ Tomato: '#FF6347',
277
+ Turquoise: '#40E0D0',
278
+ Violet: '#EE82EE',
279
+ Wheat: '#F5DEB3',
280
+ White: '#FFFFFF',
281
+ WhiteSmoke: '#F5F5F5',
282
+ Yellow: '#FFFF00',
283
+ YellowGreen: '#9ACD32'
284
+ }
285
+
286
+ String.prototype.csvLine=function(delimiter=",",quote='"'){
287
+ let i=this.length,j=i,charInQuote,result=[]
288
+ if(i==0) return result
289
+ delimiter:while(i--){
290
+ const char=this[i]
291
+ if(char==quote) {
292
+ j=i
293
+ quote:while(i--){
294
+ charInQuote=this[i]
295
+ if(charInQuote==quote){
296
+ if(!i) {
297
+ result.unshift(this.substring(i+1,j).replace(quote+quote,quote))
298
+ return result
299
+ }
300
+ charInQuote=this[--i]
301
+ if(charInQuote==quote) continue quote
302
+ if(charInQuote==delimiter) {
303
+ result.unshift(this.substring(i+2,j).replace(quote+quote,quote))
304
+ j=i
305
+ continue delimiter
306
+ }
307
+
308
+ throw Error("invalid csv on quotes at "+(i+1)+" to " + j)
309
+ }
310
+ }
311
+ } else if(char==delimiter) {
312
+ const v=this.substring(i+1,j)
313
+ result.unshift(v.length?isNaN(v)? v : Number(v):null)
314
+ j=i
315
+ }
316
+ }
317
+ const v=this.substring(i+1,j)
318
+ result.unshift(v.length?isNaN(v)? v : Number(v):null)
319
+ return result
320
+ }
321
+
322
+ String.prototype.csvFile=function(delimiter=",",quote='"'){
323
+ let i=this.length,j=i,charInQuote,result=[],line=[]
324
+ if(i==0) return result
325
+ line:while(i--){
326
+ delimiter:while(i--){
327
+ const char=this[i]
328
+ if(char=="\n") {
329
+ break delimiter
330
+ } else if(char==quote) {
331
+ j=i
332
+ quote:while(i--){
333
+ charInQuote=this[i]
334
+ if(charInQuote==quote){
335
+ if(!i) {
336
+ result.unshift(this.substring(i+1,j).replace(quote+quote,quote))
337
+ return result
338
+ }
339
+ charInQuote=this[--i]
340
+ if(charInQuote==quote) continue quote
341
+ if(charInQuote==delimiter) {
342
+ result.unshift(this.substring(i+2,j).replace(quote+quote,quote))
343
+ j=i
344
+ continue delimiter
345
+ }
346
+
347
+ throw Error("invalid csv on quotes at "+(i+1)+" to " + j)
348
+ }
349
+ }
350
+ } else if(char==delimiter) {
351
+ const v=this.substring(i+1,j)
352
+ result.unshift(v.length?isNaN(v)? v : Number(v):null)
353
+ j=i
354
+ }
355
+ }
356
+ const v=this.substring(i+1,j)
357
+ line.unshift(v.length?isNaN(v)? v : Number(v):null)
358
+ result.unshift(line)
359
+ }
360
+ return result
361
+ }
package/matrix/matrix.js CHANGED
@@ -14,7 +14,7 @@ function Matrix(rows,columns,fill) {
14
14
  return this;
15
15
  }
16
16
  if(rows instanceof Object) {
17
- Object.assign(this,rows);
17
+ Object.assign(this,rows);
18
18
  } else {
19
19
  this.rows=rows;
20
20
  this.columns=columns;
@@ -611,50 +611,4 @@ Matrix.prototype.transpose=function(){
611
611
  return matrix;
612
612
  }
613
613
 
614
- module.exports=Matrix;
615
-
616
- /*
617
- function setDataPoint(value,term,node,dp) {
618
- Object.assign(dp,{
619
- avg:0,
620
- count:0, =rows
621
- movingSum:0,
622
- movingSumSquared:0,
623
- movingSumCubed:0,
624
- outlier:false,
625
- sum:0,
626
- sumSquared:0,
627
- sumCubed:0,
628
- term:term,
629
- weightedMovingSum:0,
630
- exponentialWeightedMoving:[new EMA(0.25),new EMA(0.5),new EMA(0.75)]
631
- });
632
- };
633
- dp.max=Math.max(dp.max||value,value);
634
- dp.min=Math.min(dp.min||value,value);
635
- dp.range=dp.max-dp.min;
636
- dp.sum+=value;
637
- dp.sumSquared+=Math.pow(value,2);
638
- dp.sumCubed+=Math.pow(value,3);
639
- dp.movingSum+=value-removedValue;
640
- dp.movingSumSquared+=Math.pow(value,2)-Math.pow(removedValue,2);
641
- dp.movingSumCubed+=Math.pow(value,3)-Math.pow(removedValue,3);
642
- // dp.avg=dp.sum/this.rows;
643
- const avg=dp.avg;
644
- dp.normalised=dp.range ? (value-avg)/dp.range : 0;
645
- // dp.movingAvg=dp.movingSum/values.length;
646
- // dp.variance=dp.sumSquared/count - Math.pow(avg,2);
647
- // dp.stdDev=Math.sqrt(dp.variance);
648
- dp.movingVariance=dp.movingSumSquared/values.length - Math.pow(dp.movingAvg,2);
649
- dp.movingStdDev=Math.sqrt(dp.movingVariance);
650
- dp.median=functions.median(values);
651
- dp.standardized=( (value-avg)/dp.stdDev )||0;
652
- dp.movingStandardized=( (value-dp.movingAvg)/dp.movingStdDev )||0;
653
- dp.skewness=(dp.sumCubed-3*avg*dp.variance-Math.pow(avg,3))/dp.variance*dp.stdDev;
654
- dp.movingSkewness=(dp.movingSumCubed-3*dp.movingAvg*dp.movingVariance-Math.pow(dp.movingAvg,3))/dp.movingVariance*dp.stdDev;
655
- dp.outlier=node.outliersFunction(node,dp,value);
656
- dp.weightedMovingSum+=count*value;
657
- dp.weightedMovingAvg=(dp.weightedMovingAvg*2/count)/(count+1);
658
- dp.exponentialWeightedMoving.forEach(c=>c.sample(value));
659
- }
660
- */
614
+ module.exports=Matrix;
@@ -0,0 +1,8 @@
1
+ const getBarGauge=(max,min)=>{
2
+ return {action:"g",id:"barGauge",children:[
3
+ defs,
4
+ {action:"rect",x:x,y:y,width:width,height:height,children:[
5
+ {action:"animate",attributeName:"transform",values:"0;5;0",dur:"10s",repeatCount:"indefinite"}
6
+ ]},
7
+ ]}
8
+ }
@@ -0,0 +1,29 @@
1
+ function Dataset(settings) {
2
+ Object.assign(this,{values:[]},settings)
3
+ }
4
+ Dataset.prototype.addValue=function(v){
5
+ if(this.min==null) {
6
+ this.max=v
7
+ this.min=v
8
+ this.range=0
9
+ this.average=v
10
+ } else {
11
+ if(this.min>v){
12
+ this.min=v
13
+ this.range=this.max-this.min
14
+ } else if(this.max<v){
15
+ this.max=v
16
+ this.range=this.max-this.min
17
+ }
18
+ this.average+=(v-this.average)/(this.values.length+1)
19
+ }
20
+ this.values.push(v)
21
+ }
22
+ Dataset.prototype.getMax=function(){return this.max}
23
+ Dataset.prototype.getMin=function(){return this.min}
24
+ Dataset.prototype.getAverage=function(){return this.average}
25
+ Dataset.prototype.getFirst=function(){return this.values[0]}
26
+ Dataset.prototype.getRange=function(){return this.range}
27
+ Dataset.prototype.getLast=function(){return this.value.slice(-1)}
28
+
29
+ module.exports=Dataset
@@ -0,0 +1,109 @@
1
+ const defs=require("./defs.js")
2
+ const DialNeedle=require("./DialNeedle.js")
3
+ const boundValue=(v,max=100,min=0)=>Math.min(Math.max(v, min), max)
4
+ const pi2=2 * Math.PI
5
+ const pi2DegreeFactor=180 / Math.PI
6
+ const toRadians=(degrees)=> degrees / pi2DegreeFactor
7
+ const toDegrees=(radians)=> radians * pi2DegreeFactor
8
+ function DialGauge(settings) {
9
+ Object.assign(this,{radius:100,value:0,gapAngle:80,color:"gray",min:0,max:100,title:"%"},settings)
10
+ this.range=this.max-this.min
11
+ if(this.range<=0) throw Error("invalid range, min>=max")
12
+ this.strokeWidth = this.radius * 0.3;
13
+ this.circumference = this.radius * pi2
14
+ this.dashOffset = this.circumference * this.gapAngle/380;
15
+ this.gaugeAngleArea=360-this.gapAngle
16
+ this.angleFactor=this.gaugeAngleArea/this.range
17
+ this.halfStrokeGap=(this.circumference-this.dashOffset)/2
18
+ this.strokeInnerRadius=this.radius - this.strokeWidth / 2
19
+ this.strokeInnerCircumference= this.strokeInnerRadius * pi2
20
+ this.strokeDashOffset = this.strokeInnerCircumference * this.gaugeAngleArea/360;
21
+ this.gauge={action:"circle",fill:"transparent",
22
+ cx:this.radius,cy:this.radius,r:this.strokeInnerRadius,stroke:"lightgray","stroke-width":this.strokeWidth,
23
+ "stroke-dasharray":this.getDashArray(this.max),
24
+ transform:{rotate:{angle:90+parseInt(this.gapAngle/2),x:this.radius,y:this.radius}}}
25
+ this.needle=new DialNeedle({radius:this.radius,startAngle:-this.gaugeAngleArea/2})
26
+ this.svg=this.getSvg()
27
+ }
28
+ DialGauge.prototype.get=function(value){
29
+ return this.svg
30
+ }
31
+ DialGauge.prototype.getSvg=function(){
32
+ const group=[]
33
+ group.push(Object.assign({},this.gauge,{stroke:"red"}))
34
+ group.push(Object.assign({},this.gauge,{stroke:"orange","stroke-dasharray":this.getDashArray(80)}))
35
+ group.push(Object.assign({},this.gauge,{stroke:"yellow","stroke-dasharray":this.getDashArray(60)}))
36
+ group.push(Object.assign({},this.gauge,{stroke:"lightgreen","stroke-dasharray":this.getDashArray(40)}))
37
+ group.push(Object.assign({},this.gauge,{stroke:"green","stroke-dasharray":this.getDashArray(20)}))
38
+ group.push(Object.assign({},this.gauge,{id:"dialColor",stroke:"lightgray","stroke-dasharray":this.getDashArrayReverse(0)}))
39
+ /*
40
+ group.push({action:"clipPath",id:"clipGauge",children:[
41
+ Object.assign({},this.gauge,{id:"dialColor1","stroke-dasharray":this.getDashArray(0),"stroke-miterlimit":"10",stroke:"none",class:"heatGrad"})
42
+ ]})
43
+ group.push({action:"style",children:["circle.heatGrad {background: conic-gradient(red, orange, yellow, green); }"]})
44
+ group.push({action:"use",href:{id:"clipGauge"}})
45
+ */
46
+ group.push(this.getScale())
47
+ group.push({action:"text",x:this.radius,y:this.radius*1.5,"dominant-baseline":"middle","text-anchor":"middle",children:[this.title]})
48
+ group.push(this.needle.get(0))
49
+ return {action:"g",height:2*this.radius,children:[group]}
50
+ /*
51
+ {action:"clipPath",children:[
52
+ Object.assign({},this.gauge,{id:"dialColor","stroke-dasharray":this.getDashArray(0),stroke:"none",class:"grad"})
53
+ ]},
54
+ {action:"style",children:["circle.grad {background: conic-gradient(red, orange, yellow, green); }"]},
55
+ {action:"setConicGradient",id:"clip"},
56
+ */
57
+ }
58
+
59
+ DialGauge.prototype.getUpdate=function(value){
60
+ return [this.needle.getUpdate((value-this.min)*this.angleFactor),{action:"update",id:"dialColor","stroke-dasharray":this.getDashArrayReverse(value)}]
61
+ }
62
+ DialGauge.prototype.setMax=function(value){
63
+ this.max = value
64
+ this.range=this.max-this.min
65
+ if(this.range<=0) throw Error("invalid range, min>=max")
66
+ this.angleFactor=this.gaugeAngleArea/this.range
67
+ return this
68
+ }
69
+ DialGauge.prototype.getDashArray=function(value){
70
+ const ratio=(value-this.min)/this.range
71
+ const dash=this.strokeDashOffset*ratio
72
+ const gap=this.strokeInnerCircumference-dash
73
+ return dash+","+gap
74
+ }
75
+ DialGauge.prototype.getDashArrayReverse=function(value){
76
+ const ratio=(value-this.min)/this.range
77
+ const gap=this.strokeDashOffset*ratio
78
+ const dash=this.strokeDashOffset*(1-ratio)
79
+ return "0,"+gap+","+dash+","+this.strokeDashOffset
80
+ }
81
+
82
+ DialGauge.prototype.getScale=function() {
83
+ const sr1 = this.radius;
84
+ const sr2 = this.radius - this.strokeWidth-5;
85
+ const srT = sr2 - 10;
86
+ const objDef=[]
87
+ let n = 0;
88
+ const increment=toRadians(this.gaugeAngleArea/10)
89
+ for (let sr = toRadians(-this.gaugeAngleArea); sr <= 0; sr += increment) {
90
+ const sra=sr + toRadians(90 - this.gapAngle/2)
91
+ const saCos=Math.cos(sra)
92
+ const saSin=Math.sin(sra)
93
+ objDef.push({action:"line",
94
+ x1:this.radius + sr1 * saCos,
95
+ y1:this.radius + sr1 * saSin,
96
+ x2:this.radius + sr2 * saCos,
97
+ y2:this.radius + sr2 * saSin}
98
+ )
99
+ objDef.push({action:"text",
100
+ x:this.radius + srT * saCos,
101
+ y:this.radius + srT * saSin,
102
+ children:[String(n*10)]
103
+ })
104
+ n++
105
+ }
106
+ return objDef;
107
+ }
108
+
109
+ module.exports=DialGauge
@@ -0,0 +1,36 @@
1
+ function DialNeedle(settings) {
2
+ Object.assign(this,{
3
+ radius:100,
4
+ startAngle:0,
5
+ id:"needle",
6
+ baseDialSize:20,
7
+ value:{min:0,max:100}
8
+ },settings)
9
+ Object.assign(this,{
10
+ endAngle:this.endAngle??360-this.startAngle,
11
+ center:this.center??{x:this.radius,y:this.radius}
12
+ })
13
+ this.value.range=this.value.max-this.value.min
14
+ this.ratio=(this.endAngle-this.startAngle)/this.range,
15
+ this.svg=this.getSvg();
16
+ }
17
+ DialNeedle.prototype.get=function(value){
18
+ return this.svg
19
+ }
20
+ DialNeedle.prototype.getSvg=function(id=""){
21
+ return {action:"g",id:id+this.id,children:[
22
+ {action:"path",transform:{rotate:{angle:this.startAngle,x:this.radius,y:this.radius}},d:[
23
+ {action:"moveTo",x:this.radius,y:0},
24
+ {action:"deltaLineTo",x:-this.baseDialSize,y:this.radius},
25
+ {action:"deltaArc",radius:{x:this.baseDialSize,y:this.baseDialSize},x:this.baseDialSize*2,y:0},
26
+ {action:"Z"}
27
+ ],
28
+ fill:this.color,stroke:this.color
29
+ }
30
+ ]}
31
+ }
32
+ DialNeedle.prototype.getUpdate=function(angle){
33
+ if(angle>360 || angle < -360) throw Error("angle > 360 or < -360, angle: "+angle)
34
+ return {action:"update",id:this.id,transform:{rotate:{angle,x:this.radius,y:this.radius}}}
35
+ }
36
+ module.exports=DialNeedle
@@ -0,0 +1,74 @@
1
+ const Format={
2
+ NumberToAbbreviated:(value)=>{
3
+ if(typeof value!='number') value=parseFloat(value);
4
+ if (value>Math.pow(10,16)) return Math.round(value/Math.pow(10,15)).toString()+'P'
5
+ if (value>Math.pow(10,13)) return Math.round(value/Math.pow(10,12)).toString()+'T'
6
+ if (value>Math.pow(10,10)) return Math.round(value/Math.pow(10,9)).toString()+'G'
7
+ if (value>Math.pow(10,7)) return Math.round(value/Math.pow(10,6)).toString()+'M'
8
+ if (value>Math.pow(10,4)) return Math.round(value/Math.pow(10,3)).toString()+'K'
9
+ if (value == Math.round(value)) return value.toString()
10
+ if (value>=10000) return value.toFixed(0).toString()
11
+ if (value>=1000) return value.toFixed(1).toString()
12
+ if (value>=100) return value.toFixed(2).toString()
13
+ if (value>=10) return value.toFixed(3).toString()
14
+ return value.toString()
15
+ },
16
+ HexToString: (value)=>{
17
+ if(value==null) return null;
18
+ let valueString = '';
19
+ for (let i = 0; i < value.length; i += 2)
20
+ valueString += String.fromCharCode(parseInt(value.substr(i, 2), 16));
21
+ return valueString;
22
+ },
23
+ padLeadZero:(value,size)=>"000000000000".substr(0,size-value.toString().length)+value,
24
+ toString:(type,value)=>{
25
+ switch (type) {
26
+ case 'timestamp' :
27
+ case 'datetime' :
28
+ case 'time' :
29
+ case 'date' :
30
+ var ts = new Date();
31
+ ts.setTime(parseInt(value));
32
+ var axisLabel='';
33
+ switch (this.dataType[0]) {
34
+ case 'timestamp' :
35
+ case 'date' :
36
+ case 'datetime' :
37
+ if (this.precision[0] >= 1440) axisLabel+=ts.getFullYear()+'-';
38
+ if (this.precision[0] >= 1440) axisLabel+=Format.padLeadZero(ts.getMonth()+1,2)+'-';
39
+ if (this.precision[0] >= 1440) axisLabel+=Format.padLeadZero(ts.getDate(),2);
40
+ if (this.precision[0] >= 1440) axisLabel+=' ';
41
+ case 'time' :
42
+ if (this.precision[0] >= 360) axisLabel+=Format.padLeadZero(ts.getHours(),2)+':';
43
+ if (this.precision[0] >= 60) axisLabel+=Format.padLeadZero(ts.getMinutes(),2)+':';
44
+ if (this.precision[0] >= 1) axisLabel+=Format.padLeadZero(ts.getSeconds(),2);
45
+ }
46
+ return axisLabel;
47
+ case 'int' :
48
+ case 'real' :
49
+ case 'number' :
50
+ return format.NumberToAbbreviated(value)
51
+ }
52
+ return value.toString();
53
+ },
54
+ StringToHex:(value)=>{
55
+ if(value==null) return null;
56
+ let hex = '';
57
+ for(let i=0;i<value.length;i++)
58
+ hex += ''+value.charCodeAt(i).toString(16);
59
+ return hex;
60
+ },
61
+ xmlEncodeString(value) {
62
+ if(value==null) return null;
63
+ return value.toString().replace(/([\&"<>])/g, function(str, item) {
64
+ return {
65
+ '&': '&amp;',
66
+ '"': '&quot;',
67
+ '<': '&lt;',
68
+ '>': '&gt;'
69
+ }[item];
70
+ });
71
+ }
72
+ }
73
+
74
+ module.exports=Format
@@ -0,0 +1,14 @@
1
+ function centerElement(elementIdToCenter) {
2
+ if(elementIdToCenter == null) return;
3
+ const toCenter = document.getElementById(elementIdToCenter);
4
+ const width = toCenter.getWidth();
5
+ const height = toCenter.getHeight();
6
+ const elementParent = toCenter.ancestors();
7
+ const Pwidth = elementParent[0].getWidth();
8
+ const Pheight = elementParent[0].getHeight();
9
+ width = parseInt(Pwidth/2, 10) - parseInt(width/2, 10);
10
+ height = parseInt(Pheight/2, 10) - parseInt(height/2, 10);
11
+ toCenter.setStyle({'top': height + 'px'});
12
+ toCenter.setStyle({'left': width + 'px'});
13
+ }
14
+ module.exports=centerElement