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.
- package/.github/workflows/codeql-analysis.yml +3 -3
- package/.github/workflows/npmpublish.yml +6 -6
- package/.vs/VSWorkspaceState.json +7 -0
- package/.vs/node-red-contrib-prib-functions/v17/.wsuo +0 -0
- package/README.md +6 -2
- package/arima/index.js +18 -0
- package/dataAnalysis/arrayAllRowsSwap.js +15 -0
- package/dataAnalysis/arrayCompareToPrecision.js +34 -0
- package/dataAnalysis/arrayDifference.js +14 -0
- package/dataAnalysis/arrayDifferenceSeasonal.js +15 -0
- package/dataAnalysis/arrayDifferenceSeasonalSecondOrder.js +20 -0
- package/dataAnalysis/arrayDifferenceSecondOrder.js +14 -0
- package/dataAnalysis/arrayForEachRange.js +38 -0
- package/dataAnalysis/arrayOverlay.js +13 -0
- package/dataAnalysis/arrayProduct.js +11 -0
- package/dataAnalysis/arrayRandom.js +14 -0
- package/dataAnalysis/arrayReduceRange.js +11 -0
- package/dataAnalysis/arrayScale.js +11 -0
- package/dataAnalysis/arraySum.js +11 -0
- package/dataAnalysis/arraySumSquared.js +11 -0
- package/dataAnalysis/arraySwap.js +11 -0
- package/dataAnalysis/dataAnalysis.html +31 -14
- package/dataAnalysis/dataAnalysis.js +10 -1
- package/dataAnalysis/generateMatrixFunction.js +89 -0
- package/dataAnalysis/generateVectorFunction.js +25 -0
- package/dataAnalysis/pca.js +472 -325
- package/dataAnalysis/svd.js +239 -0
- package/echart/echart.html +68 -0
- package/echart/echart.js +85 -0
- package/echart/icons/chart-671.png +0 -0
- package/echart/lib/echarts.js +95886 -0
- package/lib/Chart.js +177 -0
- package/lib/Column.js +99 -0
- package/lib/GraphDB.js +14 -0
- package/lib/Table.js +185 -0
- package/lib/objectExtensions.js +361 -0
- package/matrix/matrix.js +2 -48
- package/monitor/BarGauge.js +8 -0
- package/monitor/Dataset.js +29 -0
- package/monitor/DialGauge.js +109 -0
- package/monitor/DialNeedle.js +36 -0
- package/monitor/Format.js +74 -0
- package/monitor/centerElement.js +14 -0
- package/monitor/compareElements.js +95 -0
- package/monitor/defs.js +23 -0
- package/monitor/extensions.js +906 -0
- package/monitor/functions.js +36 -0
- package/monitor/json2xml.js +103 -0
- package/monitor/monitorSystem.html +198 -0
- package/monitor/monitorSystem.js +322 -0
- package/monitor/svgHTML.js +179 -0
- package/monitor/svgObjects.js +64 -0
- package/package.json +18 -6
- package/test/00-objectExtensions.js +94 -0
- package/test/04-tables.js +33 -0
- package/test/data/.config.nodes.json +608 -0
- package/test/data/.config.nodes.json.backup +608 -0
- package/test/data/.config.runtime.json +4 -0
- package/test/data/.config.runtime.json.backup +3 -0
- package/test/data/.config.users.json +21 -0
- package/test/data/.config.users.json.backup +21 -0
- package/test/data/.flow.json.backup +2448 -2207
- package/test/data/float32vector10.npy +0 -0
- package/test/data/flow.json +2412 -2191
- package/test/data/int2matrix2x3.npy +0 -0
- package/test/data/package-lock.json +158 -0
- package/test/data/package.json +11 -0
- package/test/dataAnalysisExtensions.js +472 -0
- package/test/dataAnalysisPCA.js +54 -0
- package/test/dataAnalysisSVD.js +31 -0
- package/test/euclideanDistance.js +2 -2
- package/test/transformNumPy.js +132 -0
- package/transform/NumPy.js +303 -0
- package/transform/transform.html +12 -0
- package/transform/transform.js +34 -2
|
@@ -35,7 +35,7 @@ jobs:
|
|
|
35
35
|
|
|
36
36
|
steps:
|
|
37
37
|
- name: Checkout repository
|
|
38
|
-
uses: actions/checkout@
|
|
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@
|
|
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@
|
|
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@
|
|
15
|
-
- uses: actions/setup-node@
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: actions/setup-node@v4
|
|
16
16
|
with:
|
|
17
|
-
node-version:
|
|
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@
|
|
26
|
-
- uses: actions/setup-node@
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
- uses: actions/setup-node@v4
|
|
27
27
|
with:
|
|
28
|
-
node-version:
|
|
28
|
+
node-version: 'latest'
|
|
29
29
|
registry-url: https://registry.npmjs.org/
|
|
30
30
|
- run: npm ci
|
|
31
31
|
- run: npm publish
|
|
Binary file
|
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
|
-
*
|
|
57
|
-
*
|
|
59
|
+
* distance(s) minimum between points
|
|
60
|
+
* distance(s) maximum between points
|
|
61
|
+
|
|
58
62
|
|
|
59
63
|

