Kaynağa Gözat

Merge branch 'develop' of jmacura/polirural-attractiveness-clustering into master

jmacura 5 yıl önce
ebeveyn
işleme
351c604f96

+ 27 - 6
.eslintrc.json

@@ -1,11 +1,32 @@
 {
-  "extends": "standard",
+  "env": {
+    "browser": true,
+    "es6": true
+  },
+  "extends": ["openlayers", "angular"],
   "globals": {
     "angular": "readonly"
   },
   "rules": {
-    "semi": ["error", "always"],
-    "no-var": "error",
-    "prefer-const": "error"
-  }
-}
+    "angular/no-service-method": [
+      "warn"
+    ],
+    "angular/typecheck-array": "off",
+    "angular/typecheck-date": "off",
+    "angular/typecheck-function": "off",
+    "angular/typecheck-number": "off",
+    "angular/typecheck-object": "off",
+    "angular/typecheck-string": "off"
+  },
+  "overrides": [
+    {
+      "files": [
+        "**/*.spec.js"
+      ],
+      "env": {
+        "jasmine": true,
+        "angular/mocks": true
+      }
+    }
+  ]
+}

Dosya farkı çok büyük olduğundan ihmal edildi
+ 453 - 198
package-lock.json


+ 11 - 9
package.json

