node-red-contrib-prib-functions 0.18.0 → 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 (87) 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 +22 -19
  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 +546 -0
  27. package/dataAnalysis/svd.js +239 -0
  28. package/documentation/loadInjector.png +0 -0
  29. package/echart/echart.html +68 -0
  30. package/echart/echart.js +85 -0
  31. package/echart/icons/chart-671.png +0 -0
  32. package/echart/lib/echarts.js +95886 -0
  33. package/lib/Chart.js +177 -0
  34. package/lib/Column.js +99 -0
  35. package/lib/GraphDB.js +14 -0
  36. package/lib/Table.js +185 -0
  37. package/lib/objectExtensions.js +361 -0
  38. package/matrix/matrix.js +50 -50
  39. package/matrix/matrixNode.html +144 -154
  40. package/matrix/matrixNode.js +26 -9
  41. package/monitor/BarGauge.js +8 -0
  42. package/monitor/Dataset.js +29 -0
  43. package/monitor/DialGauge.js +109 -0
  44. package/monitor/DialNeedle.js +36 -0
  45. package/monitor/Format.js +74 -0
  46. package/monitor/centerElement.js +14 -0
  47. package/monitor/compareElements.js +95 -0
  48. package/monitor/defs.js +23 -0
  49. package/monitor/extensions.js +906 -0
  50. package/monitor/functions.js +36 -0
  51. package/monitor/json2xml.js +103 -0
  52. package/monitor/monitorSystem.html +198 -0
  53. package/monitor/monitorSystem.js +322 -0
  54. package/monitor/svgHTML.js +179 -0
  55. package/monitor/svgObjects.js +64 -0
  56. package/package.json +31 -8
  57. package/test/00-objectExtensions.js +94 -0
  58. package/test/01-base.js +88 -0
  59. package/test/04-tables.js +33 -0
  60. package/test/data/.config.nodes.json +608 -0
  61. package/test/data/.config.nodes.json.backup +608 -0
  62. package/test/data/.config.runtime.json +4 -0
  63. package/test/data/.config.runtime.json.backup +3 -0
  64. package/test/data/.config.users.json +21 -0
  65. package/test/data/.config.users.json.backup +21 -0
  66. package/test/data/.flow.json.backup +3433 -0
  67. package/test/data/float32vector10.npy +0 -0
  68. package/test/data/flow.json +3433 -0
  69. package/test/data/int2matrix2x3.npy +0 -0
  70. package/test/data/package-lock.json +158 -0
  71. package/test/data/package.json +11 -0
  72. package/test/data/settings.js +544 -0
  73. package/test/dataAnalysisExtensions.js +472 -0
  74. package/test/dataAnalysisPCA.js +54 -0
  75. package/test/dataAnalysisSVD.js +31 -0
  76. package/test/euclideanDistance.js +2 -2
  77. package/test/matrix/02base.js +36 -0
  78. package/test/transformNumPy.js +132 -0
  79. package/testing/data/countries.csv +250 -0
  80. package/testing/hostAvailable.html +0 -2
  81. package/testing/load-injector.html +76 -21
  82. package/testing/load-injector.js +35 -54
  83. package/testing/test.js +1 -0
  84. package/transform/NumPy.js +303 -0
  85. package/transform/transform.html +73 -19
  86. package/transform/transform.js +144 -8
  87. package/documentation/LoadInjector.JPG +0 -0
@@ -35,7 +35,7 @@ jobs:
35
35
 
36
36
  steps:
37
37
  - name: Checkout repository
38
- uses: actions/checkout@v2
38
+ uses: actions/checkout@v4
39
39
 
40
40
  # Initializes the CodeQL tools for scanning.
41
41
  - name: Initialize CodeQL
@@ -50,7 +50,7 @@ jobs:
50
50
  # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
51
51
  # If this step fails, then you should remove it and run the build manually (see below)
52
52
  - name: Autobuild
53
- uses: github/codeql-action/autobuild@v1
53
+ uses: github/codeql-action/autobuild@v3
54
54
 
55
55
  # ℹ️ Command-line programs to run using the OS shell.
56
56
  # 📚 https://git.io/JvXDl
@@ -64,4 +64,4 @@ jobs:
64
64
  # make release
65
65
 
66
66
  - name: Perform CodeQL Analysis
67
- uses: github/codeql-action/analyze@v1
67
+ uses: github/codeql-action/analyze@v3
@@ -11,10 +11,10 @@ jobs:
11
11
  build:
