Преглед на файлове

Add merseyside map layer. Remove previous layer division per heatmap

Tatiana Inama преди 6 години
родител
ревизия
a4d426017e
променени са 2 файла, в които са добавени 83 реда и са изтрити 91 реда
  1. 13 3
      src/Heatmap.css
  2. 70 88
      src/Heatmap.tsx

+ 13 - 3
src/Heatmap.css

@@ -7,11 +7,21 @@
   border: 2px solid black;
 }
 
-#vom-heatmap-range {
-  background: rgb(0,0,255);
-  background: linear-gradient(to right, #ff0000 1%,#ffff00 25%,#28d328 50%,#00ffea 75%,#0000ff 100%);
+#vom-heatmap-range,
+#vom-heatmap-amount-range {
   height: 30px;
   display: flex;
   justify-content: space-between;
   font-weight: bold;
+  border: 2px solid black;
+}
+
+#vom-heatmap-range {
+  background: rgb(0,0,255);
+  background: linear-gradient(to right, #ff0000 1%,#ffff00 25%,#28d328 50%,#00ffea 75%,#0000ff 100%);
+}
+
+#vom-heatmap-amount-range {
+  background: rgb(0,0,0);
+  background: linear-gradient(to right, #000000 1%,#ffffff 100%);
 }

+ 70 - 88
src/Heatmap.tsx

@@ -1,9 +1,11 @@
 import React, { Component } from 'react';
-import { Path, PaperScope, Point, Size, Rectangle, Color, Layer } from 'paper';
-import { Container, CustomInput, FormGroup, Label, Row, Col } from 'reactstrap';
+import { Path, PaperScope, Point, Size, Rectangle, Color, Layer, Raster, PointText } from 'paper';
+import { Container, CustomInput, FormGroup, Row, Col } from 'reactstrap';
+import map from './merseyside-nobg-white.png';
+
 import './Heatmap.css';
 
-const X_SEGMENTS = 25;
+const X_SEGMENTS = 50;
 const Y_SEGMENTS = X_SEGMENTS * 1.25;
 const MAX = 200;
 const output_start = 0,
@@ -43,14 +45,9 @@ class Heatmap extends Component<HeatmapProps, HeatmapState> {
       data: [],
       canvas: undefined,
       grid: [],
+      mapLayer: undefined,
+      areaAmount: undefined,
       heatmapType: HeatmapType.Amount,
-      heatmapLayers: {
-        amount: undefined,
-        correctness: undefined,
-        friendliness: undefined,
-        pleasantness: undefined,
-        trustworthiness: undefined
-      }
     }
   }
 
@@ -99,87 +96,70 @@ class Heatmap extends Component<HeatmapProps, HeatmapState> {
           size: gridSectionSize,
         });
 
+        const area = new Path.Rectangle(rect);
+        const items = canvas.project.activeLayer.getItems({
+          overlapping: rect
+        })
+        
         grid[row][column] = {
-          area: new Path.Rectangle(rect),
-          items: canvas.project.activeLayer.getItems({
-            overlapping: rect
-          })
+          area,
+          items
         }
       }
     }
     return grid;
   }
 
