React

by hrabinowitz

HTML

<div id="root"></div>

CSS

svg {
  background-color: lightgray;
}

rect.sz {
  fill: gray;
}

rect.map {
  fill: pink;
}

.mapSzGroup text, 
.traySensorGroup text {
  font-family: sans-serif;
  font-size: 12px;
  text-anchor: middle;
  dominant-baseline: middle;
}

rect.tray {
  fill: turquoise;
}

svg text {
  user-select: none;
}


.draggable {
  cursor: pointer;
}

.nonDraggable {
  cursor: not-allowed;
}

Babel + JSX

"use strict";

let data = {
  mappedSensors: {
    ABCD: { x: 100, y: 20, color: "yellow", dotid: "ABCD" },
    FACE: { x: 100, y: 100, color: "orange", dotid: "FACE" }
  },
  traySensors: {
    AAAA: { x: 20, y: 20, color: "yellow", dotid: "AAAA" },
    BBBB: { x: 65, y: 20, color: "orange", dotid: "BBBB" }
  },
  svgHeight: 200
};

var draggingElt = null;
var draggingEltDatum = null;
var draggingEltStartLoc = null;
var draggingEltDotid = null;
var draggingOffset = null;

class Map extends React.Component {
  constructor(props) {
    super(props);
    this.state = data;
    // These bindings are necessary to make `this` work in the callback
    this.onMouseUp = this.onMouseUp.bind(this);
    this.onMouseLeave = this.onMouseLeave.bind(this);
    this.onMouseMove = this.onMouseMove.bind(this);
    this.getMousePosition = this.getMousePosition.bind(this);
  }

  getMousePosition(evt) {
    const svg = document.getElementById("mapSvg");
    const CTM = svg.getScreenCTM();
    const modifiedPosition = {
      x: (evt.clientX - CTM.e) / CTM.a,
      y: (evt.clientY - CTM.f) / CTM.d
    };
     console.log(
      "getMousePosition(): event.clientXY=",
      [evt.clientX, evt.clientY],
      "modifiedPosition: ", modifiedPosition
    );
   return modifiedPosition;
  }

  // drop handler
  onMouseUp(event) {
    console.log("onMouseUp() started: draggingElt=", draggingElt, event);
    event.preventDefault();
    let coord = this.getMousePosition(event);
    let dotid = draggingEltDotid;
    // TODO: do drop action here...  test valid target
    // TODO: if mouseup location is over map rect
    //       (for now, assume true)
    this.setState((state) => {
      let mappedSensors = state.mappedSensors;
      mappedSensors[dotid] = draggingEltDatum;
      mappedSensors[dotid].x = coord.x;
      mappedSensors[dotid].y = coord.y;
      let traySensors = state.traySensors;
      delete traySensors[dotid];
      draggingElt = null;
      draggingEltDotid = null;
      return...