12
12
  runs-on: ubuntu-latest
13
13
  steps:
14
- - uses: actions/checkout@v2
15
- - uses: actions/setup-node@v1
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-node@v4
16
16
  with:
17
- node-version: 12
17
+ node-version: 'latest'
18
18
  - run: npm ci
19
19
  - run: npm test
20
20
 
@@ -22,10 +22,10 @@ jobs:
22
22
  needs: build
23
23
  runs-on: ubuntu-latest
24
24
  steps:
25
- - uses: actions/checkout@v2
26
- - uses: actions/setup-node@v1
25
+ - uses: actions/checkout@v4
26
+ - uses: actions/setup-node@v4
27
27
  with:
28
- node-version: 12
28
+ node-version: 'latest'
29
29
  registry-url: https://registry.npmjs.org/
30
30
  - run: npm ci
31
31
  - run: npm publish
@@ -0,0 +1,7 @@
1
+ {
2
+ "ExpandedNodes": [
3
+ ""
4
+ ],
5
+ "SelectedNode": "\\C:\\Users\\peter\\Source\\Repos\\node-red-contrib-prib-functions",
6
+ "PreviewInSolutionExplorer": false
7
+ }
package/README.md CHANGED
@@ -44,6 +44,9 @@ Single value metrics:
44
44
  Array metrics:
45
45
  * Deltas
46
46
  * Deltas Normalised
47
+ * difference
48
+ * difference seasonal
49
+ * difference seasonal second order
47
50
  * Moving Average Simple (SMA)
48
51
  * Moving Average Cumulative (CMA)
49
52
  * Moving Average Weighted (WMA)
@@ -53,8 +56,9 @@ Array metrics:
53
56
 
54
57
  Array data
55
58
  * distances
56
- * minimum distance(s) between points
57
- * maximum distance(s) between points
59
+ * distance(s) minimum between points
60
+ * distance(s) maximum between points
61
+
58
62
 
59
63
  ![Data Analysis](documentation/DataAnalysis.JPG "Data Analysis")
60
64
 
@@ -111,8 +115,12 @@ Transformations:
111
115
  * Array to ISO8385
112
116
  * Array to Messages
113
117
  * Array to xlsx / xlsx object (excel uses [xlsx][7])
114
- * AVRO to JSON (uses [avsc][6])
118
+ * AVRO to JSON (uses [avsc][6])
119
+ * Buffer to comprossed
115
120
  * Confluence to JSON
121
+ * Compressed to Buffer
122
+ * Compressed to String
123
+ * COmpressed to JSON
116
124
  * CSV to Array
117
125
  * CSV to HTML
118
126
  * CSV to Messages
@@ -199,7 +207,13 @@ The levenshtein distance between two character strings.
199
207
  Inject messages for a set period of time with varying think time.
200
208
  Primary purpose is testing and useful for load/stress testing.
201
209
 
202
- ![Load Injector](documentation/LoadInjector.JPG "Load Injector")
210
+ Has 3 extra data types
211
+ 1. generated id - Unique id for each message
212
+ 2. generated data - string text generated using [dummy-json][3]
213
+ 3. generated json - json generated using [dummy-json][3]
214
+
215
+
216
+ ![Load Injector](documentation/loadInjector.png "Load Injector")
203
217
 
204
218
  Test example:
205
219
 
@@ -278,27 +292,14 @@ Test/example flow in test/generalTest.json
278
292
 
279
293
  # Version
280
294
 
295
+ 0.19.0 Improve load injector, fix bug in test comparing buffers, add compression tranforms
296
+
281
297
  0.18.0 Add matrix node
282
298
 
283
299
  0.17.0 Add finished wire to load injector
284
300
 
285
- 0.16.10 data analysis add eulcidean distance functions. Add array pairs
286
-
287
301
  0.16.0 fix data analysis variance and stddev, add sample, add tests
288
302
 
289
- 0.14.2 fix general test flows. Add icon for data analysis
290
-
291
- 0.14.1 fix capitalization issue with levenshtein Distance
292
-
293
- 0.14.0 add xlsx transformer
294
-
295
- 0.13.0 Confluence AVRO message converter
296
-
297
- 0.12.0 added xml to json and json to xml. Make snappy installed separately as can cause install issues
298
-
299
- 0.11.1 Fix spelling of AVRO.
300
-
301
- 0.11.0 Transform for AVRO and snappy. Add JSON to CSV
302
303
 
303
304
 
304
305
  # Author
