Forráskód Böngészése

Create base heatmap page

Tatiana Inama 6 éve
szülő
commit
6e051496fe
6 módosított fájl, 9948 hozzáadás és 1 törlés
  1. 5 0
      package-lock.json
  2. 1 0
      package.json
  3. 2 1
      src/App.css
  4. 163 0
      src/Heatmap.tsx
  5. 7 0
      src/Router.tsx
  6. 9770 0
      src/results.json

+ 5 - 0
package-lock.json

@@ -6320,6 +6320,11 @@
       "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
       "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
     },
+    "heatmap.js": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/heatmap.js/-/heatmap.js-2.0.5.tgz",
+      "integrity": "sha1-Rm07hlE/XUkRKknSVwCrJzAUkVM="
+    },
     "hex-color-regex": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",

+ 1 - 0
package.json

@@ -18,6 +18,7 @@
     "@types/reactstrap": "^8.4.2",
     "axios": "^0.19.2",
     "bootstrap": "^4.4.1",
+    "heatmap.js": "^2.0.5",
     "js-file-download": "^0.4.12",
     "paper": "^0.12.4",
     "ramda": "^0.27.0",

+ 2 - 1
src/App.css

@@ -141,7 +141,8 @@ form button {
 }
 
 #magic-canvas,
-#vom-admin-canvas {
+#vom-admin-canvas,
+#vom-heatmap-canvas {
   width: 100%;
   background-color: #F2F2F2;
   background-image: url('merseyside-nobg-4_5-LIGHT.png');

+ 163 - 0
src/Heatmap.tsx

@@ -0,0 +1,163 @@
+import React, { Component } from 'react';
+import { Path, PaperScope, Point, Size, Rectangle, PointText, Color } from 'paper';
+
+const CANVAS_STYLE = {
+  width: '50%',
+  border: '2px solid black'
+};
+
+const X_SEGMENTS = 25;
+const Y_SEGMENTS = X_SEGMENTS * 1.25;
+
+type HeatmapData = {
+  id: [number, number],
+  shape: paper.Path,
+  correctness: number,
+  friendliness: number,
+  pleasantness: number,
+  trustworthiness: number
+}
+class Heatmap extends Component<HeatmapProps, HeatmapState> {
+  
+  constructor(props: HeatmapProps) {
+    super(props);
+
+    this.state = {
+      data: [],
+      canvas: undefined,
+      grid: []
+    }
+  }
+
+  drawShape = (path: string, scale: number, data: any) => {
+    const _path = new Path();
+    _path.importJSON(path);
+    _path.scale(scale, new Point(0, 0));
+    _path.data = data;
+    _path.strokeWidth = 0.5;
+    _path.selected = false;
+    return _path;
+  }
+
+  mkGrid = (canvas: paper.PaperScope) => {
+    const width = canvas.view.size.width,
+          height = canvas.view.size.height;
+    const size = new Size(width/X_SEGMENTS, height/Y_SEGMENTS);
+
+    const data = this.props.data.reduce<Array<HeatmapData>>((newData, result) => {
+      return [
+        ...newData,
+        ...result.canvas.map((shape, shapeId) => {
+          let data = {
+            id: [result.id, shapeId],
+            correctness: shape.form.correctness,
+            friendliness: shape.form.friendliness,
+            pleasantness: shape.form.pleasantness,
+            trustworthiness: shape.form.trustworthiness,
+            shape: {},
+          }
+          data.shape = this.drawShape(shape.path, width / result.canvasSize.width, data);
+          return data as HeatmapData;
+        })
+      ]
+    }, [])
+
+
+    let grid: Array<Array<paper.Path.Rectangle>> = [];
+    for(let row = 0; row < Y_SEGMENTS; row ++) {
+      grid[row] = [];
+      for(let column = 0; column < X_SEGMENTS; column ++) {
+        let rect = new Rectangle({
+          point: [column * size.width, row * size.height],
+          size: size,
+        });
+
+        let items = canvas.project.activeLayer.getItems({
+          overlapping: rect
+        })
+        new Path.Rectangle({
+          rectangle: rect,
+          fillColor: new Color(`rgb(${items.length}, ${items.length}, ${items.length})`)
+        })
+        new PointText({
+          point: rect.leftCenter,
+          content: items.length,
+          fillColor: items.length < 50 ? 'white' : 'black',
+          fontSize: 10
+        })
+        // grid[row][column] = new Path.Rectangle({
+        //   point: [column * size.width, row * size.height],
+        //   size: size,
+        // });
+      }
+    }
+    this.setState({ grid, data })
+  }
+
+
+
+  componentDidMount = () => {
+    const canvas = new PaperScope();
+    canvas.setup('vom-heatmap-canvas');
+    canvas.view.viewSize.height = canvas.view.size.width * 1.25;
+    this.mkGrid(canvas);
+    this.setState({
+      canvas,
+    })
+  }
+
+  render = () => (
+    <div className="vom-heatmap" style={{display: 'flex', justifyContent: 'center'}}>
+      <canvas id="vom-heatmap-canvas" style={CANVAS_STYLE}></canvas>
+    </div>
+  )
+}
+
+type PersonalInformation = {
+  age: string,
+  gender: string,
+  genderCustom: string,
+  birthPlace: string,
+  currentPlace: string,
+  levelEducation: string[],
+  nonNative: string,
+}
+
+type FormPath = {
+  name: string,
+  soundExample: string,
+  associations: string[],
+  correctness: number,
+  friendliness: number,
+  pleasantness: number,
+  trustworthiness: number
+}
+
+type OriginalCanvasData = {
+  form: FormPath,
+  path: string,
+}
+
+type Result = {
+  personalInformation: PersonalInformation,
+  canvas: OriginalCanvasData[],
+  canvasSize: {
+    width: number,
+    height: number
+  },
+  email: string,
+  id: number,
+}
+
+type HeatmapProps = {
+  data: Result[],
+}
+
+type HeatmapState = {
+  data: HeatmapData[],
+  canvas?: paper.PaperScope,
+  grid: Array<Array<paper.Path.Rectangle>>
+}
+
+
+export default Heatmap;

+ 7 - 0
src/Router.tsx

@@ -8,7 +8,9 @@ import App, { ClosureNotice } from './App';
 import Admin from './Admin';
 import ConsentInformation from './Consent';
 import MoreInfo from './MoreInfo';
+import Heatmap from './Heatmap';
 import './App.css';
+import results from './results.json';
 
 export const AppRouting = () => {
   return (
@@ -21,6 +23,11 @@ export const AppRouting = () => {
           <Route sensitive path="/admin">
             <Admin></Admin>
           </Route>
+          <Route path="/heatmap">
+            <Heatmap
+              data={results}
+            ></Heatmap>
+          </Route>
           <Route path="/terms">
             <ConsentInformation/>
           </Route>

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 9770 - 0
src/results.json