-  heatmapByAmount = (grid: Grid) => {
-    if (this.state.heatmapLayers.amount === undefined) {
-      const newLayer = new Layer({ name: 'amount' });
-      grid.forEach(section => {
-        section.forEach(({ area, items }) => {
-          const newArea = area.clone();
-          newArea.fillColor = new Color(`rgb(${items.length}, ${items.length}, ${items.length})`)
-          newLayer.addChild(newArea);
-        })
-      });
-      this.setState({
-        heatmapLayers: {
-          ...this.state.heatmapLayers,
-          amount: newLayer
-        }
-      })
+  mkFillColor = (key: HeatmapType, items: paper.Item[]) => {
+    if (key === HeatmapType.Amount) {
+      return new Color(`rgb(${items.length}, ${items.length}, ${items.length})`);
     } else {
-      this.state.canvas!.project.layers.forEach(l => {
-        if (l.name === 'amount') {
-          l.visible = true;
-        } else {
-          l.visible = false
-        }
-      })
+      const total = items.reduce<number>((tot, item) => {
+        return item.data[key] ? tot + item.data[key] : tot;
+      }, 0);
+      return total !== 0 ? 
+        new Color({ hue: RANGE(total / items.length), saturation: 1, brightness: items.length/MAX}) : 
+        new Color('black')
     }
   }
 
-  heatmapBy = (key: 'correctness' | 'friendliness' | 'pleasantness' | 'trustworthiness', grid: Grid) => {    
-    if (this.state.heatmapLayers[key] === undefined) {
-      const newLayer = new Layer({ name: key });
-      grid.forEach(section => {
-        section.forEach(({area, items}) => {
-          const newArea = area.clone();
-          const total = items.reduce<number>((tot, item) => {
-            return item.data[key] ? tot + item.data[key] : tot;
-          }, 0);
-          if (total !== 0) {
-            newArea.fillColor = new Color({ hue: RANGE(total / items.length), saturation: 1, brightness: items.length/MAX})
-          } else {
-            newArea.fillColor = new Color('black')
-          }
-          newLayer.addChild(newArea);
-        })
-      });
-      this.setState({
-        heatmapLayers: {
-          ...this.state.heatmapLayers,
-          [key]: newLayer
-        }
+  changeHeatmapColor = (type: HeatmapType, grid: Grid) => {
+    grid.forEach(section => {
+      section.forEach(({ area, items }) => {
+        area.fillColor = this.mkFillColor(type, items);
       })
+    })
+    this.setState({
+      heatmapType: type
+    })
+  }
+
+  showMap = (canvas: paper.PaperScope) => {
+    if (this.state.mapLayer) {
+      this.state.mapLayer.bringToFront();
     } else {
-      this.state.canvas!.project.layers.forEach(l => {
-        if (l.name === key) {
-          l.visible = true;
-        } else {
-          l.visible = false;
-        }
-      })
+      const mapLayer = new Layer({ name: 'mapLayer' });
+      const raster = new Raster(map);
+      raster.onLoad = () => {
+        raster.position = canvas.view.center;
+        raster.size = canvas.view.viewSize;
+      }
+      mapLayer.addChild(raster);
+      mapLayer.bringToFront();
+      this.setState({ mapLayer });
     }
   }
 
-  changeHeatmapType = (type: HeatmapType) => {
-    this.setState({
-      heatmapType: type
+  mkAmountCounter = () => {
+    const counter = new PointText({
+      point: [0, 0],
+      content: '',
+      fillColor: 'white'
     });
-    if (type === HeatmapType.Amount) {
-      this.heatmapByAmount(this.state.grid)
-    } else {
-      this.heatmapBy(type, this.state.grid)
-    }
+  
+    this.setState({
+      areaAmount: counter
+    })
   }
 
   componentDidMount = () => {
@@ -188,7 +168,9 @@ class Heatmap extends Component<HeatmapProps, HeatmapState> {
     canvas.view.viewSize.height = canvas.view.size.width * 1.25;
     const data = this.drawMapData(this.props.data, canvas.view.size.width);
     const grid = this.mkGrid(canvas);
-    this.heatmapByAmount(grid);
+    this.mkAmountCounter();
+    this.changeHeatmapColor(HeatmapType.Amount, grid);
+    this.showMap(canvas);
     this.setState({
       data,
       canvas,
@@ -210,7 +192,12 @@ class Heatmap extends Component<HeatmapProps, HeatmapState> {
                   <div>4</div>
                   <div>5</div>
                 </div>
-              ) : null
+              ) : (
+                <div id="vom-heatmap-amount-range">
+                  <div>1</div>
+                  <div>200</div>
+                </div>
+              )
             }
             <canvas id="vom-heatmap-canvas"></canvas>
           </div>
@@ -224,31 +211,31 @@ class Heatmap extends Component<HeatmapProps, HeatmapState> {
                   label="by amount of responses"
                   value={HeatmapType.Amount}
                   checked={this.state.heatmapType === HeatmapType.Amount}
-                  onChange={ e => { this.changeHeatmapType(e.currentTarget.value as HeatmapType)}}
+                  onChange={ e => { this.changeHeatmapColor(e.currentTarget.value as HeatmapType, this.state.grid)}}
                 />
                 <CustomInput type="radio" id="heatmap-by-friendliness" name="by-friendliness"
                   label="by friendliness"
                   value={HeatmapType.Friendliness}
                   checked={this.state.heatmapType === HeatmapType.Friendliness}
-                  onChange={ e => { this.changeHeatmapType(e.currentTarget.value as HeatmapType)}}
+                  onChange={ e => { this.changeHeatmapColor(e.currentTarget.value as HeatmapType, this.state.grid)}}
                 />
                 <CustomInput type="radio" id="heatmap-by-correctness" name="by-correctness"
                   label="by correctness"
                   value={HeatmapType.Correctness}
                   checked={this.state.heatmapType === HeatmapType.Correctness}
-                  onChange={ e => { this.changeHeatmapType(e.currentTarget.value as HeatmapType)}}
+                  onChange={ e => { this.changeHeatmapColor(e.currentTarget.value as HeatmapType, this.state.grid)}}
                 />
                 <CustomInput type="radio" id="heatmap-by-pleasantness" name="by-pleasantness"
                   label="by pleasantness"
                   value={HeatmapType.Pleasantness}
                   checked={this.state.heatmapType === HeatmapType.Pleasantness}
-                  onChange={ e => { this.changeHeatmapType(e.currentTarget.value as HeatmapType)}}
+                  onChange={ e => { this.changeHeatmapColor(e.currentTarget.value as HeatmapType, this.state.grid)}}
                 />
                 <CustomInput type="radio" id="heatmap-by-trustworthiness" name="by-trustworthiness"
                   label="by trustworthiness"
                   value={HeatmapType.Trustworthiness}
                   checked={this.state.heatmapType === HeatmapType.Trustworthiness}
-                  onChange={ e => { this.changeHeatmapType(e.currentTarget.value as HeatmapType)}}
+                  onChange={ e => { this.changeHeatmapColor(e.currentTarget.value as HeatmapType, this.state.grid)}}
                 />
               </div>
             </FormGroup>
@@ -303,14 +290,9 @@ type HeatmapState = {
   data: HeatmapData[],
   canvas?: paper.PaperScope,
   grid: Grid,
+  mapLayer: paper.Layer | undefined,
+  areaAmount: paper.TextItem | undefined,
   heatmapType: HeatmapType,
-  heatmapLayers: {
-    amount: paper.Layer | undefined,
-    friendliness: paper.Layer | undefined,
-    correctness: paper.Layer | undefined,
-    pleasantness: paper.Layer | undefined,
-    trustworthiness: paper.Layer | undefined,
-  }
 }