@@ -1,7 +1,7 @@
 {
-  "name": "polirural-attractiveness",
+  "name": "polirural-attractiveness-clustering",
   "version": "0.1.0",
-  "description": "Rural attractiveness aplication",
+  "description": "Rural attractiveness clustering application",
   "main": "build/index.html",
   "scripts": {
     "test": "echo \"Error: no test specified\" && exit 1",
@@ -25,23 +25,25 @@
   "license": "MIT",
   "dependencies": {
     "csvtojson": "^2.0.10",
-    "hslayers-ng": "^1.20.2",
+    "hslayers-ng": "^1.23.0",
+    "hsv2rgb": "^1.1.0",
     "http-server": "^0.12.3"
   },
   "devDependencies": {
-    "@babel/core": "^7.9.6",
+    "@babel/core": "^7.10.2",
     "@babel/plugin-syntax-dynamic-import": "^7.8.3",
     "babel-loader": "^8.1.0",
     "babel-plugin-angularjs-annotate": "^0.10.0",
     "clean-webpack-plugin": "^3.0.0",
     "css-loader": "^3.5.3",
-    "eslint": "^7.0.0",
-    "eslint-config-standard": "^14.1.1",
+    "eslint": "^7.1.0",
+    "eslint-config-angular": "^0.5.0",
+    "eslint-config-openlayers": "^14.0.0",
+    "eslint-plugin-angular": "^4.0.1",
     "eslint-plugin-import": "^2.20.2",
     "eslint-plugin-node": "^11.1.0",
     "eslint-plugin-promise": "^4.2.1",
-    "eslint-plugin-standard": "^4.0.1",
-    "extract-loader": "^5.0.1",
+    "extract-loader": "^5.1.0",
     "file-loader": "^6.0.0",
     "html-loader": "^1.1.0",
     "html-webpack-plugin": "^4.3.0",
@@ -49,7 +51,7 @@
     "ng-cache-loader": "0.0.26",
     "npm-run-all": "^4.1.5",
     "optimize-css-assets-webpack-plugin": "^5.0.3",
-    "postcss": "^7.0.30",
+    "postcss": "^7.0.32",
     "postcss-prefix-selector": "^1.7.1",
     "style-loader": "^1.2.1",
     "url-loader": "^4.1.0",

+ 4 - 4
src/adjuster/adjuster-sidebar-btn.directive.html

@@ -1,5 +1,5 @@
-<a href="#" class="sidebar-item list-group-item" ng-if="Core.exists('pra.adjuster')" ng-click="setMainPanel('adjuster')"
-  title="{{'Adjust factors'|translate}}" ng-class="{active: Core.mainpanel == 'adjuster'}">
-  <span class="menu-icon icon-alertpay"></span>
-  <span class="sidebar-item-title" translate>Adjust factors</span>
+<a href="#" class="flex-fill hs-sidebar-item list-group-item hs-panel-hidden" ng-if="HsCore.exists('pra.adjuster')" ng-click="setMainPanel('adjuster')"
+  title="{{'Adjust factors'|translate}}" ng-class="{active: HsCore.mainpanel == 'adjuster'}">
+  <i class="menu-icon icon-analytics-piechart" data-toggle="tooltip" data-container="body" data-placement="auto"></i>
+  <span class="hs-sidebar-item-title" translate>Adjust factors</span>
 </a>

+ 16 - 11
src/adjuster/adjuster.component.js

@@ -1,16 +1,21 @@
 export default {
   template: require('./adjuster.directive.html'),
-  controller: ['$scope', 'hs.map.service', 'Core', 'config', 'pra.adjuster.service', 'hs.utils.service',
-    function ($scope, OlMap, Core, config, adjusterService, utils) {
-      $scope.loading = false;
-      $scope.utils = utils;
+  controller: function (
+    $scope,
+    HsCore,
+    HsConfig,
+    PraAdjusterService,
+    HsUtilsService
+  ) {
+    'ngInject';
+    $scope.loading = false;
+    $scope.HsUtilsService = HsUtilsService;
 
-      angular.extend($scope, {
-        Core,
-        adjusterService
-      });
+    angular.extend($scope, {
+      HsCore,
+      PraAdjusterService,
+    });
 
-      $scope.$emit('scope_loaded', 'adjuster');
-    }
-  ]
+    $scope.$emit('scope_loaded', 'adjuster');
+  },
 };

+ 6 - 5
src/adjuster/adjuster.directive.html

@@ -11,22 +11,23 @@
     }
   </style>
   <div class="card-body">
+    <button type="button" class="btn btn-primary" ng-click="PraAdjusterService.apply()" ng-disabled="PraAdjusterService.isClusteringInProcess()">Calculate clusters</button>
     <div class="card-body">
-      <div ng-repeat="factor in adjusterService.factors">
+      <div ng-repeat="factor in PraAdjusterService.factors">
         <div class="d-flex flex-row">
           <div class="p-2 flex-grow-1">
-            <label>{{factor.factor}}</label>
+            <label>{{factor.name}}</label>
           </div>
           <div class="p-2">{{(factor.weight * 100).toFixed(0)}}&nbsp;%</div>
         </div>
-        <input type="range" class="custom-range" ng-change="adjusterService.apply()" ng-model="factor.weight" min="0"
+        <input type="range" class="custom-range" ng-model="factor.weight" min="0"
           max="1.0" step="0.05">
-        <span class="glyphicon" ng-class="datasetlistVisible ? 'icon-chevron-down' : 'icon-chevron-right'"
+        <span class="glyphicon" ng-class="datasetlistVisible ? 'icon-chevron-left' : 'icon-chevron-right'"
           ng-click="datasetlistVisible = !datasetlistVisible"></span>
         <div ng-init="datasetlistVisible = false" ng-show="datasetlistVisible">
           <div ng-repeat="dataset in factor.datasets">
             <button type="button" class="btn btn-sm btn-light hs-lm-item-visibility"
-              ng-click="dataset.included = !dataset.included;adjusterService.apply();$event.stopPropagation()"
+              ng-click="dataset.included = !dataset.included;$event.stopPropagation()"
               ng-class="dataset.included ? 'hs-checkmark' : 'hs-uncheckmark'"></button>
             <label>{{dataset.name}}</label>
           </div>

+ 7 - 6
src/adjuster/adjuster.module.js

@@ -1,13 +1,14 @@
-import adjusterComponent from './adjuster.component';
-import adjusterService from './adjuster.service';
+import adjusterComponent from './adjuster.component.js';
+import {AdjusterService} from './adjuster.service.js';
 
-angular.module('pra.adjuster', ['hs.core', 'hs.map'])
-  .directive('pra.adjuster.sidebarBtn', function () {
+angular
+  .module('pra.adjuster', ['hs.core', 'hs.map'])
+  .directive('praAdjusterSidebarBtn', function () {
     return {
-      template: require('./adjuster-sidebar-btn.directive.html')
+      template: require('./adjuster-sidebar-btn.directive.html'),
     };
   })
 
-  .service('pra.adjuster.service', adjusterService)
+  .service('PraAdjusterService', AdjusterService)
 
   .component('pra.adjuster', adjusterComponent);

+ 103 - 93
src/adjuster/adjuster.service.js

@@ -1,101 +1,111 @@
 // import attractivity from '../Attractivity.json';
-import nuts from '../nuts';
+import nuts from '../nuts.js';
+import {factors} from './factors.js';
 
-export default ['Core', 'hs.utils.service', '$rootScope', '$http',
-  function (Core, utils, $rootScope, $http) {
-    const me = {
-      factors: [
-        {
-          name: 'Natural',
-          column: 'N_index',
-          weight: 1
-        },
-        {
-          name: 'Social & Human',
-          column: 'S_index',
-          weight: 1
-        },
-        {
-          name: 'Anthropic',
-          column: 'A_index',
-          weight: 1
-        },
-        {
-          name: 'Economical',
-          column: 'E_index',
-          weight: 1
-        },
-        {
-          name: 'Cultural',
-          column: 'C_index',
-          weight: 1
-        },
-        {
-          name: 'Institutional',
-          column: 'I_index',
-          weight: 1
-        }
-      ],
-      apply () {
-        utils.debounce(function () {
-          $http({
-            method: 'post',
-            url: 'https://publish.lesprojekt.cz/nodejs/scores',
-            data: {
-              factors: me.factors.map(f => {
-                return {
-                  factor: f.factor,
-                  weight: f.weight,
-                  datasets: f.datasets.filter(ds => ds.included).map(ds => ds.name)
-                };
-              })
-            }
-          })
-            .then(response => {
-              me.attractivity = response.data;
-              let max = 0;
-              me.attractivity.forEach(a => {
-                if (a.aggregate > max) max = a.aggregate;
-              });
-              const normalizer = 1 / max;
-              me.attractivity.forEach(a => {
-                a.aggregate *= normalizer;
-              });
-              me.attractivity.forEach(a => {
-                me.nutsCodeRecordRelations[a.code] = a;
-              });
-              nuts.nuts3Source.forEachFeature(feature => {
-                feature.set('total', me.nutsCodeRecordRelations[feature.get('NUTS_ID')].aggregate);
-                feature.set('totalForHumans', (me.nutsCodeRecordRelations[feature.get('NUTS_ID')].aggregate * 100).toFixed(2));
-                me.factors.forEach(factor => {
-                  feature.set(factor.factor, (me.nutsCodeRecordRelations[feature.get('NUTS_ID')][factor.factor] * 100).toFixed(2));
-                });
-              });
-            });
-          /*
+export class AdjusterService {
+  constructor(HsCore, HsUtilsService, $rootScope, $http, $location) {
+    'ngInject';
+    this.HsCore = HsCore;
+    this.HsUtilsService = HsUtilsService;
+    this.$rootScope = $rootScope;
+    this.$http = $http;
+    this.serviceBaseUrl =
+      $location.host() === 'localhost'
+        ? 'https://jmacura.ml/ws/'
+        : 'https://publish.lesprojekt.cz/nodejs/';
+    this.factors = factors;
+    this.clusters = [];
+    this._clusteringInProcess = true;
+    this.init();
+  }
 
-            */ }, 300)();
-      }
+  /**
+   * Sends a request to polirural-attractiveness-service
+   * and applies the returned values
+   */
+  apply() {
+    const f = () => {
+      this._clusteringInProcess = true;
+      this.$http({
+        method: 'get',
+        url: this.serviceBaseUrl + 'clusters',
+        /*data: {
+          factors: this.factors.map((f) => {
+            return {
+              factor: f.factor,
+              weight: f.weight,
+              datasets: f.datasets
+                .filter((ds) => ds.included)
+                .map((ds) => ds.name),
+            };
+          }),
+        },*/
+      }).then((response) => {
+        const clusterData = response.data.response;
+        /*let max = 0;
+        this.clusters.forEach((a) => {
+          if (a.aggregate > max) {
+            max = a.aggregate;
+          }
+        });
+        const normalizer = 1 / max;
+        this.attractivity.forEach((a) => {
+          a.aggregate *= normalizer;
+        });
+        this.attractivity.forEach((a) => {
+          this.nutsCodeRecordRelations[a.code] = a;
+        });*/
+        nuts.nuts3Source.forEachFeature((feature) => {
+          // Pair each feature with its clustering data
+          const featureData = clusterData.find(
+            (item) => item['nuts_id'] === feature.get('NUTS_ID')
+          );
+          Object.keys(featureData).forEach(function (key, index) {
+            if (key !== 'nuts_id') {
+              feature.set(key, featureData[key]);
+            }
+          });
+        });
+        const clusters = [];
+        for (const region of clusterData) {
+          if (!clusters.includes(region['km25.cluster'])) {
+            clusters.push(region['km25.cluster']);
+          }
+        }
+        this.clusters = clusters;
+        this._clusteringInProcess = false;
+        this.$rootScope.$broadcast('clusters_loaded');
+      });
     };
-    me.nutsCodeRecordRelations = {};
+    this.HsUtilsService.debounce(f, 300)();
+  }
 
-    $http({ url: 'https://publish.lesprojekt.cz/nodejs/datasets' })
-      .then(response => {
-        me.factors = response.data.map(dataset => { return { factor: dataset.Factor, weight: 1, datasets: [] }; });
-        me.factors = utils.removeDuplicates(me.factors, 'factor');
-        me.factors.forEach(factor => {
-          factor.datasets = response.data
-            .filter(ds => ds.Factor === factor.factor)
-            .map(ds => {
-              return {
-                name: ds.Name,
-                included: true
-              };
-            });
-        });
-        me.apply();
+  init() {
+    this.$http({
+      url: this.serviceBaseUrl + 'datasets',
+    }).then((response) => {
+      this.factors = response.data.map((dataset) => {
+        return {name: dataset.Factor, weight: 1, datasets: []};
+      });
+      this.factors = this.HsUtilsService.removeDuplicates(this.factors, 'name');
+      this.factors.forEach((factor) => {
+        factor.datasets = response.data
+          .filter((ds) => ds.Factor === factor.name)
+          .map((ds) => {
+            return {
+              name: ds.Name,
+              included: true,
+            };
+          });
       });
+      this.apply();
+    });
+  }
 
-    return me;
+  /**
+   * @returns {boolean} true if clustering is in process, false otherwise
+   */
+  isClusteringInProcess() {
+    return this._clusteringInProcess;
   }
-];
+}

+ 32 - 0
src/adjuster/factors.js

@@ -0,0 +1,32 @@
+export const factors = [
+  {
+    name: 'Natural',
+    column: 'N_index',
+    weight: 1,
+  },
+  {
+    name: 'Social & Human',
+    column: 'S_index',
+    weight: 1,
+  },
+  {
+    name: 'Anthropic',
+    column: 'A_index',
+    weight: 1,
+  },
+  {
+    name: 'Economical',
+    column: 'E_index',
+    weight: 1,
+  },
+  {
+    name: 'Cultural',
+    column: 'C_index',
+    weight: 1,
+  },
+  {
+    name: 'Institutional',
+    column: 'I_index',
+    weight: 1,
+  },
+];

+ 176 - 131
src/app.js

@@ -1,90 +1,81 @@
 'use strict';
-import 'toolbar.module';
-import 'print.module';
-import 'query.module';
-import 'search.module';
-import 'add-layers.module';
-import 'measure.module';
-import 'permalink.module';
-import 'info.module';
-import 'datasource-selector.module';
-import 'sidebar.module';
-import 'draw.module';
-import View from 'ol/View';
-import { Tile } from 'ol/layer';
-import { OSM } from 'ol/source';
-import { Style, Stroke, Fill } from 'ol/style';
+//import angular from 'angular';
+import 'hslayers-ng/components/add-layers/add-layers.module';
+import 'hslayers-ng/components/datasource-selector/datasource-selector.module';
+import 'hslayers-ng/components/draw/draw.module';
+import 'hslayers-ng/components/info/info.module';
+import 'hslayers-ng/components/measure/measure.module';
+import 'hslayers-ng/components/permalink/permalink.module';
+import 'hslayers-ng/components/print/print.module';
+import 'hslayers-ng/components/query/query.module';
+import 'hslayers-ng/components/search/search.module';
+import 'hslayers-ng/components/sidebar/sidebar.module';
+import 'hslayers-ng/components/toolbar/toolbar.module';
+// hslayers-ng components must be loaded first, otherwise angular will be undefined
+// eslint-disable-next-line sort-imports-es6-autofix/sort-imports-es6
+import './adjuster/adjuster.module.js';
 import VectorLayer from 'ol/layer/Vector';
-import './adjuster/adjuster.module';
-import nuts from './nuts';
-
-const module = angular.module('hs', [
-  'hs.sidebar',
-  'hs.draw',
-  'hs.info',
-  'hs.toolbar',
-  'hs.layermanager',
-  'hs.query',
-  'hs.search', 'hs.print', 'hs.permalink',
-  'hs.geolocation',
-  'hs.datasource_selector',
-  'hs.save-map',
-  'hs.measure',
-  'hs.addLayers',
-  'pra.adjuster'
-]);
+import View from 'ol/View';
+import hsv2rgb from 'hsv2rgb';
+import nuts from './nuts.js';
+import {Fill, Stroke, Style} from 'ol/style';
+import {OSM} from 'ol/source';
+import {Tile} from 'ol/layer';
 
-module.directive('hs', ['config', 'Core', function (config, Core) {
-  return {
-    template: Core.hslayersNgTemplate,
-    /* link: function (scope, element) {
-      Core.fullScreenMap(element);
-     } */
-  };
-}]);
+let randomColorPalette = [];
 
-function getHostname () {
+function getHostname() {
   const url = window.location.href;
   const urlArr = url.split('/');
   const domain = urlArr[2];
   return urlArr[0] + '//' + domain;
-};
+}
 
 const stroke = new Stroke({
   color: '#3399CC',
-  width: 0.25
+  width: 0.25,
 });
 
-function perc2color (perc) {
-  perc = perc * 100;
-  let r; let g; const b = 0;
-  if (perc < 50) {
-    r = 255;
-    g = Math.round(5.1 * perc);
-  } else {
-    g = 255;
-    r = Math.round(510 - 5.10 * perc);
+/**
+ * https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
+ * @param {number} colorCount Number of colors to randomly generate
+ * @returns {Array<Array<Number>>} Array of RGB colors
+ */
+function generateRandomColorPalette(colorCount) {
+  const palette = [];
+  const goldenRatioConjugate = 0.618033988749895;
+  for (let i = 0; i < colorCount; i++) {
+    let h = Math.random();
+    h += goldenRatioConjugate;
+    h %= 1;
+    h *= 360;
+    palette.push(hsv2rgb(h, 0.5, 0.95));
   }
   // eslint-disable-next-line no-unused-vars
   // const h = r * 0x10000 + g * 0x100 + b * 0x1;
-  return `rgba(${r}, ${g}, ${b}, 0.7)`;
+  return palette;
+  //return `rgba(${r}, ${g}, ${b}, 0.7)`;
 }
 
 const styles = function (feature) {
-  if (isNaN(feature.get('total'))) {
-    return [new Style({
-      fill: new Fill({
-        color: '#FFF'
+  if (isNaN(feature.get('km25.cluster'))) {
+    return [
+      new Style({
+        fill: new Fill({
+          color: '#FFF',
+        }),
+        stroke: stroke,
       }),
-      stroke: stroke
-    })];
+    ];
   } else {
-    return [new Style({
-      fill: new Fill({
-        color: perc2color(feature.get('total'))
+    return [
+      new Style({
+        fill: new Fill({
+          color: randomColorPalette[feature.get('km25.cluster')],
+        }),
+        //stroke: stroke,
       }),
-      stroke: stroke
-    })];
+    ];
   }
 };
 
@@ -92,84 +83,138 @@ const nuts2Layer = new VectorLayer({
   source: nuts.nuts2Source,
   visible: false,
   style: styles,
-  title: 'NUTS2 regions'
+  title: 'NUTS2 regions',
 });
 
 const nuts3Layer = new VectorLayer({
   source: nuts.nuts3Source,
   visible: true,
   style: styles,
-  title: 'NUTS3 regions'
+  title: 'NUTS3 regions',
 });
-nuts3Layer.set('hoveredKeys', ['NUTS_NAME', 'totalForHumans', 'Social & Human', 'Anthropic', 'Institutional', 'Economical', 'Natural', 'Cultural']);
-nuts3Layer.set('hoveredKeysTranslations', { NUTS_NAME: 'Name', totalForHumans: 'Calculated score' });
-
-module.value('config', {
-  proxyPrefix: '../8085/',
-  default_layers: [
-    new Tile({
-      source: new OSM(),
-      title: 'Open street map',
-      base: true,
-      editor: { editable: false },
-      removable: false
-    }),
-    nuts2Layer,
-    nuts3Layer
-  ],
-  project_name: 'erra/map',
-  default_view: new View({
-    center: [2433348.3022471312, 7744501.813885343],
-    zoom: 3.6,
-    units: 'm'
-  }),
-  advanced_form: true,
-  datasources: [],
-  hostname: {
-    default: {
-      title: 'Default',
-      type: 'default',
-      editable: false,
-      url: getHostname()
-    }
-  },
-  panelWidths: {
-  },
-  // allowAddExternalDatasets: false,
-  panelsEnabled: {
-    composition_browser: false,
-    legend: false,
-    draw: false,
-    info: false,
-    saveMap: false,
-    language: false
-  },
-  searchProvider: (q) => {
-    return `/app/jupyter-test/8085/search/?q=${q}`;
-  },
-  sizeMode: 'fullscreen'
+//TODO: update to new PopUp config & align with new attrs
+nuts3Layer.set('hoveredKeys', [
+  'NUTS_NAME',
+  'totalForHumans',
+  'Social & Human',
+  'Anthropic',
+  'Institutional',
+  'Economical',
+  'Natural',
+  'Cultural',
+]);
+nuts3Layer.set('hoveredKeysTranslations', {
+  NUTS_NAME: 'Name',
+  totalForHumans: 'Calculated score',
 });
 
-module.controller('Main', ['$scope', 'Core', '$compile', 'hs.layout.service', 'pra.adjuster.service',
-  function ($scope, Core, $compile, layoutService, adjusterService) {
-    $scope.Core = Core;
-    $scope.panelVisible = layoutService.panelVisible;
-    layoutService.sidebarRight = false;
-    // layoutService.sidebarToggleable = false;
-    // Core.singleDatasources = true;
-    layoutService.sidebarButtons = true;
-    layoutService.setDefaultPanel('adjuster');
+angular
+  .module('hs', [
+    'hs.addLayers',
+    'hs.datasource_selector',
+    'hs.draw',
+    'hs.geolocation',
+    'hs.info',
+    'hs.layermanager',
+    'hs.measure',
+    'hs.permalink',
+    'hs.print',
+    'hs.query',
+    'hs.save-map',
+    'hs.search',
+    'hs.sidebar',
+    'hs.toolbar',
+    'gettext',
+    'pra.adjuster',
+  ])
+  .directive('hs', function (HsConfig, HsCore) {
+    'ngInject';
+    return {
+      template: HsCore.hslayersNgTemplate,
+      /* link: function (scope, element) {
+        HsCore.fullScreenMap(element);
+      } */
+    };
+  })
+  .value('HsConfig', {
+    proxyPrefix: '../8085/',
+    default_layers: [
+      new Tile({
+        source: new OSM(),
+        title: 'OpenStreetMap',
+        base: true,
+        removable: false,
+      }),
+      nuts2Layer,
+      nuts3Layer,
+    ],
+    popUpDisplay: 'hover',
+    project_name: 'erra/map',
+    default_view: new View({
+      center: [2433348.3022471312, 7744501.813885343],
+      zoom: 3.6,
+      units: 'm',
+    }),
+    advanced_form: true,
+    datasources: [],
+    hostname: {
+      default: {
+        title: 'Default',
+        type: 'default',
+        editable: false,
+        url: getHostname(),
+      },
+    },
+    panelWidths: {},
+    // allowAddExternalDatasets: false,
+    panelsEnabled: {
+      composition_browser: false,
+      draw: false,
+      //info: false,
+      saveMap: false,
+      language: false,
+    },
+    /*searchProvider: (q) => {
+      return `/app/jupyter-test/8085/search/?q=${q}`;
+    },*/
+    sizeMode: 'fullscreen',
+  })
+  .controller('MainController', function (
+    $scope,
+    $compile,
+    gettext,
+    HsCore,
+    HsLayoutService,
+    HsSidebarService,
+    PraAdjusterService
+  ) {
+    'ngInject';
+    const vm = this;
+    vm.exists = HsCore.exists;
+    vm.panelVisible = HsLayoutService.panelVisible;
+    HsLayoutService.sidebarRight = false;
+    // HsLayoutService.sidebarToggleable = false;
+    // HsCore.singleDatasources = true;
+    HsLayoutService.sidebarButtons = true;
+    HsLayoutService.setDefaultPanel('adjuster');
     $scope.$on('scope_loaded', function (event, args) {
-      // eslint-disable-next-line eqeqeq
-      if (args == 'Sidebar') {
-        const el = angular.element('<pra.adjuster hs.draggable ng-if="Core.exists(\'pra.adjuster\')" ng-show="panelVisible(\'adjuster\', this)"></pra.adjuster>')[0];
-        layoutService.panelListElement.appendChild(el);
+      if (args === 'Sidebar') {
+        const el = angular.element(
+          '<pra.adjuster hs.draggable ng-if="vm.exists(\'pra.adjuster\')" ng-show="vm.panelVisible(\'adjuster\', this)"></pra.adjuster>'
+        )[0];
+        HsLayoutService.panelListElement.appendChild(el);
         $compile(el)($scope);
 
-        const toolbarButton = angular.element('<div pra.adjuster.sidebar-btn></div>')[0];
-        layoutService.sidebarListElement.appendChild(toolbarButton);
+        const toolbarButton = angular.element(
+          '<div pra-adjuster-sidebar-btn></div>'
+        )[0];
+        HsLayoutService.sidebarListElement.appendChild(toolbarButton);
         $compile(toolbarButton)(event.targetScope);
       }
     });
-  }
-]);
+    $scope.$on('clusters_loaded', function (event, args) {
+      randomColorPalette = generateRandomColorPalette(
+        PraAdjusterService.clusters.length
+      );
+    });
+  });

+ 6 - 4
src/datasource-list.js

@@ -15,20 +15,22 @@ export default [
     title: 'Layman',
     url: `${window.location.protocol}//${window.location.hostname}/layman`,
     user: 'browser',
-    type: 'layman'
+    type: 'layman',
   },
   {
     title: 'OTN Hub',
     url: 'http://opentnet.eu/php/metadata/csw/',
     language: 'eng',
     type: 'micka',
-    code_list_url: 'http://opentnet.eu/php/metadata/util/codelists.php?_dc=1440156028103&language=eng&page=1&start=0&limit=25&filter=%5B%7B%22property%22%3A%22label%22%7D%5D'
+    code_list_url:
+      'http://opentnet.eu/php/metadata/util/codelists.php?_dc=1440156028103&language=eng&page=1&start=0&limit=25&filter=%5B%7B%22property%22%3A%22label%22%7D%5D',
   },
   {
     title: 'SuperCAT',
     url: 'http://cat.ccss.cz/csw/',
     language: 'eng',
     type: 'micka',
-    code_list_url: 'http://www.whatstheplan.eu/php/metadata/util/codelists.php?_dc=1440156028103&language=eng&page=1&start=0&limit=25&filter=%5B%7B%22property%22%3A%22label%22%7D%5D'
-  }
+    code_list_url:
+      'http://www.whatstheplan.eu/php/metadata/util/codelists.php?_dc=1440156028103&language=eng&page=1&start=0&limit=25&filter=%5B%7B%22property%22%3A%22label%22%7D%5D',
+  },
 ];

+ 1 - 1
src/index.html

@@ -15,7 +15,7 @@
 </head>
 
 <body>
-  <div hs ng-app="hs" ng-controller="Main" style="height: 100vh;"></div>
+  <div hs ng-app="hs" ng-controller="MainController as vm" style="height: 100vh;"></div>
   <% for (var js in htmlWebpackPlugin.files.js) { %>
     <script type="application/javascript" src="<%= htmlWebpackPlugin.files.js[js] %>"></script>
   <% } %>

+ 5 - 5
src/nuts.js

@@ -1,14 +1,14 @@
-import { GeoJSON } from 'ol/format';
-import { Vector as VectorSource } from 'ol/source';
 import nuts2 from './NUTS_RG_20M_2016_3857_LEVL_2.json';
 import nuts3 from './NUTS_RG_20M_2016_3857_LEVL_3.json';
+import {GeoJSON} from 'ol/format';
+import {Vector as VectorSource} from 'ol/source';
 
 export default {
   nuts2Source: new VectorSource({
-    features: (new GeoJSON()).readFeatures(nuts2)
+    features: new GeoJSON().readFeatures(nuts2),
   }),
 
   nuts3Source: new VectorSource({
-    features: (new GeoJSON()).readFeatures(nuts3)
-  })
+    features: new GeoJSON().readFeatures(nuts3),
+  }),
 };

+ 9 - 8
src/proxy.js

@@ -1,14 +1,15 @@
-
 // Listen on a specific host via the HOST environment variable
 const host = process.env.HOST || '0.0.0.0';
 // Listen on a specific port via the PORT environment variable
 const port = process.env.PROXY_PORT || 8085;
 
 const corsProxy = require('cors-anywhere');
-corsProxy.createServer({
-  originWhitelist: [], // Allow all origins
-  // requireHeader: ['origin', 'x-requested-with'],
-  removeHeaders: ['cookie', 'cookie2']
-}).listen(port, host, function () {
-  console.log('Running CORS Anywhere on ' + host + ':' + port);
-});
+corsProxy
+  .createServer({
+    originWhitelist: [], // Allow all origins
+    // requireHeader: ['origin', 'x-requested-with'],
+    removeHeaders: ['cookie', 'cookie2'],
+  })
+  .listen(port, host, function () {
+    console.log('Running CORS Anywhere on ' + host + ':' + port);
+  });

+ 22 - 16
webpack.common.js

@@ -10,15 +10,18 @@
  *   `'ngInject';` or `@ngInject` in comments. See https://docs.angularjs.org/guide/di
  */
 const path = require('path');
-const { CleanWebpackPlugin } = require('clean-webpack-plugin');
+const {CleanWebpackPlugin} = require('clean-webpack-plugin');
 const HtmlWebpackPlugin = require('html-webpack-plugin');
-const hslPaths = require(path.join(__dirname, './node_modules/hslayers-ng/common_paths'));
+const hslPaths = require(path.join(
+  __dirname,
+  './node_modules/hslayers-ng/common_paths'
+));
 
 module.exports = {
-  entry: { main: './src/app.js' },
+  entry: {main: './src/app.js'},
   output: {
     // Path at which output assets will be served
-    publicPath: ''
+    publicPath: '',
   },
   // Just for build speed improvement
   resolve: {
@@ -26,8 +29,8 @@ module.exports = {
     modules: [
       path.join(__dirname),
       path.join(__dirname, './node_modules'),
-      path.resolve(path.join(__dirname, './node_modules', 'hslayers-ng'))
-    ].concat(hslPaths.paths)
+      path.resolve(path.join(__dirname, './node_modules', 'hslayers-ng')),
+    ].concat(hslPaths.paths),
   },
   plugins: [
     // Clean before build
@@ -37,9 +40,9 @@ module.exports = {
       filename: 'index.html',
       template: './src/index.html',
       // We manually inject css and js files in our template
-      inject: false
+      inject: false,
       // favicon: 'assets/img/favicon.ico'
-    })
+    }),
   ],
   module: {
     rules: [
@@ -48,18 +51,21 @@ module.exports = {
       // or commented with /**@ngInject */
       {
         test: /\.js$/,
-        exclude: /node_modules/,
+        exclude: /node_modules\/(?!(hslayers-ng)\/).*/,
         use: [
           {
             loader: 'babel-loader',
             options: {
               // Babel syntax dynamic import plugin allow babel to correctly parse js files
               // using webpack dynamic import expression (i.e import('angular').then(...))
-              plugins: ['angularjs-annotate', '@babel/plugin-syntax-dynamic-import']
-            }
-          }
-        ]
-      }
-    ]
-  }
+              plugins: [
+                'angularjs-annotate',
+                '@babel/plugin-syntax-dynamic-import',
+              ],
+            },
+          },
+        ],
+      },
+    ],
+  },
 };

+ 27 - 25
webpack.dev.js

@@ -17,47 +17,49 @@ module.exports = merge(common, {
   devtool: 'cheap-eval-source-map',
   watchOptions: {
     aggregateTimeout: 300,
-    poll: 1000
+    poll: 1000,
   },
   resolve: {
-    symlinks: true
+    symlinks: true,
   },
   optimization: {
     // see https://webpack.js.org/guides/build-performance#avoid-extra-optimization-steps
     removeAvailableModules: false,
     removeEmptyChunks: false,
     // In dev mode we simply want to get a big bundle containing all our js
-    splitChunks: false
+    splitChunks: false,
   },
   output: {
     // see https://webpack.js.org/guides/build-performance#output-without-path-info
     // Path where bundled files will be output
     path: path.resolve(__dirname, './static'),
     pathinfo: false,
-    filename: '[name].bundle.js'
+    filename: '[name].bundle.js',
   },
   devServer: {
     contentBase: path.resolve(__dirname, './static'),
     hot: false,
     host: '0.0.0.0',
-    port: env.HTTP_PORT || 8082
+    port: env.HTTP_PORT || 8080,
   },
   module: {
     rules: [
       // Load css files which will be injected in html page at startup <style>...</style>)
       {
         test: /\.css$/,
-        use: ['style-loader', 'css-loader']
+        use: ['style-loader', 'css-loader'],
       },
       {
         test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
-        use: [{
-          loader: 'file-loader',
-          options: {
-            name: '[name].[ext]',
-            outputPath: 'fonts/'
-          }
-        }]
+        use: [
+          {
+            loader: 'file-loader',
+            options: {
+              name: '[name].[ext]',
+              outputPath: 'fonts/',
+            },
+          },
+        ],
       },
       // Load angularJS partials HTML file as URL
       {
@@ -66,8 +68,8 @@ module.exports = merge(common, {
         use: [
           'ng-cache-loader?prefix=[dir]/[dir]',
           'extract-loader',
-          'html-loader'
-        ]
+          'html-loader',
+        ],
       },
       // Load images as URLs
       {
@@ -76,9 +78,9 @@ module.exports = merge(common, {
           loader: 'file-loader',
           options: {
             name: '[name].[ext]',
-            outputPath: 'images'
-          }
-        }
+            outputPath: 'images',
+          },
+        },
       },
       // Load locales files
       {
@@ -90,11 +92,11 @@ module.exports = merge(common, {
             loader: 'file-loader',
             options: {
               name: '[name].[ext]',
-              outputPath: 'locales'
-            }
-          }
-        ]
-      }
-    ]
-  }
+              outputPath: 'locales',
+            },
+          },
+        ],
+      },
+    ],
+  },
 });