|
|
60
64
|
|
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
|
+
})
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
61
|
+
} else {
|
|
56
62
|
$(".form-row-http-in-term").hide();
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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);
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
function generatedMatrixFunction(arg1) {
|
|
2
|
+
if(typeof arg1 !=="object") throw Error("no definitional JSON found");
|
|
3
|
+
Object.assign(this,{
|
|
4
|
+
args:[],
|
|
5
|
+
dimensionOrder:["row","column"],
|
|
6
|
+
returnValue:"this",
|
|
7
|
+
debug:false
|
|
8
|
+
},arg1);
|
|
9
|
+
const extendedArgs=[
|
|
10
|
+
this.dimensionOrder[0]+"StartOffset=0",
|
|
11
|
+
this.dimensionOrder[0]+"EndOffset",
|
|
12
|
+
this.dimensionOrder[1]+"StartOffset=0",
|
|
13
|
+
this.dimensionOrder[1]+"EndOffset",
|
|
14
|
+
"returnValue="+this.returnValue,
|
|
15
|
+
"matrixEndOffset=matrix.length-1",
|
|
16
|
+
"rowOffset",
|
|
17
|
+
"columnOffset",
|
|
18
|
+
"rowVectorOffset",
|
|
19
|
+
"columnVectorOffset",
|
|
20
|
+
"elementOffset",
|
|
21
|
+
"element",
|
|
22
|
+
"getElementArray=()=>matrix[rowOffset][columnOffset]",
|
|
23
|
+
"getElementVector=()=>matrix[elementOffset]",
|
|
24
|
+
"setElementArray=(v)=>matrix[rowOffset][columnOffset]=v",
|
|
25
|
+
"setElementVector=(v)=>matrix[elementOffset]=v",
|
|
26
|
+
"getElement=getElementVector",
|
|
27
|
+
"setElement=setElementVector",
|
|
28
|
+
"getMatrix=()=>Object.create(Object.getPrototypeOf(matrix))",
|
|
29
|
+
"arrayFunctions={"+
|
|
30
|
+
"forEachRowColumn:(call)=>{for(rowOffset=0;rowOffset<=rowEndOffset;rowOffset++) call()},"+
|
|
31
|
+
"forEachColumnRow:(call)=>{for(columnOffset=0;columnOffset<=columnEndOffset;columnOffset++) call()}"+
|
|
32
|
+
"}",
|
|
33
|
+
"vectorFunctions={}"
|
|
34
|
+
];
|
|
35
|
+
const functionCode=
|
|
36
|
+
"("+["matrix","rows",
|
|
37
|
+
"columns"
|
|
38
|
+
].concat(this.args,extendedArgs).join()+
|
|
39
|
+
")=>{\n"+
|
|
40
|
+
" const isArray=(matrix!==null&&matrix instanceof Array)\n"+
|
|
41
|
+
" if(isArray){\n"+
|
|
42
|
+
" rows=matrix.length\n"+
|
|
43
|
+
" columns=matrix[0].length\n"+
|
|
44
|
+
" getElement=getElementArray\n"+
|
|
45
|
+
" setElement=setElementArray\n"+
|
|
46
|
+
" }\n"+
|
|
47
|
+
" if(rows<=0) throw Error('rows < 1')\n"+
|
|
48
|
+
" if(columns<=0) throw Error('rows < 1')\n"+
|
|
49
|
+
" if(rowEndOffset==null) rowEndOffset=rows-1\n"+
|
|
50
|
+
" if(columnEndOffset==null) columnEndOffset=columns-1\n"+
|
|
51
|
+
(this.debug?"console.log({matrix:matrix,matrixEndOffset:matrixEndOffset,rowEndOffset:rowEndOffset,columnEndOffset:columnEndOffset,rows:rows,columns:columns})\n":"")+
|
|
52
|
+
" if(isArray){\n"+
|
|
53
|
+
" for("+this.dimensionOrder[0]+"Offset="+this.dimensionOrder[0]+"StartOffset;"+this.dimensionOrder[0]+"Offset<="+this.dimensionOrder[0]+"EndOffset;"+this.dimensionOrder[0]+"Offset++){\n"+
|
|
54
|
+
" const "+this.dimensionOrder[0]+"=matrix["+this.dimensionOrder[0]+"Offset]\n"+
|
|
55
|
+
(this.debug?"console.log({"+this.dimensionOrder[0]+"Offset:"+this.dimensionOrder[0]+"Offset,})\n":"")+"\n"+
|
|
56
|
+
" for("+this.dimensionOrder[1]+"Offset="+this.dimensionOrder[1]+"StartOffset;"+this.dimensionOrder[1]+"Offset<="+this.dimensionOrder[1]+"EndOffset;"+this.dimensionOrder[1]+"Offset++){\n"+
|
|
57
|
+
" const element=matrix["+this.dimensionOrder[1]+"Offset]\n"+
|
|
58
|
+
(this.debug?"console.log({"+this.dimensionOrder[1]+"Offset:"+this.dimensionOrder[1]+"Offset,element:element})\n":"")+
|
|
59
|
+
this.code+"\n"+
|
|
60
|
+
" }\n"+
|
|
61
|
+
" }\n"+
|
|
62
|
+
" } else {\n"+
|
|
63
|
+
" const innerSize="+(this.dimensionOrder[0]=="row"?"columns":"1")+"\n"+
|
|
64
|
+
" const outerSize="+(this.dimensionOrder[0]=="row"?"1":"columns")+"\n"+
|
|
65
|
+
" for("+this.dimensionOrder[0]+"Offset="+this.dimensionOrder[0]+"StartOffset;"+this.dimensionOrder[0]+"Offset<="+this.dimensionOrder[0]+"EndOffset;"+this.dimensionOrder[0]+"Offset++){\n"+
|
|
66
|
+
" const "+this.dimensionOrder[0]+"VectorOffset="+this.dimensionOrder[0]+"Offset*innerSize\n"+
|
|
67
|
+
(debug?"console.log({"+this.dimensionOrder[0]+"Offset:"+this.dimensionOrder[0]+"Offset,})\n":"")+
|
|
68
|
+
" for("+this.dimensionOrder[1]+"Offset="+this.dimensionOrder[1]+"StartOffset;"+this.dimensionOrder[1]+"Offset<="+this.dimensionOrder[1]+"EndOffset;"+this.dimensionOrder[1]+"Offset++){\n"+
|
|
69
|
+
" "+this.dimensionOrder[1]+"VectorOffset="+this.dimensionOrder[1]+"Offset*outerSize\n"+
|
|
70
|
+
" elementOffset=rowVectorOffset +columnOffset\n"+
|
|
71
|
+
" element=matrix[elementOffset];\n"+
|
|
72
|
+
(debug?"console.log({"+this.dimensionOrder[1]+"Offset:"+this.dimensionOrder[1]+"Offset,rowVectorOffset:rowVectorOffset,columnVectorOffset:columnVectorOffset,elementOffset:elementOffset,element:element})\n":"")+
|
|
73
|
+
" "+this.code+"\n"+
|
|
74
|
+
" }\n"+
|
|
75
|
+
" }\n"+
|
|
76
|
+
" }\n"+
|
|
77
|
+
(this.returnValue==undefined?" return this":" return returnValue")+
|
|
78
|
+
"\n}";
|
|
79
|
+
try{
|
|
80
|
+
const evaluatedCode=eval(functionCode);
|
|
81
|
+
return evaluatedCode;
|
|
82
|
+
} catch(ex) {
|
|
83
|
+
console.error("built function: \n"+functionCode)
|
|
84
|
+
console.error("error: "+ex.message)
|
|
85
|
+
console.error(ex.stack)
|
|
86
|
+
throw Error("code failed")
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
module.exports = generatedMatrixFunction;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
function generatedVectorFunction(arg1) {
|
|
2
|
+
if(typeof arg1 !=="object") throw Error("no definitional JSON found");
|
|
3
|
+
Object.assign(this,{
|
|
4
|
+
args:[],
|
|
5
|
+
debug:false,
|
|
6
|
+
returnValue:"this"
|
|
7
|
+
},arg1);
|
|
8
|
+
const extendedArgs=["startOffset=0","endOffset=vector.length-1,returnValue="+this.returnValue]
|
|
9
|
+
const functionCode=
|
|
10
|
+
"("+["vector"].concat(this.args,extendedArgs).join()+")=>{"+
|
|
11
|
+
"for(let index=startOffset;index<=endOffset;index++){\n"+
|
|
12
|
+
this.code+";\n"+
|
|
13
|
+
"}\n"+
|
|
14
|
+
"return returnValue\n}";
|
|
15
|
+
try{
|
|
16
|
+
if(debug==true) console.log(functionCode);
|
|
17
|
+
const evaluatedCode=eval(functionCode);
|
|
18
|
+
return evaluatedCode;
|
|
19
|
+
} catch(ex) {
|
|
20
|
+
console.error("built function: "+functionCode)
|
|
21
|
+
console.error("error: "+ex.message)
|
|
22
|
+
throw Error("code failed")
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
module.exports = generatedVectorFunction;
|