@@ -318,3 +319,5 @@ Test/example flow in test/generalTest.json
318
319
  [6]: https://www.npmjs.com/package/avsc "avsc"
319
320
 
320
321
  [7]: https://www.npmjs.com/package/xlsx "xlsx"
322
+
323
+ [8]: https://www.npmjs.com/package/dummy-json "dummy-json"
package/arima/index.js ADDED
@@ -0,0 +1,18 @@
1
+ const observations=[]
2
+
3
+
4
+
5
+ if(Array.prototype.differenceSeasonalSecondOrder ==null)
6
+ Object.defineProperty(Array.prototype, "differenceSeasonalSecondOrder", {
7
+ value(lag) {
8
+ let i=result.length-lag-1
9
+ const result=new Array(size)
10
+ while(i--) {
11
+ const ilag=i-lag
12
+ result[i]=this[i]-this[i+1]-this[iLag]+this[iLag+1]
13
+ }
14
+ return result;
15
+ },
16
+ writable: true,
17
+ configurable: true
18
+ });
@@ -0,0 +1,15 @@
1
+ if(Array.prototype.allRowsSwap==null)
2
+ Object.defineProperty(Array.prototype, "allRowsSwap", {
3
+ value(x,y) {
4
+ const l=this.length;
5
+ for(let i=0; i<l; i++) {
6
+ const row=this[i]
7
+ const temp = row[x];
8
+ row[x] = row[y];
9
+ row[y] = temp;
10
+ }
11
+ return this;
12
+ },
13
+ writable: true,
14
+ configurable: true
15
+ });
@@ -0,0 +1,34 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.compareToPrecision==null)
3
+ Object.defineProperty(object.prototype, "compareToPrecision", {
4
+ value(toArray,precision=6) {
5
+ const basePrecision=Math.pow(10,-precision);
6
+ if(this.length!=toArray.length) throw Error("array length different")
7
+ this.forEach((element,index)=>{
8
+ const toElement=toArray[index];
9
+ if(typeof element !== typeof toElement) throw Error("types no same for "+index)
10
+ if(typeof element == "array"){
11
+ element.compareToPrecision(toElement,precision)
12
+ return
13
+ }
14
+ switch (typeof element) {
15
+ case "array":
16
+ try{
17
+ element.compareRounded(toElement,precision)
18
+ } catch(ex) {
19
+ throw Error(index+","+ex.message)
20
+ }
21
+ return;
22
+ default:
23
+ const diff = Math.abs(element-toElement) ;
24
+ // console.log({diff:diff,basePrecision:basePrecision})
25
+ if(Math.abs(element-toElement)/element > basePrecision)
26
+ throw Error(index+ " failed "+element+" <> "+toElement);
27
+ }
28
+ });
29
+ },
30
+ writable: true,
31
+ configurable: true
32
+ });
33
+
34
+ });
@@ -0,0 +1,14 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.difference==null)
3
+ Object.defineProperty(object.prototype, "difference", {
4
+ value(order=0) {
5
+ let i=this.length
6
+ if(i<2) return new object()
7
+ const result=new object(i-1)
8
+ while(--i) result[i-1]=this[i]-this[i-1];
9
+ return order?result.difference(--order):result;
10
+ },
11
+ writable: true,
12
+ configurable: true
13
+ });
14
+ })
@@ -0,0 +1,15 @@
1
+
2
+ [Array,Float32Array,Float64Array].forEach(object=>{
3
+ if(object.prototype.differenceSeasonal==null)
4
+ Object.defineProperty(object.prototype, "differenceSeasonal", {
5
+ value(lag=1,order=0) {
6
+ let i=this.length-lag
7
+ if(i<1) return new object()
8
+ const result=new object(i)
9
+ while(--i>=0) result[i]=this[i+lag]-this[i];
10
+ return order?result.difference(--order):result;
11
+ },
12
+ writable: true,
13
+ configurable: true
14
+ });
15
+ })
@@ -0,0 +1,20 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.differenceSeasonalSecondOrder==null)
3
+ Object.defineProperty(object.prototype, "differenceSeasonalSecondOrder", {
4
+ value(lag=1) {
5
+ let i=this.length-lag-1
6
+ if(i<1) return new object()
7
+ const result=new object(i)
8
+ let lastDiff=this[i+lag-1]-this[i-1]
9
+ while(--i>=0){
10
+ const newDiff=this[i+lag-1]-this[i-1]
11
+ result[i]=lastDiff-newDiff
12
+ lastDiff=newDiff
13
+ }
14
+ return result
15
+ },
16
+ writable: true,
17
+ configurable: true
18
+ });
19
+ })
20
+
@@ -0,0 +1,14 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.differenceSecondOrder==null)
3
+ Object.defineProperty(object.prototype, "differenceSecondOrder", {
4
+ value() {
5
+ let i=this.length-1
6
+ if(i<2) return new object()
7
+ const result=new object(i-1)
8
+ while(--i) result[i-1]=this[i-1]-2*this[i]+this[i+1]
9
+ return result;
10
+ },
11
+ writable: true,
12
+ configurable: true
13
+ });
14
+ })
@@ -0,0 +1,38 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.forEachRange==null)
3
+ Object.defineProperty(object.prototype, "forEachRange", {
4
+ value(start=0,end=this.length-1,func,o=this) {
5
+ if(start<=end) {
6
+ if(end>=this.length) throw Error("end offset "+end+" >= array length "+this.length);
7
+ if(start<0) throw Error("start offset "+start+"< 0");
8
+ for(let i=start;i<=end;i++) func(this[i],i,this)
9
+ } else {
10
+ if(start>=this.length) throw Error("end<start and start offset "+start+" >= array length "+this.length);
11
+ if(end<0) throw Error("end<start and end offset "+end+"< 0")
12
+ for(let i=start;i>=end;i--) func(this[i],i,this)
13
+ }
14
+ return this;
15
+ },
16
+ writable: true,
17
+ configurable: true
18
+ });
19
+ if(object.prototype.forEachRangeNotTested==null)
20
+ Object.defineProperty(object.prototype, "forEachRangeNotTested", {
21
+ value(start=0,end=this.length-1,func,o=this) {
22
+ if(start<=end) {
23
+ if(end>=this.length) end=this.length-1;
24
+ if(start<0) start=0;
25
+ for(let i=start;i<=end;i++) func(this[i],i,this)
26
+ } else {
27
+ if(start>=this.length) start=this.length-1
28
+ if(end<0) end=0
29
+ for(let i=start;i>=end;i--) func(this[i],i,this)
30
+ }
31
+ return this;
32
+ },
33
+ writable: true,
34
+ configurable: true
35
+ });
36
+
37
+ });
38
+
@@ -0,0 +1,13 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.overlay==null)
3
+ Object.defineProperty(object.prototype, "overlay", {
4
+ value(array) {
5
+ if(array[0] instanceof Array)
6
+ array.forEach((element,index)=>this[index].overlay(element));
7
+ else
8
+ array.forEach((element,index)=>this[index]=element);
9
+ },
10
+ writable: true,
11
+ configurable: true
12
+ });
13
+ });
@@ -0,0 +1,11 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.product==null)
3
+ Object.defineProperty(object.prototype, "product", {
4
+ value(i=0,end=this.length-1,product=this[i]) {
5
+ for(i++;i<=end;i++) product*=this[i];
6
+ return product;
7
+ },
8
+ writable: true,
9
+ configurable: true
10
+ });
11
+ })
@@ -0,0 +1,14 @@
1
+
2
+ [Array,Float32Array,Float64Array].forEach(object=>{
3
+ if(object.prototype.random==null)
4
+ Object.defineProperty(object.prototype, "random", {
5
+ value(size=this.length) {
6
+ let i=size
7
+ const result=new object(i)
8
+ while(i--) result[i]=Math.random();
9
+ return result;
10
+ },
11
+ writable: true,
12
+ configurable: true
13
+ })
14
+ })
@@ -0,0 +1,11 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.reduceRange==null)
3
+ Object.defineProperty(object.prototype, "reduceRange", {
4
+ value(start=0,end=this.length-1,func=(aggregate,cell,index)=>aggregate+cell,aggregate=0,o=this) {
5
+ for(let i=start;i<=end;i++) aggregate=func(aggregate,this[i],i,this)
6
+ return aggregate;
7
+ },
8
+ writable: true,
9
+ configurable: true
10
+ });
11
+ })
@@ -0,0 +1,11 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.scale==null)
3
+ Object.defineProperty(object.prototype, "scale", {
4
+ value(factor,start=0,end=this.length-1) {
5
+ for(let i=start;i<=end;i++) this[i]*=factor;
6
+ return this;
7
+ },
8
+ writable: true,
9
+ configurable: true
10
+ });
11
+ })
@@ -0,0 +1,11 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.sum==null)
3
+ Object.defineProperty(object.prototype, "sum", {
4
+ value(i=0,end=this.length-1,sum=0) {
5
+ for(;i<=end;i++) sum+=this[i];
6
+ return sum;
7
+ },
8
+ writable: true,
9
+ configurable: true
10
+ });
11
+ })
@@ -0,0 +1,11 @@
1
+ [Array,Float32Array,Float64Array].forEach(object=>{
2
+ if(object.prototype.sumSquared==null)
3
+ Object.defineProperty(object.prototype, "sumSquared", {
4
+ value(i=0,end=this.length-1,sum=0) {
5
+ for(;i<=end;i++) sum+=this[i]**2;
6
+ return sum;
7
+ },
8
+ writable: true,
9
+ configurable: true
10
+ });
11
+ })
@@ -0,0 +1,11 @@
1
+ if(Array.prototype.swap==null)
2
+ Object.defineProperty(Array.prototype, "swap", {
3
+ value(x,y) {
4
+ const temp = this[x];
5
+ this[x] = this[y];
6
+ this[y] = temp;
7
+ return this;
8
+ },
9
+ writable: true,
10
+ configurable: true
11
+ });
@@ -7,6 +7,7 @@
7
7
  name: {value:"",required:false},