+ 29 - 29
webpack.prod.js

@@ -29,19 +29,19 @@ module.exports = merge(common, {
     // Path where bundled files will be output
     path: path.resolve(__dirname, './build'),
     // Path at which output assets will be served
-    publicPath: ''
+    publicPath: '',
   },
   resolve: {
-    symlinks: true
+    symlinks: true,
   },
   plugins: [
     // Extract CSS into separated css files
     new MiniCssExtractPlugin({
       // Add a chunkhash to file name so it will not be cached by browsers when content changed
-      filename: '[name].[hash].bundle.css'
+      filename: '[name].[hash].bundle.css',
     }),
     // see https://webpack.js.org/guides/caching#module-identifiers
-    new webpack.HashedModuleIdsPlugin()
+    new webpack.HashedModuleIdsPlugin(),
   ],
   optimization: {
     // See https://webpack.js.org/guides/caching
@@ -52,9 +52,9 @@ module.exports = merge(common, {
         vendor: {
           name: 'vendors',
           test: /node_modules/,
-          chunks: 'initial'
-        }
-      }
+          chunks: 'initial',
+        },
+      },
     },
     minimizer: [
       // JS minifier/uglifier
@@ -62,15 +62,15 @@ module.exports = merge(common, {
         parallel: true,
         sourceMap: true,
         // Remove comments as well
-        terserOptions: { output: { comments: false } }
+        terserOptions: {output: {comments: false}},
       }),
       // CSS minifier
       new OptimizeCSSAssetsPlugin({
         cssProcessorPluginOptions: {
-          preset: ['default', { discardComments: { removeAll: true } }]
-        }
-      })
-    ]
+          preset: ['default', {discardComments: {removeAll: true}}],
+        },
+      }),
+    ],
   },
   module: {
     rules: [
@@ -81,23 +81,23 @@ module.exports = merge(common, {
           'style-loader',
           {
             loader: MiniCssExtractPlugin.loader,
-            options: { publicPath: '' }
+            options: {publicPath: ''},
           },
-          'css-loader'
-        ]
+          'css-loader',
+        ],
       },
       {
         test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
         use: {
-          loader: 'url-loader'
-        }
+          loader: 'url-loader',
+        },
       },
       // Load images as URLs
       {
         test: /\.(png|svg|jpg|gif)$/,
         use: {
-          loader: 'url-loader'
-        }
+          loader: 'url-loader',
+        },
       },
       // Load locales files
       {
@@ -109,10 +109,10 @@ module.exports = merge(common, {
             loader: 'file-loader',
             options: {
               name: '[name].[contenthash].[ext]',
-              outputPath: 'locales'
-            }
-          }
-        ]
+              outputPath: 'locales',
+            },
+          },
+        ],
       },
       // AngularJS templates are cached using cache template
       {
@@ -123,10 +123,10 @@ module.exports = merge(common, {
           'extract-loader',
           {
             loader: 'html-loader',
-            options: { minimize: true }
-          }
-        ]
-      }
-    ]
-  }
+            options: {minimize: true},
+          },
+        ],
+      },
+    ],
+  },
 });

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor