fixed heatmap

master
parent 585efcbb63
commit ff669e8f56
  1. BIN
      __pycache__/run.cpython-37.pyc
  2. 379
      frontend/package-lock.json
  3. 33
      frontend/package.json
  4. 13
      frontend/src/components/AlgorithmHyperParam.vue
  5. 2
      frontend/src/components/Algorithms.vue
  6. 10
      frontend/src/components/BarChart.vue
  7. 7
      frontend/src/components/DataSetExecController.vue
  8. 2
      frontend/src/components/DataSpace.vue
  9. 117
      frontend/src/components/FeatureSelection.vue
  10. 627
      frontend/src/components/Heatmap.vue
  11. 58
      frontend/src/components/Main.vue
  12. 2
      frontend/src/components/PredictionsSpace.vue
  13. 581
      frontend/src/components/StretchedChord.vue
  14. 70
      frontend/src/components/ToggleSelection.vue
  15. 4
      frontend/src/main.js
  16. 193
      run.py

Binary file not shown.

@ -1447,29 +1447,29 @@
} }
}, },
"@fortawesome/fontawesome-common-types": { "@fortawesome/fontawesome-common-types": {
"version": "0.2.22", "version": "0.2.24",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.22.tgz", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.24.tgz",
"integrity": "sha512-QmEuZsipX5/cR9JOg0fsTN4Yr/9lieYWM8AQpmRa0eIfeOcl/HLYoEa366BCGRSrgNJEexuvOgbq9jnJ22IY5g==" "integrity": "sha512-IPBT/1LdUVQpHcqdrh8uI2/86Fbu7933hkA/HweiCmP5QgF/8PecFM00gYvykxf0RZud8bg8zu+YfggDFUc1Kw=="
}, },
"@fortawesome/fontawesome-free": { "@fortawesome/fontawesome-free": {
"version": "5.10.2", "version": "5.11.1",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.10.2.tgz", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.11.1.tgz",
"integrity": "sha512-9pw+Nsnunl9unstGEHQ+u41wBEQue6XPBsILXtJF/4fNN1L3avJcMF/gGF86rIjeTAgfLjTY9ndm68/X4f4idQ==" "integrity": "sha512-DtXLVYAkDU0ce1cFUgLvZaMd1R2J/LviBYih9xr4ZLhQMrgvYX7w2vOxlpKLRALfIj5GyC5zoVrcACOkLcFgvg=="
}, },
"@fortawesome/fontawesome-svg-core": { "@fortawesome/fontawesome-svg-core": {
"version": "1.2.22", "version": "1.2.24",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.22.tgz", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.24.tgz",
"integrity": "sha512-Q941E4x8UfnMH3308n0qrgoja+GoqyiV846JTLoCcCWAKokLKrixCkq6RDBs8r+TtAWaLUrBpI+JFxQNX/WNPQ==", "integrity": "sha512-9uVGOEZwviZKbkOVX8nn8cErVqOHBAd1Fqd2OH7Iwu0vxGWdb3fFOMhaAyMXUHZpq1u5C9/HClCV49ci4WmJAg==",
"requires": { "requires": {
"@fortawesome/fontawesome-common-types": "^0.2.22" "@fortawesome/fontawesome-common-types": "^0.2.24"
} }
}, },
"@fortawesome/free-solid-svg-icons": { "@fortawesome/free-solid-svg-icons": {
"version": "5.10.2", "version": "5.11.1",
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.10.2.tgz", "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.11.1.tgz",
"integrity": "sha512-9Os/GRUcy+iVaznlg8GKcPSQFpIQpAg14jF0DWsMdnpJfIftlvfaQCWniR/ex9FoOpSEOrlXqmUCFL+JGeciuA==", "integrity": "sha512-bB3hXON1K6mVOetTTg5VXZ4CAHg866p7MqenDkJ/eVcbWbGQRE45ojHEwkf37tWx3E8z6lcEameRwU9r5tGwjg==",
"requires": { "requires": {
"@fortawesome/fontawesome-common-types": "^0.2.22" "@fortawesome/fontawesome-common-types": "^0.2.24"
} }
}, },
"@fortawesome/vue-fontawesome": { "@fortawesome/vue-fontawesome": {
@ -5132,10 +5132,15 @@
"resolved": "https://registry.npmjs.org/bootstrap-slider/-/bootstrap-slider-10.6.2.tgz", "resolved": "https://registry.npmjs.org/bootstrap-slider/-/bootstrap-slider-10.6.2.tgz",
"integrity": "sha512-8JTPZB9QVOdrGzYF3YgC3YW6ssfPeBvBwZnXffiZ7YH/zz1D0EKlZvmQsm/w3N0XjVNYQEoQ0ax+jHrErV4K1Q==" "integrity": "sha512-8JTPZB9QVOdrGzYF3YgC3YW6ssfPeBvBwZnXffiZ7YH/zz1D0EKlZvmQsm/w3N0XjVNYQEoQ0ax+jHrErV4K1Q=="
}, },
"bootstrap-toggle": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/bootstrap-toggle/-/bootstrap-toggle-2.2.2.tgz",
"integrity": "sha1-K4hTT8G5mGdPh3+Yug2LW3Q+lv4="
},
"bootstrap-vue": { "bootstrap-vue": {
"version": "2.0.0", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-2.0.0.tgz", "resolved": "https://registry.npmjs.org/bootstrap-vue/-/bootstrap-vue-2.0.1.tgz",
"integrity": "sha512-lBqkMtkXMqdIwMSDnWydVb38sOIQ0v+RRn/H0PEcLNd2OFarh81mHzGR+ARofGnO9Ubt0o1WJDRWk8RsNK2JfA==", "integrity": "sha512-mb2MP0f3KNRi/D8W0cItX2joM+XbwciFx1JKjtdKzt4uIXNx2SpOwF/wle26CszB1S35ArXJ/ZVN0dX8ry4yng==",
"requires": { "requires": {
"@nuxt/opencollective": "^0.3.0", "@nuxt/opencollective": "^0.3.0",
"bootstrap": ">=4.3.1 <5.0.0", "bootstrap": ">=4.3.1 <5.0.0",
@ -6025,6 +6030,11 @@
"simple-swizzle": "^0.2.2" "simple-swizzle": "^0.2.2"
} }
}, },
"colorbrewer": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/colorbrewer/-/colorbrewer-1.3.0.tgz",
"integrity": "sha512-AzVPpWa+fuO/qY8LxPQjej6F49Lb2Cl+7U9YhPn6y4/SOY6u/EZiXUc7qHzRb6i6fWPStCUdEaU2731QyQKWjg=="
},
"colormap": { "colormap": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/colormap/-/colormap-2.3.1.tgz", "resolved": "https://registry.npmjs.org/colormap/-/colormap-2.3.1.tgz",
@ -6802,9 +6812,9 @@
} }
}, },
"css-element-queries": { "css-element-queries": {
"version": "1.2.0", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/css-element-queries/-/css-element-queries-1.2.0.tgz", "resolved": "https://registry.npmjs.org/css-element-queries/-/css-element-queries-1.2.1.tgz",
"integrity": "sha512-4gaxpioSFueMcp9yj1TJFCLjfooGv38y6ZdwFUS3GuS+9NIVijdeiExXKwSIHoQDADfpgnaYSTzmJs+bV+Hehg==" "integrity": "sha512-hiI1tSzf+U/gE13qhfwnCvN90Ay0THnE+mT3pjN/c/mvFmEUHZVNrvMJrrkw2ppOzkl69FdgH2ZGZENYQUaN2A=="
}, },
"css-font": { "css-font": {
"version": "1.2.0", "version": "1.2.0",
@ -7316,6 +7326,21 @@
"d3-array": "1" "d3-array": "1"
} }
}, },
"d3-heatmap": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/d3-heatmap/-/d3-heatmap-1.2.1.tgz",
"integrity": "sha1-ukicekNWKtfcyUGvoursqVESz6Q=",
"requires": {
"d3": "^3.5.16"
},
"dependencies": {
"d3": {
"version": "3.5.17",
"resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz",
"integrity": "sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g="
}
}
},
"d3-hierarchy": { "d3-hierarchy": {
"version": "1.1.8", "version": "1.1.8",
"resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz", "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz",
@ -8289,9 +8314,9 @@
} }
}, },
"earcut": { "earcut": {
"version": "2.1.5", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/earcut/-/earcut-2.1.5.tgz", "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.1.tgz",
"integrity": "sha512-QFWC7ywTVLtvRAJTVp8ugsuuGQ5mVqNmJ1cRYeLrSHgP3nycr2RHTJob9OtM0v8ujuoKN0NY1a93J/omeTL1PA==" "integrity": "sha512-5jIMi2RB3HtGPHcYd9Yyl0cczo84y+48lgKPxMijliNQaKAHEZJbdzLmKmdxG/mCdS/YD9DQ1gihL8mxzR0F9w=="
}, },
"edges-to-adjacency-list": { "edges-to-adjacency-list": {
"version": "1.0.0", "version": "1.0.0",
@ -8308,9 +8333,9 @@
"dev": true "dev": true
}, },
"ejs": { "ejs": {
"version": "2.6.2", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.2.tgz", "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.1.tgz",
"integrity": "sha512-PcW2a0tyTuPHz3tWyYqtK6r1fZ3gp+3Sop8Ph+ZYN81Ob5rwmbHEzaqs10N3BEsaGTkh/ooniXK+WwszGlc2+Q==", "integrity": "sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ==",
"dev": true "dev": true
}, },
"electron-to-chromium": { "electron-to-chromium": {
@ -8332,9 +8357,9 @@
} }
}, },
"elliptic": { "elliptic": {
"version": "6.5.0", "version": "6.5.1",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.1.tgz",
"integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", "integrity": "sha512-xvJINNLbTeWQjrl6X+7eQCrIy/YPv5XCpKW6kB5mKvtnGILoLDcySuwomfdzt0BMdLNVnuRNTuzKNHj0bva1Cg==",
"dev": true, "dev": true,
"requires": { "requires": {
"bn.js": "^4.4.0", "bn.js": "^4.4.0",
@ -8759,9 +8784,9 @@
} }
}, },
"eslint": { "eslint": {
"version": "6.3.0", "version": "6.4.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.3.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.4.0.tgz",
"integrity": "sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==", "integrity": "sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/code-frame": "^7.0.0", "@babel/code-frame": "^7.0.0",
@ -9163,9 +9188,9 @@
"dev": true "dev": true
}, },
"eventemitter3": { "eventemitter3": {
"version": "3.1.2", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz",
"integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==",
"dev": true "dev": true
}, },
"events": { "events": {
@ -10145,12 +10170,12 @@
} }
}, },
"follow-redirects": { "follow-redirects": {
"version": "1.7.0", "version": "1.9.0",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.9.0.tgz",
"integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==", "integrity": "sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==",
"dev": true, "dev": true,
"requires": { "requires": {
"debug": "^3.2.6" "debug": "^3.0.0"
}, },
"dependencies": { "dependencies": {
"debug": { "debug": {
@ -10944,15 +10969,23 @@
} }
}, },
"gl-cone3d": { "gl-cone3d": {
"version": "1.3.1", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/gl-cone3d/-/gl-cone3d-1.3.1.tgz", "resolved": "https://registry.npmjs.org/gl-cone3d/-/gl-cone3d-1.4.0.tgz",
"integrity": "sha512-ftw75smsDy5nU94susUNimXo8H40BEOVjaFrjT387vP4fJqkSVpzVK7jGrPA8/nSrFCOIQ0msWNYL9MMqQ3hjg==", "integrity": "sha512-RiwwS0378p779Ae+aX+JqlodlALcTLrXVRkqbWdF03wRj0Ih6OgyuiVGQ/BduarWe+Tt8iGbt7zs+/H8RPVscQ==",
"requires": { "requires": {
"colormap": "^2.3.1",
"gl-buffer": "^2.1.2",
"gl-shader": "^4.2.1", "gl-shader": "^4.2.1",
"gl-texture2d": "^2.1.0",
"gl-vao": "^1.3.0",
"gl-vec3": "^1.1.3", "gl-vec3": "^1.1.3",
"glsl-inverse": "^1.0.0", "glsl-inverse": "^1.0.0",
"glsl-out-of-range": "^1.0.4", "glsl-out-of-range": "^1.0.4",
"glslify": "^7.0.0" "glslify": "^7.0.0",
"ndarray": "^1.0.18",
"normals": "^1.1.0",
"simplicial-complex-contour": "^1.0.2",
"typedarray-pool": "^1.1.0"
} }
}, },
"gl-constants": { "gl-constants": {
@ -11218,14 +11251,23 @@
} }
}, },
"gl-streamtube3d": { "gl-streamtube3d": {
"version": "1.2.1", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/gl-streamtube3d/-/gl-streamtube3d-1.2.1.tgz", "resolved": "https://registry.npmjs.org/gl-streamtube3d/-/gl-streamtube3d-1.3.0.tgz",
"integrity": "sha512-1aj1noU+jJirl5IwFXk29eDx1nO7PQk4r0UZK3My56J3vDSfRR+IbMq2YBhBkjfCWsKY1nc9ESD8t9EcqZY91w==", "integrity": "sha512-A0WBBNqLsze8Ch1pbuLJLXHwurXDqTB/F6BxKi7FbSMPEmky4l1Od5D9+mlimfJFd2n1q4m7hUHBxPLxKNUJpQ==",
"requires": { "requires": {
"gl-vec3": "^1.0.0", "colormap": "^2.3.1",
"gl-buffer": "^2.1.2",
"gl-shader": "^4.2.1",
"gl-texture2d": "^2.1.0",
"gl-vao": "^1.3.0",
"gl-vec3": "^1.1.3",
"glsl-inverse": "^1.0.0", "glsl-inverse": "^1.0.0",
"glsl-out-of-range": "^1.0.4", "glsl-out-of-range": "^1.0.4",
"glslify": "^7.0.0" "glslify": "^7.0.0",
"ndarray": "^1.0.18",
"normals": "^1.1.0",
"simplicial-complex-contour": "^1.0.2",
"typedarray-pool": "^1.1.0"
} }
}, },
"gl-surface3d": { "gl-surface3d": {
@ -12349,12 +12391,12 @@
"dev": true "dev": true
}, },
"http-proxy": { "http-proxy": {
"version": "1.17.0", "version": "1.18.0",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz",
"integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"eventemitter3": "^3.0.0", "eventemitter3": "^4.0.0",
"follow-redirects": "^1.0.0", "follow-redirects": "^1.0.0",
"requires-port": "^1.0.0" "requires-port": "^1.0.0"
} }
@ -12581,14 +12623,6 @@
"path-exists": "^3.0.0" "path-exists": "^3.0.0"
} }
}, },
"p-limit": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
"integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
"requires": {
"p-try": "^2.0.0"
}
},
"p-locate": { "p-locate": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
@ -12597,11 +12631,6 @@
"p-limit": "^2.0.0" "p-limit": "^2.0.0"
} }
}, },
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
},
"pkg-dir": { "pkg-dir": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
@ -14285,9 +14314,9 @@
} }
}, },
"loglevel": { "loglevel": {
"version": "1.6.3", "version": "1.6.4",
"resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.3.tgz", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.4.tgz",
"integrity": "sha512-LoEDv5pgpvWgPF4kNYuIp0qqSJVWak/dML0RY74xlzMZiT9w77teNAwKYKWBTYjlokMirg+o3jBwp+vlLrcfAA==", "integrity": "sha512-p0b6mOGKcGa+7nnmKbpzR6qloPbrgLcnio++E+14Vo/XffOGwZtRpUhr8dTH/x2oCMmEoIU0Zwm3ZauhvYD17g==",
"dev": true "dev": true
}, },
"longest": { "longest": {
@ -14854,9 +14883,9 @@
} }
}, },
"mdbvue": { "mdbvue": {
"version": "5.8.1", "version": "5.8.2",
"resolved": "https://registry.npmjs.org/mdbvue/-/mdbvue-5.8.1.tgz", "resolved": "https://registry.npmjs.org/mdbvue/-/mdbvue-5.8.2.tgz",
"integrity": "sha512-RzlQb1YoT60nxhrW/iTF3nJlNIdQc1tEDXkcWhKpa6YFVX5iu0GhOQvlFWBNBWDw0/OkgTbiUnimSf9Jq4ESwg==", "integrity": "sha512-2U2vx1YYctmQEj/L52DdzpRTmft0QlCIe/i0AdjlxTdFWen7AVZJBWACC7ancEIPNYhLh/JjLfaOlUay+6eIAg==",
"requires": { "requires": {
"@fortawesome/fontawesome-free": "^5.8.2", "@fortawesome/fontawesome-free": "^5.8.2",
"axios": "^0.18.0", "axios": "^0.18.0",
@ -15188,9 +15217,9 @@
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
}, },
"minipass": { "minipass": {
"version": "2.5.1", "version": "2.6.0",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.5.1.tgz", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.6.0.tgz",
"integrity": "sha512-dmpSnLJtNQioZFI5HfQ55Ad0DzzsMAb+HfokwRTNXwEQjepbTkl5mtIlSVxGIkOkxlpX7wIn5ET/oAd9fZ/Y/Q==", "integrity": "sha512-OuNZ0OHrrI+jswzmgivYBZ+fAAGHZA4293d5q0z631/I9QSw3yumKB92njxHIHiB1eAdGRsE+3CcOPkoEyV5FQ==",
"requires": { "requires": {
"safe-buffer": "^5.1.2", "safe-buffer": "^5.1.2",
"yallist": "^3.0.0" "yallist": "^3.0.0"
@ -15204,9 +15233,9 @@
} }
}, },
"minizlib": { "minizlib": {
"version": "1.2.1", "version": "1.2.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.2.tgz",
"integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", "integrity": "sha512-hR3At21uSrsjjDTWrbu0IMLTpnkpv8IIMFDFaoz43Tmu4LkmAXfH44vNNzpTnf+OAQQCHrb91y/wc2J4x5XgSQ==",
"requires": { "requires": {
"minipass": "^2.2.1" "minipass": "^2.2.1"
} }
@ -15630,9 +15659,9 @@
} }
}, },
"node-forge": { "node-forge": {
"version": "0.7.5", "version": "0.8.2",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.2.tgz",
"integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==", "integrity": "sha512-mXQ9GBq1N3uDCyV1pdSzgIguwgtVpM7f5/5J4ipz12PKWElmPpVWLDuWl8iXmhysr21+WmX/OJ5UKx82wjomgg==",
"dev": true "dev": true
}, },
"node-libs-browser": { "node-libs-browser": {
@ -15841,9 +15870,9 @@
"integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==" "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g=="
}, },
"npm-check-updates": { "npm-check-updates": {
"version": "3.1.22", "version": "3.1.23",
"resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-3.1.22.tgz", "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-3.1.23.tgz",
"integrity": "sha512-glG2ui4bM6fbPJCnUmuhaZVRTU77xqJQmFnSqeINQI2k/Vo2jiuOLpbvGTEQ4s7a/E2Gv0Ze7+qm5iPeWzl0XA==", "integrity": "sha512-Z2dkMdNgue6OPkQDPcAK62Qrwv+G1PaEmKrDrrSAiSP7pRD3u30xOVy1nLukS1XrJ2/zF8XTVxFe9/ubcvlcPQ==",
"requires": { "requires": {
"chalk": "^2.4.2", "chalk": "^2.4.2",
"cint": "^8.2.1", "cint": "^8.2.1",
@ -15954,16 +15983,17 @@
} }
}, },
"npm-registry-fetch": { "npm-registry-fetch": {
"version": "4.0.0", "version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-4.0.0.tgz", "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-4.0.1.tgz",
"integrity": "sha512-Jllq35Jag8dtv0M17ue74XtdQTyqKzuAYGiX9mAjOhkmNjib3bBUgK6mUY61+AHnXeSRobQkpY3/xIOS/omptw==", "integrity": "sha512-1ZQ+yjnxc698R5h9Yje9CASapzAZr7aYDkJDdERg9xg2hOEY0vRJwskOaJAXq8N/eLavzvW4g564YAfq6zMn/A==",
"requires": { "requires": {
"JSONStream": "^1.3.4", "JSONStream": "^1.3.4",
"bluebird": "^3.5.1", "bluebird": "^3.5.1",
"figgy-pudding": "^3.4.1", "figgy-pudding": "^3.4.1",
"lru-cache": "^5.1.1", "lru-cache": "^5.1.1",
"make-fetch-happen": "^5.0.0", "make-fetch-happen": "^5.0.0",
"npm-package-arg": "^6.1.0" "npm-package-arg": "^6.1.0",
"safe-buffer": "^5.2.0"
}, },
"dependencies": { "dependencies": {
"lru-cache": { "lru-cache": {
@ -15974,6 +16004,11 @@
"yallist": "^3.0.2" "yallist": "^3.0.2"
} }
}, },
"safe-buffer": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
},
"yallist": { "yallist": {
"version": "3.0.3", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
@ -16435,27 +16470,10 @@
"strip-eof": "^1.0.0" "strip-eof": "^1.0.0"
} }
}, },
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
"requires": {
"pump": "^3.0.0"
}
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"semver": { "semver": {
"version": "5.7.0", "version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
} }
} }
}, },
@ -16684,9 +16702,9 @@
"dev": true "dev": true
}, },
"papaparse": { "papaparse": {
"version": "5.0.2", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.0.2.tgz", "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.1.0.tgz",
"integrity": "sha512-FoaaFfNlCztJ7c+XD1Fgb0zIJ530HwSr6FBfM1mcMzLtIWoTxE5paBNJWiCWFjDrTzGiEG/uIUfqVzgKxqd+Sw==" "integrity": "sha512-3jEYMiCc8qN7V5ffi2BTS2mRauKxCu5AIED6DxbjnHhIm7OY7fzKYkndfPlHWaaKUDCTml5XTU6V+hiuxGlZuw=="
}, },
"parallel-transform": { "parallel-transform": {
"version": "1.1.0", "version": "1.1.0",
@ -17223,9 +17241,9 @@
} }
}, },
"plotly.js": { "plotly.js": {
"version": "1.49.4", "version": "1.49.5",
"resolved": "https://registry.npmjs.org/plotly.js/-/plotly.js-1.49.4.tgz", "resolved": "https://registry.npmjs.org/plotly.js/-/plotly.js-1.49.5.tgz",
"integrity": "sha512-yOcA1GKLY6vsGLWYoGa/jWTPXcHPTyTWwkgAhopNtCgxTVexXzKfnnGQ2SslL//+TkpNX8CpCzC88HQVV4p42Q==", "integrity": "sha512-R8viAou9aIeMOaI+sDWyQb4uQajGV6nFqPg2ybNTy/XcZVBetzw+2ALSdkBFR1TyzCF46IvQZcF7BcdCrdraPA==",
"requires": { "requires": {
"@plotly/d3-sankey": "0.7.2", "@plotly/d3-sankey": "0.7.2",
"@plotly/d3-sankey-circular": "0.33.1", "@plotly/d3-sankey-circular": "0.33.1",
@ -17302,15 +17320,16 @@
} }
}, },
"point-cluster": { "point-cluster": {
"version": "3.1.5", "version": "3.1.6",
"resolved": "https://registry.npmjs.org/point-cluster/-/point-cluster-3.1.5.tgz", "resolved": "https://registry.npmjs.org/point-cluster/-/point-cluster-3.1.6.tgz",
"integrity": "sha512-KpVtB1mXDlo6yzv80MA6oUq+1519CMeeUd4PPluM4ZlAQgHi/qeBrLY2G53RLy41kas7XvKol0FM98MSrjNH7Q==", "integrity": "sha512-MJx0Shjr5T9NHpq/dfLormnEMoW2aqCEPBPcyz7gIG/NkRlD/1wEgmfKLNwT6g5Ivu/t/I9P+sQLpsEh6TBHIg==",
"requires": { "requires": {
"array-bounds": "^1.0.1", "array-bounds": "^1.0.1",
"array-normalize": "^1.1.3", "array-normalize": "^1.1.3",
"binary-search-bounds": "^2.0.4", "binary-search-bounds": "^2.0.4",
"bubleify": "^1.1.0", "bubleify": "^1.1.0",
"clamp": "^1.0.1", "clamp": "^1.0.1",
"defined": "^1.0.0",
"dtype": "^2.0.0", "dtype": "^2.0.0",
"flatten-vertex-data": "^1.0.0", "flatten-vertex-data": "^1.0.0",
"is-obj": "^1.0.1", "is-obj": "^1.0.1",
@ -18766,9 +18785,9 @@
} }
}, },
"regl": { "regl": {
"version": "1.3.12", "version": "1.3.13",
"resolved": "https://registry.npmjs.org/regl/-/regl-1.3.12.tgz", "resolved": "https://registry.npmjs.org/regl/-/regl-1.3.13.tgz",
"integrity": "sha512-RsYw/01WrkFanniKeZ/x6pQjG6/2DL+ansp90Olx0yyiVIXZR2PzZ+m/eKmBQ/M43bvaGOabtt+mNEgPG0TiCg==" "integrity": "sha512-TTiCabJbbUykCL4otjqOvKqDFJhvJOT7xB51JxcDeSHGrEJl1zz4RthPcoOogqfuR3ECN4Te790DfHCXzli5WQ=="
}, },
"regl-error2d": { "regl-error2d": {
"version": "2.0.8", "version": "2.0.8",
@ -18805,10 +18824,11 @@
} }
}, },
"regl-scatter2d": { "regl-scatter2d": {
"version": "3.1.5", "version": "3.1.6",
"resolved": "https://registry.npmjs.org/regl-scatter2d/-/regl-scatter2d-3.1.5.tgz", "resolved": "https://registry.npmjs.org/regl-scatter2d/-/regl-scatter2d-3.1.6.tgz",
"integrity": "sha512-VCmASgrNIQXzDxmTLpLA4MAlbi+kdjKcVR9XugmFCTnWY7zytIhuMyIoPxinpaejGXzsC0Lq5oKvOnWFMQFGng==", "integrity": "sha512-mnLcwQzTHWgmkiD+5fToNaKJ7QNylvOcBJ/1roJJkIAtr1jnvgXiqrkeqkMIb8IVBKvm00/lCdPZat6Qifxvmw==",
"requires": { "requires": {
"array-bounds": "^1.0.1",
"array-range": "^1.0.1", "array-range": "^1.0.1",
"array-rearrange": "^2.2.2", "array-rearrange": "^2.2.2",
"clamp": "^1.0.1", "clamp": "^1.0.1",
@ -19398,9 +19418,9 @@
"integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=" "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ="
}, },
"rxjs": { "rxjs": {
"version": "6.5.2", "version": "6.5.3",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz",
"integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==",
"dev": true, "dev": true,
"requires": { "requires": {
"tslib": "^1.9.0" "tslib": "^1.9.0"
@ -19430,9 +19450,9 @@
"integrity": "sha512-bJILrpBboQfabG3BNnHI2hZl52pbt80BE09u4WhnrmzuF2JbMKZdl62G5glXskJ46p+gxE2IzOwGj/awR4g8AA==" "integrity": "sha512-bJILrpBboQfabG3BNnHI2hZl52pbt80BE09u4WhnrmzuF2JbMKZdl62G5glXskJ46p+gxE2IzOwGj/awR4g8AA=="
}, },
"sass": { "sass": {
"version": "1.22.10", "version": "1.22.12",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.22.10.tgz", "resolved": "https://registry.npmjs.org/sass/-/sass-1.22.12.tgz",
"integrity": "sha512-DUpS1tVMGCH6gr/N9cXCoemrjoNdOLhAHfQ37fJw2A5ZM4gSI9ej/8Xi95Xwus03RqZ2zdSnKZGULL7oS+jfMA==", "integrity": "sha512-u5Rxn+dKTPCW5/11kMNxtmqKsxCjcpnqj9CaJoru1NqeJ0DOa9rOM00e0HqmseTAatGkKoLY+jaNecMYevu1gg==",
"dev": true, "dev": true,
"requires": { "requires": {
"chokidar": ">=2.0.0 <4.0.0" "chokidar": ">=2.0.0 <4.0.0"
@ -19510,12 +19530,12 @@
"dev": true "dev": true
}, },
"selfsigned": { "selfsigned": {
"version": "1.10.4", "version": "1.10.6",
"resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.6.tgz",
"integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==", "integrity": "sha512-i3+CeqxL7DpAazgVpAGdKMwHuL63B5nhJMh9NQ7xmChGkA3jNFflq6Jyo1LLJYcr3idWiNOPWHCrm4zMayLG4w==",
"dev": true, "dev": true,
"requires": { "requires": {
"node-forge": "0.7.5" "node-forge": "0.8.2"
} }
}, },
"semver": { "semver": {
@ -19987,9 +20007,9 @@
} }
}, },
"sockjs-client": { "sockjs-client": {
"version": "1.3.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz", "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz",
"integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==",
"dev": true, "dev": true,
"requires": { "requires": {
"debug": "^3.2.5", "debug": "^3.2.5",
@ -21120,9 +21140,9 @@
} }
}, },
"terser": { "terser": {
"version": "4.2.1", "version": "4.3.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.2.1.tgz", "resolved": "https://registry.npmjs.org/terser/-/terser-4.3.1.tgz",
"integrity": "sha512-cGbc5utAcX4a9+2GGVX4DsenG6v0x3glnDi5hx8816X1McEAwPlPgRtXPJzSBsbpILxZ8MQMT0KvArLuE0HP5A==", "integrity": "sha512-pnzH6dnFEsR2aa2SJaKb1uSCl3QmIsJ8dEkj0Fky+2AwMMcC9doMqLOQIH6wVTEKaVfKVvLSk5qxPBEZT9mywg==",
"dev": true, "dev": true,
"requires": { "requires": {
"commander": "^2.20.0", "commander": "^2.20.0",
@ -23305,12 +23325,12 @@
} }
}, },
"vue-plotly": { "vue-plotly": {
"version": "1.0.0", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/vue-plotly/-/vue-plotly-1.0.0.tgz", "resolved": "https://registry.npmjs.org/vue-plotly/-/vue-plotly-1.0.1.tgz",
"integrity": "sha512-3zm1E/dg5I4IOJJMb2l3LXTPzJvPOUanmJNSEbRYMzmBpsmOK8DHnKj4jOfE/yn/Gp3/a9vv84USoluVA+g7SA==", "integrity": "sha512-JNBQeTgiHIomnGhwL+2FkqY/6qiIU3mNRiXBNVOmx6xyrx657H6QxeNL9YxSrKpN4wvR/ulnwztKVKO5aT6Fqg==",
"requires": { "requires": {
"plotly.js": "^1.45.2", "plotly.js": "^1.49.4",
"vue": "^2.6.9", "vue": "^2.6.10",
"vue-resize-directive": "^1.2.0" "vue-resize-directive": "^1.2.0"
} }
}, },
@ -23477,9 +23497,9 @@
} }
}, },
"webpack": { "webpack": {
"version": "4.39.3", "version": "4.40.2",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.39.3.tgz", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.40.2.tgz",
"integrity": "sha512-BXSI9M211JyCVc3JxHWDpze85CvjC842EvpRsVTc/d15YJGlox7GIDd38kJgWrb3ZluyvIjgenbLDMBQPDcxYQ==", "integrity": "sha512-5nIvteTDCUws2DVvP9Qe+JPla7kWPPIDFZv55To7IycHWZ+Z5qBdaBYPyuXWdhggTufZkQwfIK+5rKQTVovm2A==",
"dev": true, "dev": true,
"requires": { "requires": {
"@webassemblyjs/ast": "1.8.5", "@webassemblyjs/ast": "1.8.5",
@ -23553,9 +23573,9 @@
} }
}, },
"webpack-bundle-analyzer": { "webpack-bundle-analyzer": {
"version": "3.4.1", "version": "3.5.0",
"resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.4.1.tgz", "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.5.0.tgz",
"integrity": "sha512-Bs8D/1zF+17lhqj2OYmzi7HEVYqEVxu7lCO9Ff8BwajenOU0vAwEoV8e4ICCPNZAcqR1PCR/7o2SkW+cnCmF0A==", "integrity": "sha512-NzueflueLSJxWGzDlMq5oUV+P8Qoq6yiaQlXGCbDYUpHEKlmzWdPLBJ4k/B6HTdAP/vHM8ply1Fx08mDnY+S8Q==",
"dev": true, "dev": true,
"requires": { "requires": {
"acorn": "^6.0.7", "acorn": "^6.0.7",
@ -23588,9 +23608,9 @@
} }
}, },
"webpack-cli": { "webpack-cli": {
"version": "3.3.8", "version": "3.3.9",
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.8.tgz", "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.9.tgz",
"integrity": "sha512-RANYSXwikSWINjHMd/mtesblNSpjpDLoYTBtP99n1RhXqVI/wxN40Auqy42I7y4xrbmRBoA5Zy5E0JSBD5XRhw==", "integrity": "sha512-xwnSxWl8nZtBl/AFJCOn9pG7s5CYUYdZxmmukv+fAHLcBIHM36dImfpQg3WfShZXeArkWlf6QRw24Klcsv8a5A==",
"requires": { "requires": {
"chalk": "2.4.2", "chalk": "2.4.2",
"cross-spawn": "6.0.5", "cross-spawn": "6.0.5",
@ -23762,13 +23782,14 @@
} }
}, },
"webpack-dev-middleware": { "webpack-dev-middleware": {
"version": "3.7.0", "version": "3.7.1",
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.0.tgz", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.1.tgz",
"integrity": "sha512-qvDesR1QZRIAZHOE3iQ4CXLZZSQ1lAUsSpnQmlB1PBfoN/xdRjmge3Dok0W4IdaVLJOGJy3sGI4sZHwjRU0PCA==", "integrity": "sha512-5MWu9SH1z3hY7oHOV6Kbkz5x7hXbxK56mGHNqHTe6d+ewxOwKUxoUJBs7QIaJb33lPjl9bJZ3X0vCoooUzC36A==",
"dev": true, "dev": true,
"requires": { "requires": {
"memory-fs": "^0.4.1", "memory-fs": "^0.4.1",
"mime": "^2.4.2", "mime": "^2.4.4",
"mkdirp": "^0.5.1",
"range-parser": "^1.2.1", "range-parser": "^1.2.1",
"webpack-log": "^2.0.0" "webpack-log": "^2.0.0"
}, },
@ -23782,14 +23803,14 @@
} }
}, },
"webpack-dev-server": { "webpack-dev-server": {
"version": "3.8.0", "version": "3.8.1",
"resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.8.0.tgz", "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.8.1.tgz",
"integrity": "sha512-Hs8K9yI6pyMvGkaPTeTonhD6JXVsigXDApYk9JLW4M7viVBspQvb1WdAcWxqtmttxNW4zf2UFLsLNe0y87pIGQ==", "integrity": "sha512-9F5DnfFA9bsrhpUCAfQic/AXBVHvq+3gQS+x6Zj0yc1fVVE0erKh2MV4IV12TBewuTrYeeTIRwCH9qLMvdNvTw==",
"dev": true, "dev": true,
"requires": { "requires": {
"ansi-html": "0.0.7", "ansi-html": "0.0.7",
"bonjour": "^3.5.0", "bonjour": "^3.5.0",
"chokidar": "^2.1.6", "chokidar": "^2.1.8",
"compression": "^1.7.4", "compression": "^1.7.4",
"connect-history-api-fallback": "^1.6.0", "connect-history-api-fallback": "^1.6.0",
"debug": "^4.1.1", "debug": "^4.1.1",
@ -23800,28 +23821,48 @@
"import-local": "^2.0.0", "import-local": "^2.0.0",
"internal-ip": "^4.3.0", "internal-ip": "^4.3.0",
"ip": "^1.1.5", "ip": "^1.1.5",
"is-absolute-url": "^3.0.0", "is-absolute-url": "^3.0.2",
"killable": "^1.0.1", "killable": "^1.0.1",
"loglevel": "^1.6.3", "loglevel": "^1.6.4",
"opn": "^5.5.0", "opn": "^5.5.0",
"p-retry": "^3.0.1", "p-retry": "^3.0.1",
"portfinder": "^1.0.21", "portfinder": "^1.0.24",
"schema-utils": "^1.0.0", "schema-utils": "^1.0.0",
"selfsigned": "^1.10.4", "selfsigned": "^1.10.6",
"semver": "^6.3.0", "semver": "^6.3.0",
"serve-index": "^1.9.1", "serve-index": "^1.9.1",
"sockjs": "0.3.19", "sockjs": "0.3.19",
"sockjs-client": "1.3.0", "sockjs-client": "1.4.0",
"spdy": "^4.0.1", "spdy": "^4.0.1",
"strip-ansi": "^3.0.1", "strip-ansi": "^3.0.1",
"supports-color": "^6.1.0", "supports-color": "^6.1.0",
"url": "^0.11.0", "url": "^0.11.0",
"webpack-dev-middleware": "^3.7.0", "webpack-dev-middleware": "^3.7.1",
"webpack-log": "^2.0.0", "webpack-log": "^2.0.0",
"ws": "^6.2.1", "ws": "^6.2.1",
"yargs": "12.0.5" "yargs": "12.0.5"
}, },
"dependencies": { "dependencies": {
"chokidar": {
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
"integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
"dev": true,
"requires": {
"anymatch": "^2.0.0",
"async-each": "^1.0.1",
"braces": "^2.3.2",
"fsevents": "^1.2.7",
"glob-parent": "^3.1.0",
"inherits": "^2.0.3",
"is-binary-path": "^1.0.0",
"is-glob": "^4.0.0",
"normalize-path": "^3.0.0",
"path-is-absolute": "^1.0.0",
"readdirp": "^2.2.1",
"upath": "^1.1.1"
}
},
"debug": { "debug": {
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
@ -23832,9 +23873,9 @@
} }
}, },
"is-absolute-url": { "is-absolute-url": {
"version": "3.0.0", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.0.tgz", "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.2.tgz",
"integrity": "sha512-3OkP8XrM2Xq4/IxsJnClfMp3OaM3TAatLPLKPeWcxLBTrpe6hihwtX+XZfJTcXg/FTRi4qjy0y/C5qiyNxY24g==", "integrity": "sha512-+5g/wLlcm1AcxSP7014m6GvbPHswDx980vD/3bZaap8aGV9Yfs7Q6y6tfaupgZ5O74Byzc8dGrSCJ+bFXx0KdA==",
"dev": true "dev": true
}, },
"ms": { "ms": {

@ -13,9 +13,9 @@
"dependencies": { "dependencies": {
"@babel/core": "^7.6.0", "@babel/core": "^7.6.0",
"@babel/runtime": "^7.6.0", "@babel/runtime": "^7.6.0",
"@fortawesome/fontawesome-free": "^5.10.2", "@fortawesome/fontawesome-free": "^5.11.1",
"@fortawesome/fontawesome-svg-core": "^1.2.22", "@fortawesome/fontawesome-svg-core": "^1.2.24",
"@fortawesome/free-solid-svg-icons": "^5.10.2", "@fortawesome/free-solid-svg-icons": "^5.11.1",
"@fortawesome/vue-fontawesome": "^0.1.7", "@fortawesome/vue-fontawesome": "^0.1.7",
"@statnett/vue-plotly": "^0.3.2", "@statnett/vue-plotly": "^0.3.2",
"@types/d3-drag": "^1.2.3", "@types/d3-drag": "^1.2.3",
@ -27,10 +27,13 @@
"babel-preset-vue": "^2.0.2", "babel-preset-vue": "^2.0.2",
"blob": "0.0.5", "blob": "0.0.5",
"bootstrap": "^4.3.1", "bootstrap": "^4.3.1",
"bootstrap-vue": "^2.0.0", "bootstrap-toggle": "^2.2.2",
"bootstrap-vue": "^2.0.1",
"clean-webpack-plugin": "^3.0.0", "clean-webpack-plugin": "^3.0.0",
"colorbrewer": "^1.3.0",
"d3": "^5.12.0", "d3": "^5.12.0",
"d3-drag": "^1.2.4", "d3-drag": "^1.2.4",
"d3-heatmap": "^1.2.1",
"d3-lasso": "0.0.5", "d3-lasso": "0.0.5",
"d3-loom": "^1.0.2", "d3-loom": "^1.0.2",
"d3-selection": "^1.4.0", "d3-selection": "^1.4.0",
@ -44,12 +47,12 @@
"ify-loader": "^1.1.0", "ify-loader": "^1.1.0",
"interactjs": "^1.6.2", "interactjs": "^1.6.2",
"jquery": "^3.4.1", "jquery": "^3.4.1",
"mdbvue": "^5.8.1", "mdbvue": "^5.8.2",
"mini-css-extract-plugin": "^0.8.0", "mini-css-extract-plugin": "^0.8.0",
"npm-check-updates": "^3.1.22", "npm-check-updates": "^3.1.23",
"papaparse": "^5.0.2", "papaparse": "^5.1.0",
"parcoord-es": "^2.2.10", "parcoord-es": "^2.2.10",
"plotly.js": "^1.49.4", "plotly.js": "^1.49.5",
"popper.js": "^1.15.0", "popper.js": "^1.15.0",
"strip-loader": "^0.1.2", "strip-loader": "^0.1.2",
"toposort": "^2.0.2", "toposort": "^2.0.2",
@ -59,11 +62,11 @@
"vue": "^2.6.10", "vue": "^2.6.10",
"vue-bootstrap-slider": "^2.1.8", "vue-bootstrap-slider": "^2.1.8",
"vue-papa-parse": "^1.2.2", "vue-papa-parse": "^1.2.2",
"vue-plotly": "^1.0.0", "vue-plotly": "^1.0.1",
"vue-router": "^3.1.3", "vue-router": "^3.1.3",
"vue-slider-component": "^3.0.40", "vue-slider-component": "^3.0.40",
"vue2-simplert-plugin": "^0.5.3", "vue2-simplert-plugin": "^0.5.3",
"webpack-cli": "^3.3.8", "webpack-cli": "^3.3.9",
"webpack-require": "0.0.16" "webpack-require": "0.0.16"
}, },
"devDependencies": { "devDependencies": {
@ -87,7 +90,7 @@
"chalk": "^2.4.2", "chalk": "^2.4.2",
"copy-webpack-plugin": "^5.0.4", "copy-webpack-plugin": "^5.0.4",
"css-loader": "^3.2.0", "css-loader": "^3.2.0",
"eslint": "^6.3.0", "eslint": "^6.4.0",
"eslint-config-standard": "^14.1.0", "eslint-config-standard": "^14.1.0",
"eslint-friendly-formatter": "^4.0.1", "eslint-friendly-formatter": "^4.0.1",
"eslint-loader": "^3.0.0", "eslint-loader": "^3.0.0",
@ -108,7 +111,7 @@
"postcss-loader": "^3.0.0", "postcss-loader": "^3.0.0",
"postcss-url": "^8.0.0", "postcss-url": "^8.0.0",
"rimraf": "^3.0.0", "rimraf": "^3.0.0",
"sass": "^1.22.10", "sass": "^1.22.12",
"sass-loader": "^8.0.0", "sass-loader": "^8.0.0",
"semver": "^6.3.0", "semver": "^6.3.0",
"shelljs": "^0.8.3", "shelljs": "^0.8.3",
@ -122,9 +125,9 @@
"vue-template-compiler": "^2.6.10", "vue-template-compiler": "^2.6.10",
"vue2-simplert": "^1.0.0", "vue2-simplert": "^1.0.0",
"vuetify-loader": "^1.3.0", "vuetify-loader": "^1.3.0",
"webpack": "^4.39.3", "webpack": "^4.40.2",
"webpack-bundle-analyzer": "^3.4.1", "webpack-bundle-analyzer": "^3.5.0",
"webpack-dev-server": "^3.8.0", "webpack-dev-server": "^3.8.1",
"webpack-merge": "^4.2.2" "webpack-merge": "^4.2.2"
}, },
"browserslist": [ "browserslist": [

@ -25,7 +25,7 @@ export default {
PCPView () { PCPView () {
d3.selectAll("#PCP > *").remove(); d3.selectAll("#PCP > *").remove();
if (this.selAlgorithm != '') { if (this.selAlgorithm != '') {
var colors = ['#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a'] var colors = ['#8dd3c7','#ffffb3','#bebada','#fb8072','#80b1d3','#fdb462','#b3de69','#fccde5','#d9d9d9','#bc80bd','#ccebc5','#ffed6f']
var colorGiv = 0 var colorGiv = 0
var Combined = 0 var Combined = 0
@ -38,22 +38,29 @@ export default {
} }
var valuesPerf = Object.values(Combined['mean_test_score']) var valuesPerf = Object.values(Combined['mean_test_score'])
var ObjectsParams = Combined['params'] var ObjectsParams = Combined['params']
var newObjectsParams = []
var ArrayCombined = new Array(valuesPerf.length) var ArrayCombined = new Array(valuesPerf.length)
for (let i = 0; i < valuesPerf.length; i++) { for (let i = 0; i < valuesPerf.length; i++) {
if (this.selAlgorithm == 'KNN') {
newObjectsParams.push({'weights':ObjectsParams[i].weights, 'algorithm':ObjectsParams[i].algorithm,'metric':ObjectsParams[i].metric,'n_neighbors':ObjectsParams[i].n_neighbors})
Object.assign(newObjectsParams[i], {performance: valuesPerf[i]}, {model: i})
ArrayCombined[i] = newObjectsParams[i]
} else {
Object.assign(ObjectsParams[i], {performance: valuesPerf[i]}, {model: i}) Object.assign(ObjectsParams[i], {performance: valuesPerf[i]}, {model: i})
ArrayCombined[i] = ObjectsParams[i] ArrayCombined[i] = ObjectsParams[i]
} }
}
EventBus.$emit('AllAlModels', ArrayCombined.length) EventBus.$emit('AllAlModels', ArrayCombined.length)
this.pc = ParCoords()("#PCP") this.pc = ParCoords()("#PCP")
.data(ArrayCombined) .data(ArrayCombined)
.color(colorGiv) .color(colorGiv)
.hideAxis(['model']) .hideAxis(['model','performance'])
.bundlingStrength(0) // set bundling strength .bundlingStrength(0) // set bundling strength
.smoothness(0) .smoothness(0)
.bundleDimension('performance')
.showControlPoints(false) .showControlPoints(false)
.render() .render()
.brushMode('1D-axes') .brushMode('1D-axes')
.reorderable()
.interactive(); .interactive();
this.pc.on("brush", function(d) { this.pc.on("brush", function(d) {

@ -79,7 +79,7 @@ export default {
}, },
brushed () { brushed () {
var allPoints = document.getElementsByClassName("d3-exploding-boxplot point") var allPoints = document.getElementsByClassName("d3-exploding-boxplot point")
const previousColor = ['#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a'] const previousColor = ['#8dd3c7','#ffffb3','#bebada','#fb8072','#80b1d3','#fdb462','#b3de69','#fccde5','#d9d9d9','#bc80bd','#ccebc5','#ffed6f']
var modelsActive = [] var modelsActive = []
for (let j = 0; j < this.brushedBoxPl.length; j++) { for (let j = 0; j < this.brushedBoxPl.length; j++) {
modelsActive.push(this.brushedBoxPl[j].model) modelsActive.push(this.brushedBoxPl[j].model)

@ -32,12 +32,12 @@ export default {
}, },
methods: { methods: {
BarChartView () { BarChartView () {
const PerClassMetrics = JSON.parse(this.BarChartResults[4]) const PerClassMetrics = JSON.parse(this.BarChartResults[3])
var ClassNames = JSON.parse(this.BarChartResults[5]) var ClassNames = JSON.parse(this.BarChartResults[4])
this.ClassNamesOverview = ClassNames this.ClassNamesOverview = ClassNames
const limit = JSON.parse(this.BarChartResults[13]) let ClassifierswithoutFI = JSON.parse(this.BarChartResults[7])
let ClassifierswithoutFI = JSON.parse(this.BarChartResults[8]) let ClassifierswithFI = JSON.parse(this.BarChartResults[8])
let ClassifierswithFI = JSON.parse(this.BarChartResults[9]) const limit = JSON.parse(this.BarChartResults[14])
for (let j = 0; j < this.ClassNamesOverview.length; j++) { for (let j = 0; j < this.ClassNamesOverview.length; j++) {
Plotly.purge('barChartf1Score' + j) Plotly.purge('barChartf1Score' + j)

@ -19,6 +19,12 @@
<font-awesome-icon icon="play" /> <font-awesome-icon icon="play" />
{{ value }} {{ value }}
</button> </button>
<button
id="Reset"
v-on:click="execute">
<font-awesome-icon icon="trash" />
{{ valueReset }}
</button>
</div> </div>
</template> </template>
@ -32,6 +38,7 @@ export default {
return { return {
RetrieveValueCSV: 'IrisC', RetrieveValueCSV: 'IrisC',
value: 'Execute', value: 'Execute',
valueReset: 'Reset',
InitializeEnsemble: false InitializeEnsemble: false
} }
}, },

@ -16,7 +16,7 @@ export default {
}, },
methods: { methods: {
ScatterPlotDataView () { ScatterPlotDataView () {
const XandYCoordinates = JSON.parse(this.DataSpace[10]) const XandYCoordinates = JSON.parse(this.DataSpace[9])
var result = XandYCoordinates.reduce(function(r, a) { var result = XandYCoordinates.reduce(function(r, a) {
a.forEach(function(s, i) { a.forEach(function(s, i) {

@ -1,117 +0,0 @@
<template>
<div id="myDynamicTable" v-on:change="this.getFeatureSelection"></div>
</template>
<script>
import { EventBus } from '../main.js'
export default {
name: 'FeatureSelection',
data () {
return {
GetResults: '',
datafromCheckbox: '',
loop: 0
}
},
methods: {
FeatureSelection () {
document.getElementById("myDynamicTable").innerHTML = "";
let Features= JSON.parse(this.GetResults[7])
let ClassifierswithoutFI = JSON.parse(this.GetResults[8])
let ClassifierswithFI = JSON.parse(this.GetResults[9])
const limit = JSON.parse(this.GetResults[13])
var Classifiers
Classifiers = ClassifierswithoutFI.concat(ClassifierswithFI)
var limitList = []
if (limit == '') {
for (let i = 0; i < Classifiers.length; i++) {
limitList.push(Classifiers[i])
}
} else {
limitList = []
for (let i = 0; i < limit.length; i++) {
for (let j = 0; j < Classifiers.length; j++) {
if (Number(limit[i].match(/\d+/)[0]) == Classifiers[j]) {
limitList.push(Number(limit[i].match(/\d+/)[0]))
}
}
}
}
var myTableDiv = document.getElementById("myDynamicTable");
var table = document.createElement('TABLE');
table.border = '1';
var tableBody = document.createElement('TBODY');
table.appendChild(tableBody);
var checkBoxArray = []
for (var i = 0; i < limitList.length+1; i++) {
var tr = document.createElement('TR');
tableBody.appendChild(tr);
for (var j = 0; j < Features.length; j++) {
if (j == 0){
if (i == 0) {
var td = document.createElement('TD');
td.width = '75';
td.appendChild(document.createTextNode(''));
tr.appendChild(td);
} else {
var td = document.createElement('TD');
td.width = '90';
td.appendChild(document.createTextNode('M ' + (i - 1)));
tr.appendChild(td);
}
}
if (i == 0){
var td = document.createElement('TD');
td.width = '30';
td.appendChild(document.createTextNode('F ' + j));
tr.appendChild(td);
} else {
var checkbox = document.createElement('input');
checkbox.type = "checkbox";
checkbox.checked = true;
checkbox.name = i-1;
checkbox.text = "F " + j
checkbox.value = "value";
checkbox.id = "M " + (i-1) + ", F " + j;
checkBoxArray.push(checkbox)
var td = document.createElement('TD');
td.appendChild(myTableDiv.appendChild(checkbox));
tr.appendChild(td);
}
}
}
//if (this.loop == 0) {
myTableDiv.appendChild(table);
//}
this.loop++
this.datafromCheckbox = checkBoxArray
},
getFeatureSelection () {
var results = new Array()
this.datafromCheckbox.forEach(eachCheckbox => {
if (eachCheckbox.checked == true) {
results.push('ClassifierID: ' + eachCheckbox.name, 'FeatureName: ' + eachCheckbox.text, 'Check: 1')
}
else {
results.push('ClassifierID: ' + eachCheckbox.name, 'FeatureName: ' + eachCheckbox.text, 'Check: 0')
}
});
EventBus.$emit('SendSelectedFeaturesEvent', results)
},
reset () {
document.getElementById("myDynamicTable").innerHTML = "";
}
},
mounted () {
EventBus.$on('emittedEventCallingTableView', data => { this.GetResults = data })
EventBus.$on('emittedEventCallingTableView', this.FeatureSelection)
EventBus.$on('resetViews', this.reset)
}
}
</script>

@ -5,27 +5,53 @@
<script> <script>
import * as d3Base from 'd3' import * as d3Base from 'd3'
import { EventBus } from '../main.js' import { EventBus } from '../main.js'
import $ from 'jquery'
import * as colorbr from 'colorbrewer'
// attach all d3 plugins to the d3 library // attach all d3 plugins to the d3 library
const d3 = Object.assign(d3Base) const d3 = Object.assign(d3Base)
const colorbrewer = Object.assign(colorbr)
export default { export default {
name: "Heatmap", name: "Heatmap",
data () { data () {
return { return {
GetResultsAll: '', GetResultsAll: '',
Toggles: '',
limitation: 0,
flag: false,
classesNumber: 10,
cellSize: 24
} }
}, },
methods: { methods: {
Refresh () {
EventBus.$emit('SendSelectedFeaturesEvent', '')
},
Heatmap () { Heatmap () {
// Clear Heatmap first // Clear Heatmap first
var svg = d3.select("#Heatmap"); var svg = d3.select("#Heatmap");
svg.selectAll("*").remove(); svg.selectAll("*").remove();
//svg.selectAll("*").remove();
//var FeaturesImportance = JSON.parse(this.GetResultsAll[3])
var FeaturesAccuracy = JSON.parse(this.GetResultsAll[5])
var Features= JSON.parse(this.GetResultsAll[6])
var ClassifierswithoutFI = JSON.parse(this.GetResultsAll[7])
var ClassifierswithFI = JSON.parse(this.GetResultsAll[8])
var Classifiers
Classifiers = ClassifierswithoutFI.concat(ClassifierswithFI)
//var RFEList = JSON.parse(this.GetResultsAll[13])
var PermImpEli = JSON.parse(this.GetResultsAll[12])
var featureUni = JSON.parse(this.GetResultsAll[13])
var limit
if (this.flag) {
limit = this.limitation;
} else {
limit = JSON.parse(this.GetResultsAll[14])
this.limitation = limit;
}
var FeaturesAccuracy = JSON.parse(this.GetResultsAll[6])
var Features= JSON.parse(this.GetResultsAll[7])
const limit = JSON.parse(this.GetResultsAll[13])
var Classifiers = JSON.parse(this.GetResultsAll[8])
if (Classifiers != '') { if (Classifiers != '') {
var limitList = [] var limitList = []
@ -44,66 +70,77 @@ export default {
} }
} }
var maxUni = Math.max.apply(Math, featureUni.map(function(o) { return o.Score; }))
var minUni = Math.min.apply(Math, featureUni.map(function(o) { return o.Score; }))
let len = Features.length let len = Features.length
let indicesYAxis = new Array(len) let indicesYAxis = new Array(len)
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
indicesYAxis[i] = i indicesYAxis[i] = [Features[i]]
} }
var len2 = limitList.length
// set the dimensions and margins of the graph
var margin = {top: 30, right: 30, bottom: 30, left: 30},
width = 300 - margin.left - margin.right,
height = 300 - margin.top - margin.bottom;
// append the svg object to the body of the page
var svg = d3.select("#Heatmap")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
let len2 = limitList.length
let indicesXAxis = new Array(len) let indicesXAxis = new Array(len)
var temp = []
for (let i = 0; i < len2; i++) { for (let i = 0; i < len2; i++) {
indicesXAxis[i] = i temp = []
} temp.push("R")
temp.push("Model "+i.toString())
// Labels of row and columns indicesXAxis[i] = temp
var myGroups = indicesXAxis }
var myVars = indicesYAxis temp = []
temp.push("R")
// Build X scales and axis: temp.push("Average")
var x = d3.scaleBand() indicesXAxis[len2] = temp
.range([ 0, width ])
.domain(myGroups)
.padding(0.01);
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
// Build X scales and axis:
var y = d3.scaleBand()
.range([ height, 0 ])
.domain(myVars)
.padding(0.01);
svg.append("g")
.call(d3.axisLeft(y));
// Build color scale
var myColor = d3.scaleLinear().range(["#deebf7", "#08306b"])
.domain([1,100])
var data = [] let withoutfilength = ClassifierswithoutFI.length
var values = []
var msg = false
var counter = 0 var counter = 0
var modelData = []
for (let j = 0; j < len2; j++) { for (let j = 0; j < len2; j++) {
var data = []
for (let i = 0; i <len; i++) { for (let i = 0; i <len; i++) {
data.push({'group':indicesXAxis[j], 'variable':indicesYAxis[i],'value':FeaturesAccuracy[counter][0]*100}) if (this.Toggles[0] == 1 && this.Toggles[1] == 1 && this.Toggles[2] == 1) {
values[j] = ((((featureUni[i].Score-minUni)/(maxUni-minUni))*100)+(PermImpEli[j][i]*100+(FeaturesAccuracy[counter][0]*100)))/3
}
else if (this.Toggles[0] == 1 && this.Toggles[1] == 1 && this.Toggles[2] == 0) {
values[j] = ((((featureUni[i].Score-minUni)/(maxUni-minUni))*100)+(PermImpEli[j][i]*100))/2
}
else if (this.Toggles[0] == 1 && this.Toggles[1] == 0 && this.Toggles[2] == 1) {
values[j] = ((((featureUni[i].Score-minUni)/(maxUni-minUni))*100)+(FeaturesAccuracy[counter][0]*100))/2
}
else if (this.Toggles[0] == 0 && this.Toggles[1] == 1 && this.Toggles[2] == 1) {
values[j] = ((PermImpEli[j][i]*100))/2
}
else if (this.Toggles[0] == 1 && this.Toggles[1] == 0 && this.Toggles[2] == 0) {
values[j] = ((featureUni[i].Score-minUni)/(maxUni-minUni))*100
}
else if (this.Toggles[0] == 0 && this.Toggles[1] == 1 && this.Toggles[2] == 0) {
values[j] = PermImpEli[j][i]*100
}
else if (this.Toggles[0] == 0 && this.Toggles[1] == 0 && this.Toggles[2] == 1) {
values[j] = FeaturesAccuracy[counter][0]*100
} else {
continue
}
data.push(values[j]/100)
counter++ counter++
} }
modelData.push(data)
} }
var transposedArray = []
transposedArray = modelData[0].map((col, i) => modelData.map(row => row[i]))
let sum = 0
let avg = 0
for (let i = 0; i < transposedArray.length; i++) {
sum = 0
sum = (transposedArray[i].reduce((previous, current) => current += previous))
avg = sum / transposedArray[i].length
transposedArray[i][transposedArray[i].length] = avg
}
var dataAll = {"columns":indicesXAxis,"index":indicesYAxis,"data":transposedArray}
this.heatmap_display(dataAll, "#Heatmap");
/*
// add the squares // add the squares
svg.selectAll() svg.selectAll()
.data(data, function(d) {return d.group+':'+d.variable;}) .data(data, function(d) {return d.group+':'+d.variable;})
@ -114,7 +151,412 @@ export default {
.attr("width", x.bandwidth() ) .attr("width", x.bandwidth() )
.attr("height", y.bandwidth() ) .attr("height", y.bandwidth() )
.style("fill", function(d) { return myColor(d.value)} ) .style("fill", function(d) { return myColor(d.value)} )
*/
}
},
heatmap_display(data, heatmapId) {
var cellSize = this.cellSize
//##########################################################################
// Patrick.Brockmann@lsce.ipsl.fr
//##########################################################################
//==================================================
// References
// http://bl.ocks.org/Soylent/bbff6cc507dca2f48792
// http://bost.ocks.org/mike/selection/
// http://bost.ocks.org/mike/join/
// http://stackoverflow.com/questions/9481497/understanding-how-d3-js-binds-data-to-nodes
// http://bost.ocks.org/mike/miserables/
// http://bl.ocks.org/ianyfchang/8119685
//==================================================
var tooltip = d3.select(heatmapId)
.append("div")
.style("position", "absolute")
.style("visibility", "hidden");
//==================================================
// http://bl.ocks.org/mbostock/3680958
/* function zoom() {
console.log(d3.event.translate)
console.log(d3.event.scale)
svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}*/
// define the zoomListener which calls the zoom function on the "zoom" event constrained within the scaleExtents
const zoom = d3.zoom()
.scaleExtent([0.1, 3]) //zoom limit
.on('zoom', () => {
svg.attr('transform', d3.event.transform) // updated for d3 v4
})
//==================================================
var viewerWidth = $(document).width()/4.5;
var viewerHeight = $(document).height()/6;
var viewerPosTop = 125;
var viewerPosLeft = 100;
var legendElementWidth = cellSize * 2;
// http://bl.ocks.org/mbostock/5577023
var colors = colorbrewer.RdYlGn[this.classesNumber];
// http://bl.ocks.org/mbostock/3680999
var svg;
//==================================================
var arr = data.data;
var row_number = arr.length;
var col_number = arr[0].length;
var colorScale = d3.scaleQuantize()
.domain([0.0, 1.0])
.range(colors);
svg = d3.select(heatmapId).append("svg")
.attr("width", viewerWidth)
.attr("height", viewerHeight)
.call(zoom)
//.call(zoom.transform, d3.zoomIdentity.translate(200, 20).scale(0.25)) //initial size
.append('svg:g')
.attr("transform", "translate(" + viewerPosLeft + "," + viewerPosTop + ")");
svg.append('defs')
.append('pattern')
.attr('id', 'diagonalHatch')
.attr('patternUnits', 'userSpaceOnUse')
.attr('width', 4)
.attr('height', 4)
.append('path')
.attr('d', 'M-1,1 l2,-2 M0,4 l4,-4 M3,5 l2,-2')
.attr('stroke', '#000000')
.attr('stroke-width', 1);
var rowSortOrder = false;
var colSortOrder = false;
var rowLabels = svg.append("g")
.attr("class", "rowLabels")
.selectAll(".rowLabel")
.data(data.index)
.enter().append("text")
.text(function(d) {
return d.count > 1 ? d.join("/") : d;
})
.attr("x", 0)
.attr("y", function(d, i) {
return (i * cellSize);
})
.style("text-anchor", "end")
.attr("transform", function(d, i) {
return "translate(-3," + cellSize / 1.5 + ")";
})
.attr("class", "rowLabel mono")
.attr("id", function(d, i) {
return "rowLabel_" + i;
})
.on('mouseover', function(d, i) {
d3.select('#rowLabel_' + i).classed("hover", true);
})
.on('mouseout', function(d, i) {
d3.select('#rowLabel_' + i).classed("hover", false);
})
.on("click", function(d, i) {
rowSortOrder = !rowSortOrder;
sortByValues("r", i, rowSortOrder);
d3.select("#order").property("selectedIndex", 0);
//$("#order").jqxComboBox({selectedIndex: 0});
});
var colLabels = svg.append("g")
.attr("class", "colLabels")
.selectAll(".colLabel")
.data(data.columns)
.enter().append("text")
.text(function(d) {
d.shift();
return d.count > 1 ? d.reverse().join("/") : d.reverse();
})
.attr("x", 0)
.attr("y", function(d, i) {
return (i * cellSize);
})
.style("text-anchor", "left")
.style('font-weight',function(d,i){
/*if (d[0] === "Average") {
return "bold"
}*/
})
.attr("transform", function(d, i) {
return "translate(" + cellSize / 2 + ", -3) rotate(-90) rotate(45, 0, " + (i * cellSize) + ")";
})
.attr("class", "colLabel mono")
.attr("id", function(d, i) {
return "colLabel_" + i;
})
.on('mouseover', function(d, i) {
d3.select('#colLabel_' + i).classed("hover", true);
})
.on('mouseout', function(d, i) {
d3.select('#colLabel_' + i).classed("hover", false);
})
.on("click", function(d, i) {
colSortOrder = !colSortOrder;
sortByValues("c", i, colSortOrder);
d3.select("#order").property("selectedIndex", 0);
});
var row = svg.selectAll(".row")
.data(data.data)
.enter().append("g")
.attr("id", function(d) {
return d.idx;
})
.attr("class", "row");
var heatMap = row.selectAll(".cell")
.data(function(d) {
return d;
})
.enter().append("svg:rect")
.attr("id", function(d, i, j){
var k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode) - 3;
return k.toString()+i.toString();
})
.attr("x", function(d, i) {
return i * cellSize;
})
.attr("y", function(d, i, j) {
var k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode) - 3;
return k * cellSize;
})
.attr("rx", 4)
.attr("ry", 4)
.attr("class", function(d, i, j) {
var k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode) - 3;
return "cell bordered cr" + k + " cc" + i;
})
.attr("row", function(d, i, j) {
var k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode) - 3;
return k;
})
.attr("col", function(d, i, j) {
return i;
})
.attr("width", cellSize)
.attr("height", cellSize)
.style("fill", function(d) {
if (d != null) return colorScale(d);
else return "url(#diagonalHatch)";
})
.on('mouseover', function(d, i, j) {
var k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode) - 3;
d3.select('#colLabel_' + i).classed("hover", true);
d3.select('#rowLabel_' + k).classed("hover", true);
if (d != null) {
tooltip.style("visibility", "visible");
tooltip.html('<div class="heatmap_tooltip">' + d.toFixed(3) + '</div>');
} else
tooltip.style("visibility", "hidden");
})
.on('mouseout', function(d, i, j) {
var k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode) - 3;
d3.select('#colLabel_' + i).classed("hover", false);
d3.select('#rowLabel_' + k).classed("hover", false);
tooltip.style("visibility", "hidden");
})
.on("mousemove", function(d, i) {
tooltip.style("top", (d3.mouse(this)[1]+75) + "px").style("left", (d3.mouse(this)[0]+87) + "px");
})
.on('click', function(d, i, j) {
var rowsExtracted = svg.selectAll(".row")._groups[0]
var k = Array.prototype.indexOf.call(j[i].parentNode.parentNode.childNodes,j[i].parentNode) - 3;
d3.select(this).style("fill", function(d) {
if (d3.select(this).style("fill") === "url(\"#diagonalHatch\")"){
return colorScale(d)
} else {
return "url(#diagonalHatch)"
}
})
if (i+1 === j.length) {
if(d3.select(this).style("fill") === "url(\"#diagonalHatch\")") {
row.selectAll(".cr"+k).style("fill", "url(#diagonalHatch)")
} else {
row.selectAll(".cr"+k).style("fill", function(d) {
return colorScale(d)
})
}
}
var results = new Array()
for (let i = 0; i < rowsExtracted[0].childNodes.length; i++) {
for (let j = 0; j < rowsExtracted.length; j++) {
if (rowsExtracted[j].childNodes[i].style.fill === "url(\"#diagonalHatch\")") {
results.push('ClassifierID: ' + i, 'FeatureName: ' + j, 'Check: 0')
} else {
results.push('ClassifierID: ' + i, 'FeatureName: ' + j, 'Check: 1')
}
}
}
EventBus.$emit('SendSelectedFeaturesEvent', results)
});
var legend = svg.append("g")
.attr("class", "legend")
.attr("transform", "translate(0,-240)")
.selectAll(".legendElement")
.data([0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
.enter().append("g")
.attr("class", "legendElement");
legend.append("svg:rect")
.attr("x", function(d, i) {
return legendElementWidth * i;
})
.attr("y", viewerPosTop)
.attr("class", "cellLegend bordered")
.attr("width", legendElementWidth)
.attr("height", cellSize / 2)
.style("fill", function(d, i) {
return colors[i];
});
legend.append("text")
.attr("class", "mono legendElement")
.text(function(d) {
return "≥" + Math.round(d * 100) / 100;
})
.attr("x", function(d, i) {
return legendElementWidth * i;
})
.attr("y", viewerPosTop + cellSize);
//==================================================
// Change ordering of cells
function sortByValues(rORc, i, sortOrder) {
var t = svg.transition().duration(1000);
var values = [];
var sorted;
d3.selectAll(".c" + rORc + i)
.filter(function(d) {
if (d != null) values.push(d);
else values.push(-999); // to handle NaN
});
//console.log(values);
if (rORc == "r") { // sort on cols
sorted = d3.range(col_number).sort(function(a, b) {
if (sortOrder) {
return values[b] - values[a];
} else {
return values[a] - values[b];
}
});
t.selectAll(".cell")
.attr("x", function(d) {
var col = parseInt(d3.select(this).attr("col"));
return sorted.indexOf(col) * cellSize;
});
t.selectAll(".colLabel")
.attr("y", function(d, i) {
return sorted.indexOf(i) * cellSize;
})
.attr("transform", function(d, i) {
return "translate(" + cellSize / 2 + ", -3) rotate(-90) rotate(45, 0, " + (sorted.indexOf(i) * cellSize) + ")";
});
} else { // sort on rows
sorted = d3.range(row_number).sort(function(a, b) {
if (sortOrder) {
return values[b] - values[a];
} else {
return values[a] - values[b];
}
});
t.selectAll(".cell")
.attr("y", function(d) {
var row = parseInt(d3.select(this).attr("row"));
return sorted.indexOf(row) * cellSize;
});
t.selectAll(".rowLabel")
.attr("y", function(d, i) {
return sorted.indexOf(i) * cellSize;
})
.attr("transform", function(d, i) {
return "translate(-3," + cellSize / 1.5 + ")";
});
}
}
//==================================================
d3.select("#order").on("change", function() {
var newOrder = d3.select("#order").property("value");
this.changeOrder(newOrder, heatmapId);
});
//==================================================
d3.select("#palette")
.on("keyup", function() {
var newPalette = d3.select("#palette").property("value");
if (newPalette != null) // when interfaced with jQwidget, the ComboBox handles keyup event but value is then not available ?
this.changePalette(newPalette, heatmapId);
})
.on("change", function() {
var newPalette = d3.select("#palette").property("value");
this.changePalette(newPalette, heatmapId);
});
//==================================================
},
changeOrder(newOrder, heatmapId) {
var svg = d3.select(heatmapId);
var cellSize = this.cellSize
var t = svg.transition().duration(1000);
if (newOrder == "sortinit_col") { // initial sort on cols (alphabetically if produced like this)
t.selectAll(".cell")
.attr("x", function(d) {
var col = parseInt(d3.select(this).attr("col"));
return col * cellSize;
});
t.selectAll(".colLabel")
.attr("y", function(d, i) {
return i * cellSize;
})
.attr("transform", function(d, i) {
return "translate(" + cellSize / 2 + ", -3) rotate(-90) rotate(45, 0, " + (i * cellSize) + ")";
});
} else if (newOrder == "sortinit_row") { // initial sort on rows (alphabetically if produced like this)
t.selectAll(".cell")
.attr("y", function(d) {
var row = parseInt(d3.select(this).attr("row"));
return row * cellSize;
});
t.selectAll(".rowLabel")
.attr("y", function(d, i) {
return i * cellSize;
})
.attr("transform", function(d, i) {
return "translate(-3," + cellSize / 1.5 + ")";
});
} else if (newOrder == "sortinit_col_row") { // initial sort on rows and cols (alphabetically if produced like this)
t.selectAll(".cell")
.attr("x", function(d) {
var col = parseInt(d3.select(this).attr("col"));
return col * cellSize;
})
.attr("y", function(d) {
var row = parseInt(d3.select(this).attr("row"));
return row * cellSize;
});
t.selectAll(".colLabel")
.attr("y", function(d, i) {
return i * cellSize;
})
.attr("transform", function(d, i) {
return "translate(" + cellSize / 2 + ", -3) rotate(-90) rotate(45, 0, " + (i * cellSize) + ")";
});
t.selectAll(".rowLabel")
.attr("y", function(d, i) {
return i * cellSize;
})
.attr("transform", function(d, i) {
return "translate(-3," + cellSize / 1.5 + ")";
});
} }
}, },
reset () { reset () {
@ -123,9 +565,92 @@ export default {
} }
}, },
mounted () { mounted () {
EventBus.$on('emittedEventCallingHeatmapView', data => { this.GetResultsAll = data }) EventBus.$on('emittedEventCallingToggles', data => { this.Toggles = data })
EventBus.$on('emittedEventCallingHeatmapView', data => { this.GetResultsAll = data; this.flag = false })
EventBus.$on('emittedEventCallingHeatmapView', this.Heatmap) EventBus.$on('emittedEventCallingHeatmapView', this.Heatmap)
EventBus.$on('emittedEventCallingTogglesUpdate', data => { this.Toggles = data; this.flag = true })
EventBus.$on('emittedEventCallingTogglesUpdate', this.Refresh)
EventBus.$on('emittedEventCallingTogglesUpdate', this.Heatmap)
EventBus.$on('resetViews', this.reset) EventBus.$on('resetViews', this.reset)
} }
} }
</script> </script>
<style>
.heatmap {
font-size: 8px;
font-family: monospace;
}
rect.bordered {
stroke: #E6E6E6;
stroke-width:2px;
}
text.mono {
font-size: 8px;
font-family: monospace;
fill: #000;
}
text.legendElement {
font-size: 10px;
}
text.hover {
font-weight: bold;
fill: #007bff;
font-background: #000;
}
.heatmap_tooltip {
text-align: center;
font-family: monospace;
font-size: 14pt;
color: #000;
position: relative;
background: rgba(255, 255, 255, 0.8);
border: 4px solid #007bff;
padding: 5px;
border-radius: 8px ;
-webkit-border-top-left-radius: 8px;
-webkit-border-top-right-radius: 8px;
-webkit-border-bottom-right-radius: 8px;
-webkit-border-bottom-left-radius: 8px;
-khtml-border-top-left-radius: 8px;
-khtml-border-top-right-radius: 8px;
-khtml-border-bottom-right-radius: 8px;
-khtml-border-bottom-left-radius: 8px;
-moz-border-radius-topleft: 8px;
-moz-border-radius-topright: 8px;
-moz-border-radius-bottomright: 8px;
-moz-border-radius-bottomleft: 8px;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;
width: 100px;
z-index:10000;
-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.8);
-moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.8);
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.8);
}
.heatmap_tooltip:after, .heatmap_tooltip:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.heatmap_tooltip:after {
border-color: rgba(236, 240, 241, 0);
border-top-color: #FFFFF;
border-width: 10px;
left: 50%;
margin-left: -10px;
}
.heatmap_tooltip:before {
border-color: rgba(44, 62, 80, 0);
border-top-color: #007bff;
border-width: 16px;
left: 50%;
margin-left: -16px;
}
</style>

@ -6,7 +6,7 @@
<b-row class="md-3"> <b-row class="md-3">
<b-col cols="3"> <b-col cols="3">
<mdb-card> <mdb-card>
<mdb-card-header color="primary-color" tag="h5" class="text-center">Data Set Selection and Execution</mdb-card-header> <mdb-card-header color="primary-color" tag="h5" class="text-center">Basic Operations Control Panel</mdb-card-header>
<mdb-card-body> <mdb-card-body>
<mdb-card-text class="text-center" > <mdb-card-text class="text-center" >
<DataSetExecController <DataSetExecController
@ -18,7 +18,7 @@
</b-col> </b-col>
<b-col cols="6"> <b-col cols="6">
<mdb-card> <mdb-card>
<mdb-card-header color="primary-color" tag="h5" class="text-center">Per Class Metrics Exploration</mdb-card-header> <mdb-card-header color="primary-color" tag="h5" class="text-center">Diverse Models Exploration</mdb-card-header>
<mdb-card-body> <mdb-card-body>
<BarChart/> <BarChart/>
</mdb-card-body> </mdb-card-body>
@ -48,21 +48,18 @@
</b-col> </b-col>
<b-col cols="6"> <b-col cols="6">
<mdb-card> <mdb-card>
<mdb-card-header color="primary-color" tag="h5" class="text-center">Subset Feature Selection Per Model</mdb-card-header> <mdb-card-header color="primary-color" tag="h5" class="text-center">Models Feature Selection</mdb-card-header>
<b-row> <b-row>
<b-col cols="4"> <b-col cols="12">
<mdb-card-body>
<StretchedChord/>
</mdb-card-body>
</b-col>
<b-col cols="4">
<mdb-card-body> <mdb-card-body>
<Heatmap/> <Heatmap/>
</mdb-card-body> </mdb-card-body>
</b-col> </b-col>
<b-col cols="4"> </b-row>
<b-row>
<b-col cols="12">
<mdb-card-body> <mdb-card-body>
<FeatureSelection/> <ToggleSelection/>
</mdb-card-body> </mdb-card-body>
</b-col> </b-col>
</b-row> </b-row>
@ -118,13 +115,13 @@ import ScatterPlot from './ScatterPlot.vue'
import DataSpace from './DataSpace.vue' import DataSpace from './DataSpace.vue'
import PredictionsSpace from './PredictionsSpace.vue' import PredictionsSpace from './PredictionsSpace.vue'
import BarChart from './BarChart.vue' import BarChart from './BarChart.vue'
import StretchedChord from './StretchedChord.vue'
import Heatmap from './Heatmap.vue' import Heatmap from './Heatmap.vue'
import FeatureSelection from './FeatureSelection.vue' import ToggleSelection from './ToggleSelection.vue'
import FinalResultsLinePlot from './FinalResultsLinePlot.vue' import FinalResultsLinePlot from './FinalResultsLinePlot.vue'
import axios from 'axios' import axios from 'axios'
import { loadProgressBar } from 'axios-progress-bar' import { loadProgressBar } from 'axios-progress-bar'
import 'axios-progress-bar/dist/nprogress.css' import 'axios-progress-bar/dist/nprogress.css'
import 'bootstrap-css-only/css/bootstrap.min.css'
import { mdbCard, mdbCardBody, mdbCardText, mdbCardHeader } from 'mdbvue' import { mdbCard, mdbCardBody, mdbCardText, mdbCardHeader } from 'mdbvue'
import { EventBus } from '../main.js' import { EventBus } from '../main.js'
import * as jQuery from 'jquery' import * as jQuery from 'jquery'
@ -145,9 +142,8 @@ export default Vue.extend({
DataSpace, DataSpace,
PredictionsSpace, PredictionsSpace,
BarChart, BarChart,
StretchedChord,
Heatmap, Heatmap,
FeatureSelection, ToggleSelection,
FinalResultsLinePlot, FinalResultsLinePlot,
mdbCard, mdbCard,
mdbCardBody, mdbCardBody,
@ -180,7 +176,10 @@ export default Vue.extend({
valueSel: 0, valueSel: 0,
valueAll: 0, valueAll: 0,
OverSelLength: 0, OverSelLength: 0,
OverAllLength: 0 OverAllLength: 0,
toggle1: 1,
toggle2: 1,
toggle3: 1
} }
}, },
methods: { methods: {
@ -240,10 +239,17 @@ export default Vue.extend({
var length = JSON.parse(this.OverviewResults[0]).length var length = JSON.parse(this.OverviewResults[0]).length
this.OverSelLength = length this.OverSelLength = length
this.OverAllLength = length this.OverAllLength = length
this.valueSel = 0
this.valueAll = 0
var toggles = []
toggles.push(this.toggle1)
toggles.push(this.toggle2)
toggles.push(this.toggle3)
if (length < this.limitModels) { if (length < this.limitModels) {
this.OverviewResults.push(JSON.stringify(this.ClassifierIDsList)) this.OverviewResults.push(JSON.stringify(this.ClassifierIDsList))
EventBus.$emit('emittedEventCallingBarChart', this.OverviewResults) EventBus.$emit('emittedEventCallingBarChart', this.OverviewResults)
EventBus.$emit('emittedEventCallingChordView', this.OverviewResults) EventBus.$emit('emitToggles', this.OverviewResults)
EventBus.$emit('emittedEventCallingToggles', toggles)
EventBus.$emit('emittedEventCallingHeatmapView', this.OverviewResults) EventBus.$emit('emittedEventCallingHeatmapView', this.OverviewResults)
EventBus.$emit('emittedEventCallingTableView', this.OverviewResults) EventBus.$emit('emittedEventCallingTableView', this.OverviewResults)
EventBus.$emit('emittedEventCallingDataSpacePlotView', this.OverviewResults) EventBus.$emit('emittedEventCallingDataSpacePlotView', this.OverviewResults)
@ -305,7 +311,6 @@ export default Vue.extend({
if (this.ClassifierIDsList.length < this.limitModels) { if (this.ClassifierIDsList.length < this.limitModels) {
this.OverviewResults.push(JSON.stringify(this.ClassifierIDsList)) this.OverviewResults.push(JSON.stringify(this.ClassifierIDsList))
EventBus.$emit('emittedEventCallingBarChart', this.OverviewResults) EventBus.$emit('emittedEventCallingBarChart', this.OverviewResults)
EventBus.$emit('emittedEventCallingChordView', this.OverviewResults)
EventBus.$emit('emittedEventCallingHeatmapView', this.OverviewResults) EventBus.$emit('emittedEventCallingHeatmapView', this.OverviewResults)
EventBus.$emit('emittedEventCallingTableView', this.OverviewResults) EventBus.$emit('emittedEventCallingTableView', this.OverviewResults)
EventBus.$emit('emittedEventCallingDataSpacePlotView', this.OverviewResults) EventBus.$emit('emittedEventCallingDataSpacePlotView', this.OverviewResults)
@ -390,7 +395,6 @@ export default Vue.extend({
SendBrushedParameters () { SendBrushedParameters () {
EventBus.$emit('emittedEventCallingModelBrushed') EventBus.$emit('emittedEventCallingModelBrushed')
const path = `http://127.0.0.1:5000/data/SendBrushedParam` const path = `http://127.0.0.1:5000/data/SendBrushedParam`
this.brushedAll.push(this.brushed)
const postData = { const postData = {
brushed: this.brushed, brushed: this.brushed,
algorithm: this.selectedAlgorithm algorithm: this.selectedAlgorithm
@ -418,8 +422,7 @@ export default Vue.extend({
UpdateBasedonFeatures () { UpdateBasedonFeatures () {
const path = `http://127.0.0.1:5000/data/FeaturesSelection` const path = `http://127.0.0.1:5000/data/FeaturesSelection`
const postData = { const postData = {
featureSelection: this.SelectedFeaturesPerClassifier, featureSelection: this.SelectedFeaturesPerClassifier
brushedAll: this.brushedAll
} }
const axiosConfig = { const axiosConfig = {
headers: { headers: {
@ -531,6 +534,13 @@ export default Vue.extend({
console.log(error) console.log(error)
}) })
}, },
updateToggle () {
var toggles = []
toggles.push(this.toggle1)
toggles.push(this.toggle2)
toggles.push(this.toggle3)
EventBus.$emit('emittedEventCallingTogglesUpdate', toggles)
}
}, },
created() { created() {
// does the browser support the Navigation Timing API? // does the browser support the Navigation Timing API?
@ -564,6 +574,12 @@ export default Vue.extend({
EventBus.$on('SendToServerDataSetConfirmation', data => { this.RetrieveValueFile = data }) EventBus.$on('SendToServerDataSetConfirmation', data => { this.RetrieveValueFile = data })
EventBus.$on('SendToServerDataSetConfirmation', this.fileNameSend) EventBus.$on('SendToServerDataSetConfirmation', this.fileNameSend)
EventBus.$on('PCPCall', data => { this.selectedAlgorithm = data }) EventBus.$on('PCPCall', data => { this.selectedAlgorithm = data })
EventBus.$on('toggle1', data => { this.toggle1 = data })
EventBus.$on('toggle2', data => { this.toggle2 = data })
EventBus.$on('toggle3', data => { this.toggle3 = data })
EventBus.$on('toggle1', this.updateToggle)
EventBus.$on('toggle2', this.updateToggle)
EventBus.$on('toggle3', this.updateToggle)
EventBus.$on('PCPCall', this.CallPCP) EventBus.$on('PCPCall', this.CallPCP)
EventBus.$on('PCPCallDB', this.SendBrushedParameters) EventBus.$on('PCPCallDB', this.SendBrushedParameters)
EventBus.$on('UpdateBoxPlot', data => { this.brushedBoxPlotUpdate = data }) EventBus.$on('UpdateBoxPlot', data => { this.brushedBoxPlotUpdate = data })

@ -15,7 +15,7 @@ export default {
}, },
methods: { methods: {
ScatterPlotDataView () { ScatterPlotDataView () {
const XandYCoordinates = JSON.parse(this.PredictionsData[11]) const XandYCoordinates = JSON.parse(this.PredictionsData[10])
var result = XandYCoordinates.reduce(function(r, a) { var result = XandYCoordinates.reduce(function(r, a) {
a.forEach(function(s, i) { a.forEach(function(s, i) {

@ -1,581 +0,0 @@
<template>
<div id="chart"></div>
</template>
<script>
import * as d3Base from 'd3'
import { loom, string } from 'd3-loom'
import { EventBus } from '../main.js'
// attach all d3 plugins to the d3 library
const d3 = Object.assign(d3Base, { loom, string })
export default {
name: "StretchedChord",
data () {
return {
AllResults: 0
}
},
methods: {
StretchChord () {
d3.selectAll("#chart > *").remove();
const FeatureImportance = JSON.parse(this.AllResults[3])
const ClassNames = JSON.parse(this.AllResults[5])
const ClassifiersIDs = JSON.parse(this.AllResults[9])
const limit = JSON.parse(this.AllResults[13])
var limitList = []
if (limit == '') {
for (let i = 0; i < ClassifiersIDs.length; i++) {
limitList.push(ClassifiersIDs[i])
}
} else {
limitList = []
for (let i = 0; i < limit.length; i++) {
for (let j = 0; j < ClassifiersIDs.length; j++) {
if (Number(limit[i].match(/\d+/)[0]) == ClassifiersIDs[j]) {
limitList.push(Number(limit[i].match(/\d+/)[0]))
}
}
}
}
if (limitList.length != 0){
var SortFeaturesPerClass = []
var MergeSortFeaturesPerClass = []
var counter = 0
var SortFeaturesPerClassRemoveEmpty = []
var returnvalue = 0
FeatureImportance.forEach(classifier => {
for (let i = 0; i < limitList.length; i++) {
returnvalue = this.sortObject(classifier[i], limitList[counter], ClassNames[i])
if (returnvalue === undefined || returnvalue.length == 0) {
} else {
if (returnvalue[0]['classifier'] != 'M undefined') {
SortFeaturesPerClass.push(returnvalue)
}
}
}
counter++
})
//var SortFeaturesPerClassRemoveEmpty = SortFeaturesPerClass.filter(e => e.length);
MergeSortFeaturesPerClass = SortFeaturesPerClass[0]
for (let i = 0; i < SortFeaturesPerClass.length - 1; i++) {
MergeSortFeaturesPerClass = MergeSortFeaturesPerClass.concat(SortFeaturesPerClass[i+1])
}
var margin = {left:60, top:40, right:80, bottom:50},
width = Math.max( Math.min(window.innerWidth, 500) - margin.left - margin.right - 20, 10),
height = Math.max( Math.min(window.innerHeight - 250, 700) - margin.top - margin.bottom - 20, 10),
innerRadius = Math.min(width * 0.33, height * .45),
outerRadius = innerRadius * 1.05;
//Recalculate the width and height now that we know the radius
width = outerRadius * 2 + margin.right + margin.left;
height = outerRadius * 2 + margin.top + margin.bottom;
//Reset the overall font size
var newFontSize = Math.min(70, Math.max(40, innerRadius * 62.5 / 250));
d3.select("html").style("font-size", newFontSize + "%");
////////////////////////////////////////////////////////////
////////////////// Set-up Chord parameters /////////////////
////////////////////////////////////////////////////////////
var pullOutSize = 20 + 30/135 * innerRadius;
var numFormat = d3.format(",.0f");
var defaultOpacity = 0.85,
fadeOpacity = 0.075;
var loom = d3.loom()
.padAngle(0.05)
//.sortSubgroups(sortCharacter)
//.heightInner(0)
//.sortGroups(function(d) { return d.words })
//.sortLooms(d3.descending)
.emptyPerc(0)
.widthInner(40)
//.widthInner(function(d) { return 6 * d.length; })
.value(function(d) { return d.importancerate; })
.outercolorfun(function(d) { return d.class; })
.inner(function(d) { return d.feature; })
.outer(function(d) { return d.classifier; });
var arc = d3.arc()
.innerRadius(innerRadius*1.01)
.outerRadius(outerRadius);
var string = d3.string()
.radius(innerRadius)
.pullout(pullOutSize);
////////////////////////////////////////////////////////////
////////////////////// Create SVG //////////////////////////
////////////////////////////////////////////////////////////
d3.select("#chart").selectAll("*").remove();
var svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
////////////////////////////////////////////////////////////
///////////////////// Read in data /////////////////////////
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
///////////////////// Prepare the data /////////////////////
////////////////////////////////////////////////////////////
//Sort the inner characters based on the total number of words spoken
var dataAgg = MergeSortFeaturesPerClass
//Find the total number of words per character
var dataChar = d3.nest()
.key(function(d) { return d.character; })
.rollup(function(leaves) { return d3.sum(leaves, function(d) { return d.words; }); })
.entries(dataAgg)
.sort(function(a, b){ return d3.descending(a.value, b.value); });
//Unflatten the result
var characterOrder = dataChar.map(function(d) { return d.key })
//Sort the characters on a specific order
function sortCharacter(a, b) {
return characterOrder.indexOf(a) - characterOrder.indexOf(b)
}//sortCharacter
//Set more loom functions
loom
.sortSubgroups(sortCharacter)
.heightInner(innerRadius*0.2/characterOrder.length)
////////////////////////////////////////////////////////////
///////////////////////// Colors ///////////////////////////
////////////////////////////////////////////////////////////
var categories = ClassNames
var colors = ["#0000FF", "#ff0000", "#00ff00"]
var color = d3.scaleOrdinal()
.domain(categories)
.range(colors)
//Create a group that already holds the data
var g = svg.append("g")
.attr("transform", "translate(" + (width/2 + margin.left) + "," + (height/2 + margin.top) + ")")
.datum(loom(dataAgg))
////////////////////////////////////////////////////////////
///////////////////// Set-up title /////////////////////////
////////////////////////////////////////////////////////////
var titles = g.append("g")
.attr("class", "texts")
.style("opacity", 0)
titles.append("text")
.attr("class", "name-title")
.attr("x", 0)
.attr("y", -innerRadius*5/6)
titles.append("text")
.attr("class", "value-title")
.attr("x", 0)
.attr("y", -innerRadius*5/6 + 25)
//The character pieces
titles.append("text")
.attr("class", "character-note")
.attr("x", 0)
.attr("y", innerRadius/2)
.attr("dy", "0.35em")
////////////////////////////////////////////////////////////
////////////////////// Draw outer arcs /////////////////////
////////////////////////////////////////////////////////////
var arcs = g.append("g")
.attr("class", "arcs")
.selectAll("g")
.data(function(s) {
return s.groups
})
.enter().append("g")
.attr("class", "arc-wrapper")
.each(function(d) {
d.pullOutSize = (pullOutSize * ( d.startAngle > Math.PI + 1e-2 ? -1 : 1))
})
.on("mouseover", function(d) {
//Hide all other arcs
d3.selectAll(".arc-wrapper")
.transition()
.style("opacity", function(s) { return s.outername === d.outername ? 1 : 0.5 })
//Hide all other strings
d3.selectAll(".string")
.transition()
.style("opacity", function(s) { return s.outer.outername === d.outername ? 1 : fadeOpacity })
//Find the data for the strings of the hovered over location
var locationData = loom(dataAgg).filter(function(s) { return s.outer.outername === d.outername })
//Hide the characters who haven't said a word
d3.selectAll(".inner-label")
.transition()
.style("opacity", function(s) {
//Find out how many words the character said at the hovered over location
var char = locationData.filter(function(c) { return c.outer.innername === s.name })
return char.length === 0 ? 0.1 : 1
})
})
.on("mouseout", function(d) {
//Sjow all arc labels
d3.selectAll(".arc-wrapper")
.transition()
.style("opacity", 1)
//Show all strings again
d3.selectAll(".string")
.transition()
.style("opacity", defaultOpacity)
//Show all characters again
d3.selectAll(".inner-label")
.transition()
.style("opacity", 1)
})
var outerArcs = arcs.append("path")
.attr("class", "arc")
//.style("fill", function(d) { return color(d.outer.innername) })
.attr("d", arc)
.attr("transform", function(d, i) { //Pull the two slices apart
return "translate(" + d.pullOutSize + ',' + 0 + ")"
})
////////////////////////////////////////////////////////////
//////////////////// Draw outer labels /////////////////////
////////////////////////////////////////////////////////////
//The text needs to be rotated with the offset in the clockwise direction
var outerLabels = arcs.append("g")
.each(function(d) { d.angle = ((d.startAngle + d.endAngle) / 2) })
.attr("class", "outer-labels")
.attr("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null })
.attr("transform", function(d,i) {
var c = arc.centroid(d)
return "translate(" + (c[0] + d.pullOutSize) + "," + c[1] + ")"
+ "rotate(" + (d.angle * 180 / Math.PI - 90) + ")"
+ "translate(" + 26 + ",0)"
+ (d.angle > Math.PI ? "rotate(180)" : "")
})
//The outer name
outerLabels.append("text")
.attr("class", "outer-label")
.attr("dy", ".35em")
.text(function(d,i){ return d.outername })
//The value below it
outerLabels.append("text")
.attr("class", "outer-label-value")
.attr("dy", "1.5em")
.text(function(d,i){ return 'Rel.:' + numFormat(d.value) + '%'})
////////////////////////////////////////////////////////////
////////////////// Draw inner strings //////////////////////
////////////////////////////////////////////////////////////
var strings = g.append("g")
.attr("class", "stringWrapper")
.style("isolation", "isolate")
.selectAll("path")
.data(function(strings) {
return strings
})
.enter().append("path")
.attr("class", "string")
.style("mix-blend-mode", "multiply")
.attr("d", string)
.style("fill", function(d) {
return d3.rgb( color(d.outer.outercolor) ).brighter(0.2)
})
.style("opacity", defaultOpacity)
////////////////////////////////////////////////////////////
//////////////////// Draw inner labels /////////////////////
////////////////////////////////////////////////////////////
//The text also needs to be displaced in the horizontal directions
//And also rotated with the offset in the clockwise direction
var innerLabels = g.append("g")
.attr("class","inner-labels")
.selectAll("text")
.data(function(s) {
return s.innergroups
})
.enter().append("text")
.attr("class", "inner-label")
.attr("x", function(d,i) { return d.x })
.attr("y", function(d,i) { return d.y })
.style("text-anchor", "middle")
.attr("dy", ".35em")
.text(function(d,i) { return d.name })
.on("mouseover", function(d) {
//Show all the strings of the highlighted character and hide all else
d3.selectAll(".string")
.transition()
.style("opacity", function(s) {
return s.outer.innername !== d.name ? fadeOpacity : 1
})
//Update the word count of the outer labels
var characterData = loom(dataAgg).filter(function(s) { return s.outer.innername === d.name })
d3.selectAll(".outer-label-value")
.text(function(s,i){
//Find which characterData is the correct one based on location
var loc = characterData.filter(function(c) { return c.outer.outername === s.outername })
if(loc.length === 0) {
var value = 0
} else {
var value = loc[0].outer.value
}
return numFormat(value) + (value === 1 ? " Imp." : " Imp.")
})
//Hide the arc where the character hasn't said a thing
d3.selectAll(".arc-wrapper")
.transition()
.style("opacity", function(s) {
//Find which characterData is the correct one based on location
var loc = characterData.filter(function(c) { return c.outer.outername === s.outername })
return loc.length === 0 ? 0.1 : 1
})
})
.on("mouseout", function(d) {
//Put the string opacity back to normal
d3.selectAll(".string")
.transition()
.style("opacity", defaultOpacity)
//Return the word count to what it was
d3.selectAll(".outer-label-value")
.text(function(s,i){ return 'Imp.: ' + numFormat(s.value) })
//Show all arcs again
d3.selectAll(".arc-wrapper")
.transition()
.style("opacity", 1)
//Hide the title
d3.selectAll(".texts")
.transition()
.style("opacity", 0)
})
////////////////////////////////////////////////////////////
///////////////////// Extra functions //////////////////////
////////////////////////////////////////////////////////////
//Sort alphabetically
function sortAlpha(a, b){
if(a < b) return -1
if(a > b) return 1
return 0
}//sortAlpha
//Sort on the number of words
function sortWords(a, b){
if(a.words < b.words) return -1
if(a.words > b.words) return 1
return 0
}//sortWords
/*Taken from http://bl.ocks.org/mbostock/7555321
//Wraps SVG text*/
function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.2, // ems
y = parseFloat(text.attr("y")),
x = parseFloat(text.attr("x")),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", x).attr("y", y).attr("dy", dy + "em")
while (word = words.pop()) {
line.push(word)
tspan.text(line.join(" "))
if (tspan.node().getComputedTextLength() > width) {
line.pop()
tspan.text(line.join(" "))
line = [word]
tspan = text.append("tspan").attr("x", x).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word)
}
}
})
}//wrap
}
},
sortObject (obj, classifierID, ClassName) {
var arr = []
for (var prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
//if ((this.LimitFeatureImportance/100) < Math.abs(obj[prop])) {
arr.push({
'feature': 'F ' + prop,
'classifier': 'M ' + classifierID,
'class': ClassName,
'importancerate': Math.abs(Math.round(obj[prop] * 100))
})
//}
}
}
arr = arr.sort(function (a, b) { return Math.abs(b.ImportanceValue - a.ImportanceValue) })
return arr
},
ObjectSize (obj) {
let size = 0
let key
for (key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) size++
}
return size
},
reset () {
d3.selectAll("#chart > *").remove();
}
},
mounted () {
EventBus.$on('emittedEventCallingChordView', data => { this.AllResults = data })
EventBus.$on('emittedEventCallingChordView', this.StretchChord)
EventBus.$emit('resetViews', this.reset)
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
html { font-size: 62.5%; }
body {
font-family: 'Cormorant', serif;
font-size: 1.2rem;
fill: #b9b9b9;
}
.lotr-content-wrapper {
max-width: 900px;
margin: 0 auto;
}
#lotr-title {
font-size: 42px;
font-weight: 300;
margin: 40px 30px 0px 30px;
color: #272727;
}
#lotr-subtitle {
font-size: 14px;
color: #b1b1b1;
margin: 0px 30px 20px 30px;
font-weight: 300;
}
#lotr-intro {
font-size: 16px;
margin: 0px 30px 10px 30px;
max-width: 800px;
}
#lotr-note {
font-size: 14px;
margin: 0px 30px 10px 30px;
max-width: 800px;
color: #b1b1b1;
font-weight: 300;
}
#chart {
text-align: center;
}
#lotr-credit {
font-size: 14px;
margin: 10px 30px 5px 30px;
}
#lotr-sources {
font-size: 11px;
max-width: 300px;
margin: 15px 30px 5px 30px;
color: #9e9e9e;
font-weight: 300;
padding-bottom: 20px;
}
a:hover {
text-decoration: none;
border-bottom: 1px solid black;
}
a, a:link, a:visited, a:active {
text-decoration: none;
color: black;
border-bottom: 1px dotted rgba(0, 0, 0, .5);
}
.MiddleEarth {
font-family: 'Macondo', cursive;
color: #53821a;
}
/*--- chart ---*/
.name-title {
font-family: 'Macondo Swash Caps', cursive;
font-size: 2.8rem;
fill: #232323;
cursor: default;
text-anchor: middle;
}
.value-title {
text-anchor: middle;
font-size: 1.8rem;
fill: #b9b9b9;
}
.character-note {
text-anchor: middle;
font-size: 1.4rem;
fill: #232323;
}
.inner-label {
font-family: 'Macondo Swash Caps', cursive;
font-size: 1.4rem;
fill: #232323;
cursor: default;
}
.outer-label {
font-family: 'Macondo', cursive;
font-size: 1.6rem;
fill: #5f5f5f;
cursor: default;
}
.outer-label-value {
font-size: 1.2rem;
fill: #b9b9b9;
}
</style>

@ -0,0 +1,70 @@
<template>
<div>
<div id="toggles" style="visibility:hidden">
Univariate Selection:<input type="checkbox" id="toggle-uni" data-toggle="toggle" checked="checked" data-on="Enabled" data-off="Disabled" data-size="small">
Permutation Importance:<input type="checkbox" id="toggle-per" data-toggle="toggle" checked="checked" data-on="Enabled" data-off="Disabled" data-size="small">
Feature Accuracy Importance:<input type="checkbox" id="toggle-fi" data-toggle="toggle" checked="checked" data-on="Enabled" data-off="Disabled" data-size="small">
</div>
</div>
</template>
<script>
import { EventBus } from '../main.js'
import $ from 'jquery'
import { bootstrapToggle } from 'bootstrap-toggle'
import 'bootstrap-toggle/css/bootstrap-toggle.css'
export default {
name: 'ToggleSelection',
data () {
return {
}
},
methods: {
ToggleSelection () {
},
ToggleShow () {
document.getElementById('toggles').style.visibility = "visible"
}
},
mounted () {
$('#toggle-uni').bootstrapToggle({
on: 'Enabled',
off: 'Disabled'
});
$('#toggle-uni').change(function() {
var toggleID = document.getElementById('toggle-uni')
if (toggleID.checked === false) {
EventBus.$emit('toggle1', 0)
} else {
EventBus.$emit('toggle1', 1)
}
})
$('#toggle-per').bootstrapToggle({
on: 'Enabled',
off: 'Disabled'
});
$('#toggle-per').change(function() {
var toggleID = document.getElementById('toggle-per')
if (toggleID.checked === false) {
EventBus.$emit('toggle2', 0)
} else {
EventBus.$emit('toggle2', 1)
}
})
$('#toggle-fi').bootstrapToggle({
on: 'Enabled',
off: 'Disabled'
});
$('#toggle-fi').change(function() {
var toggleID = document.getElementById('toggle-fi')
if (toggleID.checked === false) {
EventBus.$emit('toggle3', 0)
} else {
EventBus.$emit('toggle3', 1)
}
})
EventBus.$on('emittedEventCallingToggles', this.ToggleShow)
}
}
</script>

@ -6,10 +6,10 @@ import 'bootstrap-vue/dist/bootstrap-vue.css'
import router from './router' import router from './router'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { faUpload, faPlay, faCheck, faSave} from '@fortawesome/free-solid-svg-icons' import { faUpload, faPlay, faCheck, faSave, faTrash} from '@fortawesome/free-solid-svg-icons'
import bFormSlider from 'vue-bootstrap-slider' import bFormSlider from 'vue-bootstrap-slider'
library.add(faUpload, faPlay, faCheck, faSave) library.add(faUpload, faPlay, faCheck, faSave, faTrash)
Vue.component('font-awesome-icon', FontAwesomeIcon) Vue.component('font-awesome-icon', FontAwesomeIcon)

193
run.py

@ -24,6 +24,14 @@ from sklearn.manifold import MDS
from sklearn.manifold import TSNE from sklearn.manifold import TSNE
from sklearn.metrics import classification_report from sklearn.metrics import classification_report
from sklearn.preprocessing import scale from sklearn.preprocessing import scale
#from sklearn.metrics import r2_score
#from rfpimp import permutation_importances
import eli5
from eli5.sklearn import PermutationImportance
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
from sklearn.feature_selection import RFE
from sklearn.decomposition import PCA
from mlxtend.classifier import StackingCVClassifier from mlxtend.classifier import StackingCVClassifier
from mlxtend.feature_selection import ColumnSelector from mlxtend.feature_selection import ColumnSelector
@ -53,6 +61,9 @@ def Reset():
global yData global yData
yData = [] yData = []
global detailsParams
detailsParams = []
global algorithmList global algorithmList
algorithmList = [] algorithmList = []
@ -130,6 +141,9 @@ def RetrieveFileName():
global algorithmList global algorithmList
algorithmList = [] algorithmList = []
global detailsParams
detailsParams = []
# Initializing models # Initializing models
global classifiersId global classifiersId
@ -263,7 +277,7 @@ def column_index(df, query_cols):
global mem global mem
mem = Memory("./cache_dir") mem = Memory("./cache_dir")
def GridSearch(clf, params, FI): def GridSearch(clf, params):
global XData global XData
global yData global yData
global scoring global scoring
@ -292,7 +306,10 @@ def GridSearch(clf, params, FI):
df_cv_results_classifiers = pd.DataFrame(data = df_cv_results_per_row, columns= df_cv_results.columns) df_cv_results_classifiers = pd.DataFrame(data = df_cv_results_per_row, columns= df_cv_results.columns)
parameters = df_cv_results_classifiers['params'] parameters = df_cv_results_classifiers['params']
PerClassMetrics = [] PerClassMetrics = []
FeatureImp = [] #perm_imp_rfpimp = []
#FeatureImp = []
#RFEList = []
permList = []
PerFeatureAccuracy = [] PerFeatureAccuracy = []
global subset global subset
global loopFeatures global loopFeatures
@ -326,24 +343,42 @@ def GridSearch(clf, params, FI):
element = (column_index(XData, featureSelected)) element = (column_index(XData, featureSelected))
columns.append(element) columns.append(element)
grid.fit(subset, yData) grid.fit(subset, yData)
if (FI == 0): #perm_imp_rfpimp.append(permutation_importances(grid.best_estimator_, subset, yData, r2)['Importance'])
n_feats = XData.shape[1] perm = PermutationImportance(grid.best_estimator_, cv = None, refit = True, n_iter = 50).fit(subset, yData)
permList.append(perm.feature_importances_)
n_feats = subset.shape[1]
for i in range(n_feats): for i in range(n_feats):
scores = model_selection.cross_val_score(grid.best_estimator_, XData.values[:, i].reshape(-1, 1), yData, cv=crossValidation) scores = model_selection.cross_val_score(grid.best_estimator_, subset.values[:, i].reshape(-1, 1), yData, cv=crossValidation)
PerFeatureAccuracy.append(scores.mean()) PerFeatureAccuracy.append(scores.mean())
yPredict = grid.predict(subset) yPredict = grid.predict(subset)
yPredictProb.append(grid.predict_proba(subset)) yPredictProb.append(grid.predict_proba(subset))
PerClassMetrics.append(classification_report(yData, yPredict, target_names=target_names, digits=2, output_dict=True)) PerClassMetrics.append(classification_report(yData, yPredict, target_names=target_names, digits=2, output_dict=True))
if (FI == 1): #if (FI == 1):
X = subset.values # X = subset.values
Y = array(yData) # Y = array(yData)
FeatureImp.append(class_feature_importance(X, Y, grid.best_estimator_.feature_importances_)) # FeatureImp.append(class_feature_importance(X, Y, grid.best_estimator_.feature_importances_))
# rfe = RFE(grid.best_estimator_, 3)
FeatureImpPandas = pd.DataFrame(FeatureImp) # fit = rfe.fit(subset, yData)
# RFEList.append(fit.ranking_)
bestfeatures = SelectKBest(score_func=chi2, k='all')
fit = bestfeatures.fit(subset,yData)
dfscores = pd.DataFrame(fit.scores_)
dfcolumns = pd.DataFrame(subset.columns)
#concat two dataframes for better visualization
featureScores = pd.concat([dfcolumns,dfscores],axis=1)
featureScores.columns = ['Specs','Score'] #naming the dataframe columns
#FeatureImpPandas = pd.DataFrame(FeatureImp)
#RFEListPD = pd.DataFrame(RFEList)
#perm_imp_rfpimp = pd.DataFrame(perm_imp_rfpimp)
perm_imp_eli5PD = pd.DataFrame(permList)
PerClassMetricsPandas = pd.DataFrame(PerClassMetrics) PerClassMetricsPandas = pd.DataFrame(PerClassMetrics)
PerFeatureAccuracyPandas = pd.DataFrame(PerFeatureAccuracy) PerFeatureAccuracyPandas = pd.DataFrame(PerFeatureAccuracy)
return df_cv_results_classifiers, parameters, FeatureImpPandas, PerClassMetricsPandas, PerFeatureAccuracyPandas return df_cv_results_classifiers, parameters, PerClassMetricsPandas, PerFeatureAccuracyPandas, perm_imp_eli5PD, featureScores
#def r2(rf, X_train, y_train):
# return r2_score(y_train, rf.predict(X_train))
def class_feature_importance(X, Y, feature_importances): def class_feature_importance(X, Y, feature_importances):
N, M = X.shape N, M = X.shape
@ -363,21 +398,33 @@ def Preprocessing():
global resultsList global resultsList
df_cv_results_classifiersList = [] df_cv_results_classifiersList = []
parametersList = [] parametersList = []
FeatureImportanceList = [] #FeatureImportanceList = []
PerClassMetricsList = [] PerClassMetricsList = []
FeatureAccuracyList = [] FeatureAccuracyList = []
#RFEListPD = []
#perm_imp_rfpimp = []
perm_imp_eli5PD = []
featureScores = []
for j, result in enumerate(resultsList): for j, result in enumerate(resultsList):
df_cv_results_classifiersList.append(resultsList[j][0]) df_cv_results_classifiersList.append(resultsList[j][0])
parametersList.append(resultsList[j][1]) parametersList.append(resultsList[j][1])
FeatureImportanceList.append(resultsList[j][2]) #FeatureImportanceList.append(resultsList[j][2])
PerClassMetricsList.append(resultsList[j][3]) PerClassMetricsList.append(resultsList[j][2])
FeatureAccuracyList.append(resultsList[j][4]) FeatureAccuracyList.append(resultsList[j][3])
#RFEListPD.append(resultsList[j][5])
#perm_imp_rfpimp.append(resultsList[j][6])
perm_imp_eli5PD.append(resultsList[j][4])
featureScores.append(resultsList[j][5])
df_cv_results_classifiers = pd.concat(df_cv_results_classifiersList, ignore_index=True, sort=False) df_cv_results_classifiers = pd.concat(df_cv_results_classifiersList, ignore_index=True, sort=False)
parameters = pd.concat(parametersList, ignore_index=True, sort=False) parameters = pd.concat(parametersList, ignore_index=True, sort=False)
FeatureImportance = pd.concat(FeatureImportanceList, ignore_index=True, sort=False) #FeatureImportanceListPD = pd.concat(FeatureImportanceList, ignore_index=True, sort=False)
PerClassMetrics = pd.concat(PerClassMetricsList, ignore_index=True, sort=False) PerClassMetrics = pd.concat(PerClassMetricsList, ignore_index=True, sort=False)
FeatureAccuracy = pd.concat(FeatureAccuracyList, ignore_index=True, sort=False) FeatureAccuracy = pd.concat(FeatureAccuracyList, ignore_index=True, sort=False)
#RFEListPDCon = pd.concat(RFEListPD, ignore_index=True, sort=False)
#perm_imp_rfpimpCon = pd.concat(perm_imp_rfpimp, ignore_index=True, sort=False)
perm_imp_eli5PDCon = pd.concat(perm_imp_eli5PD, ignore_index=True, sort=False)
featureScoresCon = pd.concat(featureScores, ignore_index=True, sort=False)
global factors global factors
factors = [1,1,1,1,1,1] factors = [1,1,1,1,1,1]
global scoring global scoring
@ -388,18 +435,23 @@ def Preprocessing():
del df_cv_results_classifiers_metrics['mean_fit_time'] del df_cv_results_classifiers_metrics['mean_fit_time']
del df_cv_results_classifiers_metrics['mean_score_time'] del df_cv_results_classifiers_metrics['mean_score_time']
df_cv_results_classifiers_metrics = df_cv_results_classifiers_metrics.ix[:, 0:NumberofscoringMetrics] df_cv_results_classifiers_metrics = df_cv_results_classifiers_metrics.ix[:, 0:NumberofscoringMetrics]
return [parameters,FeatureImportance,PerClassMetrics,FeatureAccuracy,df_cv_results_classifiers_metrics] return [parameters,PerClassMetrics,FeatureAccuracy,df_cv_results_classifiers_metrics,perm_imp_eli5PDCon,featureScoresCon]
def sumPerMetric(factors): def sumPerMetric(factors):
sumPerClassifier = [] sumPerClassifier = []
global df_cv_results_classifiers_metrics preProcessResults = []
for index, row in df_cv_results_classifiers_metrics.iterrows(): preProcessResults = Preprocessing()
loopThroughMetrics = preProcessResults[4]
for index, row in loopThroughMetrics.iterrows():
rowSum = 0 rowSum = 0
global scoring global scoring
lengthFactors = len(scoring) lengthFactors = len(scoring)
for loop,elements in enumerate(row): for loop,elements in enumerate(row):
lengthFactors = lengthFactors - 1 + factors[loop] lengthFactors = lengthFactors - 1 + factors[loop]
rowSum = elements*factors[loop] + rowSum rowSum = elements*factors[loop] + rowSum
if lengthFactors is 0:
sumPerClassifier = 0
else:
sumPerClassifier.append(rowSum/lengthFactors) sumPerClassifier.append(rowSum/lengthFactors)
return sumPerClassifier return sumPerClassifier
@ -413,6 +465,7 @@ def RetrieveFactors():
global ModelSpaceMDSNew global ModelSpaceMDSNew
global ModelSpaceTSNENew global ModelSpaceTSNENew
sumPerClassifierSel = [] sumPerClassifierSel = []
sumPerClassifierSel = sumPerMetric(FactorsInt['Factors'])
ModelSpaceMDSNew = [] ModelSpaceMDSNew = []
ModelSpaceTSNENew = [] ModelSpaceTSNENew = []
preProcessResults = [] preProcessResults = []
@ -423,13 +476,12 @@ def RetrieveFactors():
for l,el in enumerate(FactorsInt['Factors']): for l,el in enumerate(FactorsInt['Factors']):
if el is 0: if el is 0:
XClassifiers.drop(XClassifiers.columns[[l-countRemovals]], axis=1, inplace=True) XClassifiers.drop(XClassifiers.columns[[l-countRemovals]], axis=1, inplace=True)
counter = countRemovals + 1 countRemovals = countRemovals + 1
flagLocal = 1 flagLocal = 1
if flagLocal is 1: if flagLocal is 1:
ModelSpaceMDSNew = FunMDS(XClassifiers) ModelSpaceMDSNew = FunMDS(XClassifiers)
ModelSpaceTSNENew = FunTsne(XClassifiers) ModelSpaceTSNENew = FunTsne(XClassifiers)
ModelSpaceTSNENew = ModelSpaceTSNENew.tolist() ModelSpaceTSNENew = ModelSpaceTSNENew.tolist()
sumPerClassifierSel = sumPerMetric(FactorsInt['Factors'])
return 'Everything Okay' return 'Everything Okay'
@app.route('/data/UpdateOverv', methods=["GET", "POST"]) @app.route('/data/UpdateOverv', methods=["GET", "POST"])
@ -470,26 +522,38 @@ def InitializeEnsemble():
def ReturnResults(sumPerClassifier,ModelSpaceMDS,ModelSpaceTSNE,preProcessResults,DataSpaceList,PredictionSpaceList): def ReturnResults(sumPerClassifier,ModelSpaceMDS,ModelSpaceTSNE,preProcessResults,DataSpaceList,PredictionSpaceList):
global Results global Results
Results = [] Results = []
FeatureImportance = preProcessResults[1] #FeatureImportanceListPD = preProcessResults[1]
PerClassMetrics = preProcessResults[2] PerClassMetrics = preProcessResults[1]
FeatureAccuracy = preProcessResults[3] FeatureAccuracy = preProcessResults[2]
FeatureImportance = FeatureImportance.to_json(orient='records') #RFEListPDCon = preProcessResults[5]
#perm_imp_rfpimpCon = preProcessResults[6]
perm_imp_eli5PDCon = preProcessResults[4]
featureScoresCon = preProcessResults[5]
#FeatureImportanceListPD = FeatureImportanceListPD.to_json(orient='records')
PerClassMetrics = PerClassMetrics.to_json(orient='records') PerClassMetrics = PerClassMetrics.to_json(orient='records')
FeatureAccuracy = FeatureAccuracy.to_json(orient='records') FeatureAccuracy = FeatureAccuracy.to_json(orient='records')
#RFEListPDCon = RFEListPDCon.to_json(orient='records')
#perm_imp_rfpimpCon = perm_imp_rfpimpCon.to_json(orient='records')
perm_imp_eli5PDCon = perm_imp_eli5PDCon.to_json(orient='records')
featureScoresCon = featureScoresCon.to_json(orient='records')
XDataJSON = XData.columns.tolist() XDataJSON = XData.columns.tolist()
Results.append(json.dumps(sumPerClassifier)) # Position: 0 Results.append(json.dumps(sumPerClassifier)) # Position: 0
Results.append(json.dumps(ModelSpaceMDS)) # Position: 1 Results.append(json.dumps(ModelSpaceMDS)) # Position: 1
Results.append(json.dumps(classifiersIDPlusParams)) # Position: 2 Results.append(json.dumps(classifiersIDPlusParams)) # Position: 2
Results.append(FeatureImportance) # Position: 3 #Results.append(FeatureImportanceListPD) # Position: 3
Results.append(PerClassMetrics) # Position: 4 Results.append(PerClassMetrics) # Position: 3
Results.append(json.dumps(target_names)) # Position: 5 Results.append(json.dumps(target_names)) # Position: 4
Results.append(FeatureAccuracy) # Position: 6 Results.append(FeatureAccuracy) # Position: 5
Results.append(json.dumps(XDataJSON)) # Position: 7 Results.append(json.dumps(XDataJSON)) # Position: 6
Results.append(json.dumps(classifiersId)) # Position: 8 Results.append(json.dumps(classifiersId)) # Position: 7
Results.append(json.dumps(classifiersIDwithFI)) # Position: 9 Results.append(json.dumps(classifiersIDwithFI)) # Position: 8
Results.append(json.dumps(DataSpaceList)) # Position: 10 Results.append(json.dumps(DataSpaceList)) # Position: 9
Results.append(json.dumps(PredictionSpaceList)) # Position: 11 Results.append(json.dumps(PredictionSpaceList)) # Position: 10
Results.append(json.dumps(ModelSpaceTSNE)) # Position: 12 Results.append(json.dumps(ModelSpaceTSNE)) # Position: 11
#Results.append(RFEListPDCon) # Position: 13
#Results.append(perm_imp_rfpimpCon) # Position: 14
Results.append(perm_imp_eli5PDCon) # Position: 12
Results.append(featureScoresCon) # Position: 13
return Results return Results
# Retrieve data from client # Retrieve data from client
@ -507,45 +571,30 @@ def RetrieveSelClassifiersID():
@app.route('/data/FeaturesSelection', methods=["GET", "POST"]) @app.route('/data/FeaturesSelection', methods=["GET", "POST"])
def FeatureSelPerModel(): def FeatureSelPerModel():
global featureSelection global featureSelection
global loopFeatures
global ClassifierIDsList global ClassifierIDsList
RetrieveModelsPar = request.get_data().decode('utf8').replace("'", '"')
RetrieveModelsPar = json.loads(RetrieveModelsPar)
RetrieveModelsParRed = []
print(RetrieveModelsPar['brushedAll']) # FIX THIS THING!!!!!
#for j, i in enumerate(RetrieveModelsPar['brushedAll']):
# print(j)
#RetrieveModelsParRed = [for j, i in enumerate(RetrieveModelsPar['brushedAll']) if j not in ClassifierIDsList]
#RetrieveModelsParPandas = pd.DataFrame(RetrieveModelsParRed)
RetrieveModelsParPandas = pd.DataFrame(RetrieveModelsPar)
RetrieveModelsParPandas = RetrieveModelsParPandas.drop(columns=['performance'])
RetrieveModelsParPandas = RetrieveModelsParPandas.to_dict(orient='list')
print(RetrieveModelsParPandas)
RetrieveModels = {}
for key, value in RetrieveModelsParPandas.items():
withoutDuplicates = Remove(value)
RetrieveModels[key] = withoutDuplicates
global RetrieveModelsListNew
RetrieveModelsListNew.append(RetrieveModels)
loopFeatures = 2
featureSelection = request.get_data().decode('utf8').replace("'", '"') featureSelection = request.get_data().decode('utf8').replace("'", '"')
featureSelection = json.loads(featureSelection) featureSelection = json.loads(featureSelection)
global detailsParams
global algorithmList global algorithmList
results = [] results = []
global resultsList
resultsList = []
global loopFeatures
loopFeatures = 2
for index, eachalgor in enumerate(algorithmList): for index, eachalgor in enumerate(algorithmList):
if (eachalgor == 'KNN'): if (eachalgor == 'KNN'):
clf = KNeighborsClassifier() clf = KNeighborsClassifier()
params = RetrieveModelsListNew[index] params = detailsParams[index]
IF = 0 results.append(GridSearch(clf, params))
results.append(GridSearch(clf, params, IF))
resultsList.append(results[0]) resultsList.append(results[0])
else: else:
clf = RandomForestClassifier() clf = RandomForestClassifier()
params = RetrieveModelsListNew[index] params = detailsParams[index]
IF = 1 results.append(GridSearch(clf, params))
results.append(GridSearch(clf, params, IF))
resultsList.append(results[0]) resultsList.append(results[0])
if (featureSelection['featureSelection'] == ''):
key = 0
else:
key = 2 key = 2
EnsembleModel(ClassifierIDsList, key) EnsembleModel(ClassifierIDsList, key)
return 'Everything Okay' return 'Everything Okay'
@ -570,6 +619,7 @@ def EnsembleModel (ClassifierIDsList, keyRetrieved):
global columns global columns
global all_classifiers global all_classifiers
global algorithmList
if (keyRetrieved == 0): if (keyRetrieved == 0):
columnsInit = [] columnsInit = []
@ -684,11 +734,11 @@ def RetrieveModel():
else: else:
clf = RandomForestClassifier() clf = RandomForestClassifier()
params = {'n_estimators': list(range(80, 120)), 'criterion': ['gini', 'entropy']} params = {'n_estimators': list(range(80, 120)), 'criterion': ['gini', 'entropy']}
GridSearchForParameters(clf, params) GridSearchForParameters(clf, params, eachAlgor)
SendEachClassifiersPerformanceToVisualize() SendEachClassifiersPerformanceToVisualize()
return 'Everything Okay' return 'Everything Okay'
def GridSearchForParameters(clf, params): def GridSearchForParameters(clf, params, eachAlgor):
grid = GridSearchCV(estimator=clf, grid = GridSearchCV(estimator=clf,
param_grid=params, param_grid=params,
scoring='accuracy', scoring='accuracy',
@ -753,28 +803,31 @@ def RetrieveModelsParam():
global classifierID global classifierID
global algorithmList global algorithmList
global detailsParams
results = [] results = []
algorithmList.append(algorithm) algorithmList.append(algorithm)
if (algorithm == 'KNN'): if (algorithm == 'KNN'):
clf = KNeighborsClassifier() clf = KNeighborsClassifier()
params = RetrieveModels params = RetrieveModels
IF = 0 detailsParams.append(params)
results.append(GridSearch(clf, params, IF)) results.append(GridSearch(clf, params))
resultsList.append(results[0]) resultsList.append(results[0])
for j, oneClassifier in enumerate(results[0][1]): for j, oneClassifier in enumerate(results[0][1]):
classifiersId.append(classifierID) classifiersId.append(classifierID)
classifiersIDPlusParams.append(classifierID) classifiersIDPlusParams.append(classifierID)
classifierID = classifierID + 1 classifierID = classifierID + 1
else: elif (algorithm == 'RF'):
clf = RandomForestClassifier() clf = RandomForestClassifier()
params = RetrieveModels params = RetrieveModels
IF = 1 detailsParams.append(params)
results.append(GridSearch(clf, params, IF)) results.append(GridSearch(clf, params))
resultsList.append(results[0]) resultsList.append(results[0])
for oneClassifier, j in enumerate(results[0][1]): for oneClassifier, j in enumerate(results[0][1]):
classifiersIDPlusParams.append(classifierID) classifiersIDPlusParams.append(classifierID)
classifiersIDwithFI.append(classifierID) classifiersIDwithFI.append(classifierID)
classifierID = classifierID + 1 classifierID = classifierID + 1
else:
pass
return 'Everything Okay' return 'Everything Okay'
Loading…
Cancel
Save