8
8
  action: {value:"avg",required:true},
9
9
  columns:{value:"",required:false},
10
+ lag: {value:1,required:true},
10
11
  outputs: {value:(["realtime","realtimePredict"].includes(this.action)?3:2),required:true},
11
12
  outliersBase: {value:"avg",required:false},
12
13
  outliersStdDevs: {value:"3",required:false},
@@ -45,50 +46,56 @@
45
46
  }
46
47
  });
47
48
  $("#node-input-action").change(function() {
48
- if(["distances","distancesMax","distancesMin"].includes( $(this).val() )) {
49
+ if(["differenceSeasonal","differenceSeasonalSecondOrder"].includes( $(this).val() )) {
50
+ $(".form-row-http-in-lag").show();
51
+ } else {
52
+ $(".form-row-http-in-lag").hide();
53
+ }
54
+ if(["distances","distancesMax","distancesMin"].includes( $(this).val() )) {
49
55
  $(".form-row-http-in-columns").show();
50
- } else {
56
+ } else {
51
57
  $(".form-row-http-in-columns").hide();
52
- }
58
+ }
53
59
  if(["movingAvgSimple","movingAvgWeighted","movingAvgExponential","realtime","realtimePredict"].includes( $(this).val() )) {
54
60
  $(".form-row-http-in-term").show();
55
- } else {
61
+ } else {
56
62
  $(".form-row-http-in-term").hide();
57
- }
58
- if(["movingAvgExponential"].includes( $(this).val() )) {
63
+ }
64
+ if(["movingAvgExponential"].includes( $(this).val() )) {
59
65
  $("#node-input-term").attr({min:0,max:1,step:0.1});
60
66
  if(node.term<0 || node.term>1) $("#node-input-term").val(0.5);
61
67
  $("#node-input-term").change(function() {
62
68
  if(node.term<0) $(this).val(0);
63
69
  if(node.term>1) $(this).val(1);
64
70
  });
65
- } else {
71
+ } else {
66
72
  $("#node-input-term").attr({min:1,max:100,step:1});
67
73
  $("#node-input-term").change(function() {
68
74
  if(node.term<1) $(this).val(1);
69
75
  if(node.term>100) $(this).val(100);
70
76
  });
71
- }
72
- if(["realtime","realtimePredict"].includes( $(this).val() )) {
77
+ }
78
+ if(["realtime","realtimePredict"].includes( $(this).val() )) {
73
79
  node.outputs=3;
74
80
  $(".form-row-http-in-keyProperty").show();
75
81
  $(".form-row-http-in-outliersStdDevs").show();
76
82
  $(".form-row-http-in-outliersBase").show();
77
83
  $("#node-input-outliersStdDevs").change();
78
- } else {
84
+ } else {
79
85
  node.outputs=2;
80
86
  $(".form-row-http-in-keyProperty").hide();
81
87
  $(".form-row-http-in-outliersStdDevs").hide();
82
88
  $(".form-row-http-in-outliersBase").hide();
83
- }
84
- if(["pearsonR","covariance","corelationship"].includes( $(this).val() )) {
89
+ }
90
+ if(["pearsonR","covariance","corelationship"].includes( $(this).val() )) {
85
91
  $(".node-input-dataProperties-container-row").show();
86
92
  $(".form-row-http-in-dataProperty").hide();
87
- } else {
93
+ } else {
88
94
  $(".node-input-dataProperties-container-row").hide();
89
95
  $(".form-row-http-in-dataProperty").show();
90
- }
96
+ }
91
97
  $("#node-input-term").change();
98
+ $("#node-input-lag").change();
92
99
  });
93
100
 
94
101
  node.dataProperties.forEach((r)=>addDataProperty(r));
@@ -148,6 +155,10 @@
148
155
  <option value="corelationship">Corelationship</option>
149
156
  <option value="deltas">Deltas</option>
150
157
  <option value="deltaNormalised">Deltas Normalised</option>
158
+ <option value="difference">Difference</option>
159
+ <option value="differenceSeasonal">Difference Seasonal</option>
160
+ <option value="differenceSeasonalSecondOrder">Difference Seasonal Second Order</option>
161
+ <option value="differenceSecondOrder">Difference Second Order</option>
151
162
  <option value="distances">Euclidean Distances</option>
152
163
  <option value="distancesMax">Euclidean Distances Max</option>
153
164
  <option value="distancesMin">Euclidean Distances Min</option>
@@ -162,6 +173,7 @@
162
173
  <option value="movingAvgExponential">Moving Average Exponential (EMA/EWMA)</option>
163
174
  <option value="normalize">Normalise</option>
164
175
  <option value="pearsonR">Pearson Product Moment Correlation (PPMC)</option>
176
+ <option value="randomise">Randomise</option>
165
177
  <option value="range">Range</option>
166
178
  <option value="realtime">RealTime Metrics</option>
167
179
  <option value="realtimePredict">RealTime Metrics + predicts</option>
@@ -179,6 +191,11 @@
179
191
  <label for="node-input-columns"><i class="icon-bookmark"></i> Columns</label>
180
192
  <input type="text" id="node-input-columns" placeholder="columns">
181
193
  </div>
194
+
195
+ <div class="form-row form-row-http-in-lag hide">
196
+ <label for="node-input-lag"><i class="icon-bookmark"></i> Lag</label>
197
+ <input type="number" id="node-input-lag" placeholder="lag" min="1" max="10000" step="1">
198
+ </div>
182
199
 
183
200
  <div class="form-row form-row-http-in-term hide">
184
201
  <label for="node-input-term"><i class="icon-bookmark"></i> Term</label>
@@ -2,6 +2,11 @@ const logger = new (require("node-red-contrib-logger"))("Data Analysis");
2
2
  logger.sendInfo("Copyright 2020 Jaroslav Peter Prib");
3
3
 
4
4
  require("./arrayLast");
5
+ require("./arrayDifference")
6
+ require("./arrayDifferenceSeasonal")
7
+ require("./arrayDifferenceSeasonalSecondOrder")
8
+ require("./arrayDifferenceSecondOrder")
9
+ require("./arrayRandom")
5
10
  const ed=require("./euclideanDistance.js");
6
11
  require("./forNestedEach");
7
12
 
@@ -157,6 +162,10 @@ functions={
157
162
  },
158
163
  distancesMin: (d,term,node)=>ed.minDistances(d,getColumns(node)),
159
164
  distancesMax: (d,term,node)=>ed.maxDistances(d,getColumns(node)),
165
+ difference: (d)=>d.difference(),
166
+ differenceSeasonal: (d,term,node)=>d.differenceSeasonal(node.lag),
167
+ differenceSeasonalSecondOrder: (d,term,node)=>d.differenceSeasonalSecondOrder(node.lag),
168
+ differenceSecondOrder: (d)=>d.differenceSecondOrder(),
160
169
  max: (d)=> Math.max(...d),
161
170
  median:(d)=>{
162
171
  const i=Math.floor(d.length/2);
@@ -313,7 +322,7 @@ module.exports = function (RED) {
313
322
  }
314
323
  switch (node.action) {
315
324
  case "realtime":
316
- node.outliersStdDevs=Number.parseInt(node.outliersStdDevs,10)||3;
325
+ node.outliersStdDevs=Number.parseInt(node.outliersStdDevs,10)||3;
317
326
  if(![1,2,3].includes(node.outliersStdDevs)) throw Error("outlier std deviation "+node.outliersStdDevs+" not 1,2 or 3");
318
327
  const outliersFunction=(node.outliersBase||"avg")=="median";
319
328
  node.log("realtime outliersBase set avg "+outliersFunction);