luis 7 лет назад
Родитель
Сommit
e0378dd50b

+ 5 - 155
browser/vue-flow/src/App.vue

@@ -1,129 +1,20 @@
 <template>
   <div id="app">
     <h3>An app with svg</h3>
-    <input
-      type="text"
-      v-model="nodes[nodes.length-1].label">
-    <s-svg
+    <flow-manager
       width="100%"
-      height="100%">
+      height="100%"/>
 
-      <g class="connection" v-for="l of links">
-        <path
-          class="area"
-          :d="l.link.d"
-        />
-        <path
-          class="visible"
-          :d="l.link.d"
-        />
-      </g>
-
-      <s-node
-        v-model="n.node"
-        v-for="(n,i) of nodes"
-        :inputs="n.inputs"
-        :label="n.label"
-        :key="n.id"
-        :id="n.id"
-        @nodeDragStart="nodeDragStart(i,$event)"
-        @nodeDrag="nodeDrag(i,$event)"
-      />
-
-    </s-svg>
-
-    <div v-for="n of nodes">{{ n }}</div>
   </div>
 </template>
 
 <script>
-import AppSvg from '@/components/svgcontainer'
-import AppCircle from '@/components/circle'
-import AppNode from '@/components/node'
+import FlowManager from '@/components/flowmanager'
 
 export default {
   name: 'App',
   components: {
-    's-svg': AppSvg,
-    's-circle': AppCircle,
-    's-node': AppNode
-  },
-  data () {
-    return {
-      // And retrieve as event
-      // We want X/Y position from the node to serialize
-      // we will comunicate to the server only the nodes and links
-      nodes: [
-        {id: '1', label: 'Input', inputs: 0, node: {}},
-        {id: '2', label: 'MatMul-2', inputs: 2, node: {}},
-        {id: '3', label: 'Weights-3', inputs: 0, node: {}},
-        {id: '4', label: 'Activation-4', inputs: 1, node: {}},
-        {id: '5', label: 'MatMul-5', inputs: 4, node: {}}
-      ],
-      links: [
-        {from: '1', to: '2', in: 1, link: {}},
-        {from: '3', to: '2', in: 0, link: {}},
-
-        {from: '2', to: '4', in: 0, link: {}},
-        {from: '4', to: '5', in: 1, link: {}}
-        // {from: '3', to: '4', in: 1, link: {}}
-      ]
-    }
-  },
-  watch: {
-    nodes (nodes) {
-      console.log('Nodes:', nodes)
-      for (let node of nodes) {
-        console.log('Linking:', node.id)
-        // Links for node?
-        const foundLinks = this.links.filter(l => l.from === node.id)
-        for (let l of foundLinks) {
-          const fromNode = this.nodes.find(n => n.id === l.from)
-          const toNode = this.nodes.find(n => n.id === l.to)
-
-          let {cx: x1, cy: y1} = fromNode.node.output[0]
-          let {cx: x2, cy: y2} = toNode.node.input[l.in]
-
-          x1 += fromNode.node.movePos.x
-          y1 += fromNode.node.movePos.y
-
-          x2 += toNode.node.movePos.x
-          y2 += toNode.node.movePos.y
-
-          l.link.d = `M${x1},${y1} C${x1 + 50},${y1} ${x2 - 50},${y2} ${x2},${y2}`
-        }
-      }
-    },
-    deep: true
-  },
-  methods: {
-    nodeDragStart (idx) {
-      console.log('Start drag')
-      var tnode = this.nodes[idx]
-      this.nodes.splice(idx, 1)
-      this.nodes.push(tnode) // put in last
-    },
-    nodeDrag (idx) {
-      this.$nextTick(() => {
-        var tnode = this.nodes[idx]
-        const foundLinks = this.links.filter(l => l.from === tnode.id || l.to === tnode.id)
-        for (let l of foundLinks) {
-          const fromNode = this.nodes.find(n => n.id === l.from)
-          const toNode = this.nodes.find(n => n.id === l.to)
-
-          let {cx: x1, cy: y1} = fromNode.node.output[0]
-          let {cx: x2, cy: y2} = toNode.node.input[l.in]
-
-          x1 += fromNode.node.movePos.x
-          y1 += fromNode.node.movePos.y
-
-          x2 += toNode.node.movePos.x
-          y2 += toNode.node.movePos.y
-
-          l.link.d = `M${x1},${y1} C${x1 + 50},${y1} ${x2 - 50},${y2} ${x2},${y2}`
-        }
-      })
-    }
+    'FlowManager': FlowManager
   }
 }
 </script>
@@ -138,53 +29,12 @@ export default {
   margin-top: 60px;
 }
 
-#app svg {
+#app .flow-container {
   position:fixed;
   top:0;
   right:0;
   left:0;
   bottom:0;
-  pointer-events:none;
-}
-#app svg > * {
-  pointer-events: initial;
 }
 
-h1, h2 {
-  font-weight: normal;
-}
-
-ul {
-  list-style-type: none;
-  padding: 0;
-}
-
-li {
-  display: inline-block;
-  margin: 0 10px;
-}
-
-a {
-  color: #42b983;
-}
-input {
-  display:block;
-}
-.connection {
-  cursor:pointer;
-}
-.connection .area {
-  stroke-width:20;
-  stroke: transparent;
-  fill:none;
-}
-.connection .visible{
-  stroke: rgba(0,0,0,0.5);
-  stroke-width:5;
-  stroke-linecap:round;
-  fill: transparent;
-}
-.connection:hover .visible {
-  stroke: #F00;
-}
 </style>

+ 0 - 24
browser/vue-flow/src/components/circle.vue

@@ -1,24 +0,0 @@
-<template>
-  <circle
-    class="mycircle"
-    :cx="cx"
-    :cy="cy"
-    :r="r"/>
-</template>
-<script>
-export default {
-  props: {
-    'cx': {type: Number, default: 0},
-    'cy': {type: Number, default: 0},
-    'r': {type: Number, default: 0}
-  }
-}
-</script>
-<style scoped>
-.mycircle:hover {
-  cursor:pointer;
-  fill:transparent;
-  stroke: #F00;
-}
-
-</style>

+ 0 - 3
browser/vue-flow/src/components/eventbus.js

@@ -1,3 +0,0 @@
-import Vue from 'vue'
-
-export const EventBus = new Vue()

+ 234 - 0
browser/vue-flow/src/components/flowmanager.vue

@@ -0,0 +1,234 @@
+<template>
+  <div class="flow-container">
+    <svg
+      ref="svg"
+      class="view"
+      :width="width"
+      :height="height">
+
+      <!-- static dragger -->
+      <rect
+        ref="transformer"
+        class="transformer"
+        width="100%"
+        height="100%"
+        @mousedown="dragStart"/>
+
+      <g
+        ref="transform"
+        :transform="panzoomTransform">
+
+        <!-- links -->
+        <g
+          class="connection"
+          v-for="(l,i) in nodeData.links"
+          :key="i"
+        >
+          <path
+            class="area"
+            v-bind="link(l)"
+          />
+          <path
+            class="visible"
+            v-bind="link(l)"
+          />
+        </g>
+
+        <!-- nodes -->
+        <flow-node
+          ref="nodes"
+          v-for="(n,i) of nodeData.nodes"
+          :key="'node' + n.id"
+          :id="n.id"
+          :value="n"
+          :transform="nodeTransform(i)"
+          @nodePointerDown.prevent="nodeDragStart($event,i)"
+          @socketPointerDown.prevent="nodeDragStart($event,i)"
+        />
+
+      </g>
+    </svg>
+    {{ nodeData }}
+    <div v-for="(n,i) of nodeData.nodes">
+      <input type="text" v-model="n.label">
+    </div>
+  </div>
+</template>
+<script>
+import nodeData from './nodedata'
+import FlowNode from './flownode'
+
+export default {
+  name: 'FlowManager',
+  components: {FlowNode},
+  props: {
+    'width': {type: String, default: '800px'},
+    'height': {type: String, default: '600px'}
+  },
+  data () {
+    return {
+      nodeData: nodeData // shared?
+    }
+  },
+  computed: {
+    panzoomTransform () {
+      const transString = 'matrix(' + [
+        this.nodeData.zoom, 0, 0,
+        this.nodeData.zoom, this.nodeData.pan.x, this.nodeData.pan.y
+      ].join(' ') + ')'
+      return transString
+    },
+    nodeTransform () {
+      return (i) => `translate(${this.nodeData.nodes[i].x} ${this.nodeData.nodes[i].y})`
+    }
+  },
+  mounted () {
+    document.addEventListener('mousewheel', this.wheel)
+    document.addEventListener('mousemove', this.mousemove)
+    this.$nextTick(() => {
+      this.$forceUpdate()
+    })
+  },
+  beforeDestroy () {
+    document.removeEventListener('mousewheel', this.wheel)
+    document.removeEventListener('mousemove', this.mousemove)
+  },
+  methods: {
+    socketPointerDown (e, i, ...params) {
+      console.log('Socket down', e, i, params)
+    },
+    nodeDragStart (e, i) {
+      // we can handle with nodeId and a search
+      var tnode = this.nodeData.nodes[i]
+      this.nodeData.nodes.splice(i, 1)
+      this.nodeData.nodes.push(tnode) // put in last
+
+      const mousemove = (e) => {
+        tnode.x += e.movementX / this.nodeData.zoom
+        tnode.y += e.movementY / this.nodeData.zoom
+      }
+      const mouseup = (e) => {
+        document.removeEventListener('mousemove', mousemove)
+        document.removeEventListener('mouseup', mouseup)
+      }
+      document.addEventListener('mousemove', mousemove)
+      document.addEventListener('mouseup', mouseup)
+    },
+    link (link) {
+      if (!this.$refs.nodes) return
+      const refFrom = this.$refs.nodes.find(n => n.value.id === link.from)
+      const refTo = this.$refs.nodes.find(n => n.value.id === link.to)
+
+      const fromOutput = refFrom.output(0) // only 1 output
+      const toInput = refTo.input(link.in)
+
+      const x1 = refFrom.value.x + fromOutput.cx // + inputPos.x
+      const y1 = refFrom.value.y + fromOutput.cy // + inputPos.y
+
+      const x2 = refTo.value.x + toInput.cx
+      const y2 = refTo.value.y + toInput.cy
+      // console.log('Thing:', x1, y1, x2, y2)
+
+      const linkProps = {d: `M${x1},${y1} C${x1 + 50},${y1} ${x2 - 50},${y2} ${x2},${y2}`}
+      return linkProps
+    },
+    /*
+    nodeDragStart (idx) {
+      console.log('Start drag')
+      var tnode = this.nodes[idx]
+      this.nodes.splice(idx, 1)
+      this.nodes.push(tnode) // put in last
+    },
+    nodeDrag (idx) {
+      this.$nextTick(() => {
+        // manipulate links
+        var tnode = this.nodes[idx]
+        const foundLinks = this.links.filter(l => l.from === tnode.id || l.to === tnode.id)
+        for (let l of foundLinks) {
+          const fromNode = this.nodes.find(n => n.id === l.from)
+          const toNode = this.nodes.find(n => n.id === l.to)
+
+          let {cx: x1, cy: y1} = fromNode.node.output[0]
+          let {cx: x2, cy: y2} = toNode.node.input[l.in]
+
+          x1 += fromNode.node.movePos.x
+          y1 += fromNode.node.movePos.y
+
+          x2 += toNode.node.movePos.x
+          y2 += toNode.node.movePos.y
+
+          l.link.d = `M${x1},${y1} C${x1 + 50},${y1} ${x2 - 50},${y2} ${x2},${y2}`
+        }
+      })
+    }, */
+
+    // panStart
+    dragStart (e) {
+      console.log(e.target)
+      if (e.target !== this.$refs.transformer) return
+      document.addEventListener('mousemove', this.drag)
+      document.addEventListener('mouseup', this.dragStop)
+    },
+    drag (e) {
+      this.nodeData.pan.x += e.movementX
+      this.nodeData.pan.y += e.movementY
+    },
+    dragStop (e) {
+      document.removeEventListener('mousemove', this.drag)
+      document.removeEventListener('mouseup', this.dragStop)
+    },
+    wheel (e) {
+      var oX = e.clientX
+      var oY = e.clientY
+      const z = this.nodeData.zoom - (e.deltaY * 0.001 * this.nodeData.zoom)
+
+      var curX = this.nodeData.pan.x
+      var curY = this.nodeData.pan.y
+      var scaleD = z / this.nodeData.zoom // delta
+
+      var nx = scaleD * (curX - oX) + oX
+      var ny = scaleD * (curY - oY) + oY
+
+      this.nodeData.pan.x = nx
+      this.nodeData.pan.y = ny
+      this.nodeData.zoom = z
+    }
+  }
+
+}
+
+</script>
+<style>
+.flow-container {
+  display:flex;
+  flex-flow:column;
+}
+svg.view {
+  border: solid 1px #F00;
+  position:relative;
+}
+.transformer {
+  stroke: black;
+  stroke-width: 1;
+  fill:transparent;
+
+}
+.connection {
+  cursor:pointer;
+}
+.connection .area {
+  stroke-width:20;
+  stroke: transparent;
+  fill:none;
+}
+.connection .visible{
+  stroke: rgba(0,0,0,0.5);
+  stroke-width:5;
+  stroke-linecap:round;
+  fill: transparent;
+}
+.connection:hover .visible {
+  stroke: #F00;
+}
+
+</style>

+ 139 - 0
browser/vue-flow/src/components/flownode.vue

@@ -0,0 +1,139 @@
+<template>
+  <g
+    class="s-node"
+    :class="{'s-node--dragging':dragging}"
+    @mousedown="$emit('nodePointerDown',$event)"
+  >
+    <rect
+      ref="body"
+      class="s-node__body"
+      v-bind="bodyProps"
+    />
+    <!-- input -->
+    <circle
+      class="s-node__socket s-node__inputs"
+      v-for="i in value.inputs"
+      v-bind="input(i-1)"
+      :key="'in'+i"
+      @mousedown="$emit('socketPointerDown',$event, {in:i-1})"
+    />
+    <!-- output -->
+    <circle
+      class="s-node__socket s-node__outputs"
+      :key="'out'+0"
+      v-bind="output(0)"
+    />
+    <text
+      ref="label"
+      class="s-node__label"
+      v-bind="labelProps">
+      {{ value.label }}
+    </text>
+  </g>
+</template>
+
+<script>
+
+export default {
+  name: 'FlowNode',
+  props: {
+    'value': {type: Object, default: () => {}}
+  },
+  data () {
+    return {
+      // maintain reference here?
+      dragging: false,
+      labelRect: {x: 0, y: 0, width: 0, height: 0},
+      bodyRect: {x: 0, y: 0, width: 0, height: 0}
+    }
+  },
+  computed: {
+    labelProps () {
+      return {x: -this.labelRect.width / 2, y: 5}
+    },
+    bodyProps () {
+      const width = this.labelRect.width + 20
+      const rect = {x: -width / 2, y: -50, width: width, height: 100}
+      if (this.value.type === 'circle') {
+        rect.rx = width
+        rect.ry = width
+      }
+      return rect
+    },
+    input () {
+      return (i) => {
+        if (this.value.inputs === 0) return {}
+        const d = this.bodyProps.height / (this.value.inputs * 2)
+        return {
+          cx: this.bodyProps.x,
+          cy: this.bodyProps.y + d + (i * 2 * d)
+        }
+      }
+    },
+    output () {
+      return (i) => {
+        const rect = this.bodyProps
+        return {cx: rect.x + rect.width, cy: 0, r: 10}
+      }
+    }
+
+  },
+  watch: {
+    // the only thing now that affects geometry
+    'value.label' () {
+      this.$nextTick(() => {
+        this.labelRect = this.$refs.label.getBBox()
+      })
+    }
+  },
+  mounted () {
+    // After render
+    this.labelRect = this.$refs.label.getBBox()
+    this.$nextTick(() => { // after mount we reupdate with new values
+      this.$forceUpdate()
+    })
+  }
+}
+</script>
+<style lang="scss">
+.s-node__body {
+  fill: #EFEFEF;
+  stroke: #ddd;
+  stroke-width:1;
+
+  -webkit-filter: drop-shadow(5px 5px 5px #000);
+          filter: drop-shadow(5px 5px 5px #000);
+
+}
+.s-node__body:hover,
+.s-node.snode--dragging s-node__body {
+  z-index:10;
+  fill: #DFDFDF;
+  cursor:move;
+  //stroke:red;
+  //stroke-width:4;
+  transition: all 1s;
+}
+.s-node {
+}
+.s-node.s-node--dragging {
+}
+.s-node__socket {
+  fill: #AFAFAF;
+  stroke:none;
+
+  cursor:pointer;
+  stroke-width:2;
+  r:6;
+}
+.s-node__socket:hover {
+  r:10;
+}
+.s-node__inputs {
+}
+.s-node__label {
+  fill: #444;
+  pointer-events:none;
+  user-select:none;
+}
+</style>

+ 0 - 193
browser/vue-flow/src/components/node.vue

@@ -1,193 +0,0 @@
-<template>
-  <g
-    class="s-node"
-    @mousedown.prevent="pointerDown"
-    :transform="nodeTransform"
-    :class="{'s-node--dragging':node.dragging}"
-  >
-    <rect
-      class="s-node__rect"
-      v-bind="node.rect"
-    />
-    <!-- input -->
-    <circle
-      class="s-node__socket s-node__inputs"
-      v-for="(v,i) in node.input"
-      :key="'in'+i"
-      v-bind="v"
-    />
-    <!-- output -->
-    <circle
-      class="s-node__socket s-node__outputs"
-      v-for="(m,i) in node.output"
-      :key="'out'+i"
-      v-bind="m"
-    />
-    <text
-      ref="label"
-      class="s-node__label"
-      v-bind="node.labelPos">
-      {{ label }}
-    </text>
-  </g>
-</template>
-
-<script>
-import {EventBus} from './eventbus'
-
-export default {
-  name: 'SNode',
-  props: {
-    'id': {type: String, required: true},
-    'inputs': {type: Number, default: 0},
-    'outputs': {type: Number, default: 1},
-    'label': {type: String, default: 'und'}
-  },
-  data () {
-    return {
-      node: {
-        id: this.id,
-        labelPos: {x: -40, y: 5},
-        movePos: {x: 200, y: 200},
-        dragging: false,
-        rect: {
-          x: -(100 / 2),
-          y: -(100 / 2),
-          width: 100,
-          height: 100
-        },
-        input: [],
-        output: []
-      }
-    }
-  },
-  computed: {
-    nodeTransform () {
-      return `translate(${this.node.movePos.x} ${this.node.movePos.y})`
-    }
-  },
-
-  watch: {
-    label () {
-      if (!this.$refs) return
-      this.$nextTick(() => { // After element update
-        this.recalculate()
-      })
-    }
-  },
-  mounted () {
-    this.$nextTick(() => {
-      this.recalculate()
-    })
-  },
-  methods: {
-    // Recalculate visuals
-    recalculate () {
-      if (!this.$refs) return
-      // change
-      const box = this.$refs.label.getBBox()
-      this.node.rect.width = box.width + 20
-
-      // inputs
-      {
-        this.node.input = []
-        const d = (this.node.rect.height) / (this.inputs * 2)
-        for (let i = 0; i < this.inputs; i++) {
-          this.node.input.push({
-            cx: this.node.rect.x,
-            cy: this.node.rect.y + d + (i * 2 * d),
-            r: 10
-          })
-        }
-      }
-      {
-        this.node.output = []
-        const d = (this.node.rect.height) / (this.outputs * 2)
-        for (let i = 0; i < this.outputs; i++) {
-          this.node.output.push({
-            cx: this.node.rect.x + this.node.rect.width,
-            cy: this.node.rect.y + d + (i * 2 * d),
-            r: 10
-          })
-        }
-      }
-      this.$emit('input', this.node)
-      this.$emit('update', this.node)
-    },
-
-    pointerDown (e) {
-      this.$emit('nodeDragStart', this)
-      this.node.dragging = true
-      EventBus.$on('mousemove', this.pointerMove)
-      // document.addEventListener('mousemove', this.pointerMove)
-      document.addEventListener('mouseup', this.pointerUp)
-
-      this.$emit('input', this.node)
-      this.$emit('update', this.node)
-    },
-    pointerMove (e) {
-      this.$emit('nodeDrag', this)
-      this.node.movePos.x += e.movementX
-      this.node.movePos.y += e.movementY
-
-      this.$emit('input', this.node)
-      this.$emit('update', this.node)
-      // this.$el.setAttribute('transform', `translate(${this.movePos.x} ${this.movePos.y})`)
-    },
-    pointerUp (e) {
-      this.$emit('nodeDragStop', this)
-      // document.removeEventListener('mousemove', this.pointerMove)
-      EventBus.$off('mousemove', this.pointerMove)
-      document.removeEventListener('mouseup', this.pointerUp)
-      this.node.dragging = false
-      this.$emit('input', this.node)
-      this.$emit('update', this.node)
-    }
-
-  }
-
-}
-</script>
-<style lang="scss">
-.s-node__rect {
-  fill: #EFEFEF;
-  stroke: #ddd;
-  stroke-width:1;
-
-  -webkit-filter: drop-shadow(5px 5px 5px #000);
-          filter: drop-shadow(5px 5px 5px #000);
-
-}
-.s-node__rect:hover,
-.s-node.snode--dragging s-node__rect {
-  z-index:10;
-  fill: #DFDFDF;
-  cursor:move;
-  //stroke:red;
-  //stroke-width:4;
-  transition: all 1s;
-}
-.s-node {
-}
-.s-node.s-node--dragging {
-}
-.s-node__socket {
-  fill: #AFAFAF;
-  stroke:none;
-
-  cursor:pointer;
-  stroke-width:2;
-  r:6;
-
-}
-.s-node__socket:hover {
-  r:10;
-}
-.s-node__inputs {
-}
-.s-node__label {
-  fill: #444;
-  pointer-events:none;
-  user-select:none;
-}
-</style>

+ 21 - 0
browser/vue-flow/src/components/nodedata.js

@@ -0,0 +1,21 @@
+// Document shared state
+export default {
+  pan: {x: 0, y: 0},
+  zoom: 1,
+  defaults: {
+    nodeHeight: 100
+  },
+  nodes: [
+    {id: '1', x: 100, y: 100, label: 'Test input random', inputs: 2},
+    {id: '2', x: 100, y: 300, label: 'Sigmoid', inputs: 1, type: 'circle'},
+    {id: '3', x: 300, y: 400, label: 'MatMul', inputs: 2},
+    {id: '4', x: 250, y: 300, label: 'Input', inputs: 0},
+    {id: '5', x: 700, y: 300, label: 'Weights', inputs: 0}
+  ],
+  links: [
+    {from: '4', to: '3', in: 1, link: {}},
+    {from: '5', to: '3', in: 0, link: {}},
+    {from: '3', to: '2', in: 0, link: {}},
+    {from: '2', to: '1', in: 0, link: {}}
+  ]
+}

+ 0 - 3
browser/vue-flow/src/components/readme.md

@@ -1,3 +0,0 @@
-svgcontainer should be the data container
-can contain the links
-node will have the input and output

+ 0 - 100
browser/vue-flow/src/components/svgcontainer.vue

@@ -1,100 +0,0 @@
-<template>
-  <svg
-    class="view"
-    :width="width"
-    :height="height">
-    <rect ref="transformer" class="transformer" width="100%" height="100%" @mousedown="dragStart"/>
-    <g ref="transform" :transform="panzoomTransform">
-      <slot/>
-    </g>
-  </svg>
-</template>
-<script>
-import {EventBus} from './eventbus'
-
-export default {
-  props: {
-    'width': {type: String, default: '800px'},
-    'height': {type: String, default: '600px'}
-  },
-  data () {
-    return {
-      tr: { x: 0, y: 0, z: 1 }
-    }
-  },
-  computed: {
-    panzoomTransform () {
-      const transString = 'matrix(' + [
-        this.tr.z, 0, 0,
-        this.tr.z, this.tr.x, this.tr.y
-      ].join(' ') + ')'
-      return transString
-    }
-  },
-  mounted () {
-    document.addEventListener('mousewheel', this.wheel)
-
-    document.addEventListener('mousemove', (e) => {
-      EventBus.$emit('mousemove', {
-        movementX: e.movementX * (1 / this.tr.z),
-        movementY: e.movementY * (1 / this.tr.z)
-      })
-    })
-  },
-  beforeDestroy () {
-    document.removeEventListener('mousewheel', this.wheel)
-  },
-  methods: {
-    dragStart (e) {
-      console.log(e.target)
-      if (e.target !== this.$refs.transformer) return
-      document.addEventListener('mousemove', this.drag)
-      document.addEventListener('mouseup', this.dragStop)
-    },
-    drag (e) {
-      this.tr.x += e.movementX
-      this.tr.y += e.movementY
-    },
-    dragStop (e) {
-      document.removeEventListener('mousemove', this.drag)
-      document.removeEventListener('mouseup', this.dragStop)
-    },
-    wheel (e) {
-      /* if (e.deltaY < 0) {
-        this.zoom = 1.1
-      } else {
-        this.zoom = 0.9
-      } */
-      var oX = e.clientX
-      var oY = e.clientY
-      const z = this.tr.z + e.deltaY * 0.001
-
-      var curX = this.tr.x
-      var curY = this.tr.y
-      var scaleD = z / this.tr.z // delta
-
-      var nx = scaleD * (curX - oX) + oX
-      var ny = scaleD * (curY - oY) + oY
-
-      this.tr.x = nx
-      this.tr.y = ny
-      this.tr.z = z
-      console.log('Trans:', this.tr.x, this.tr.x, ' zoom:', this.tr.z)
-    }
-  }
-
-}
-
-</script>
-<style>
-svg.view {
-  border: solid 1px #F00;
-  position:relative;
-}
-.transformer {
-  stroke: black;
-  stroke-width: 1;
-  fill:transparent;
-
-}
-</style>

+ 1 - 1
go/.gitignore

@@ -1,4 +1,4 @@
 deps
-pkgs
+pkg
 bin
 

+ 0 - 1
go/deps/src/github.com/gohxs/vec-benchmark

@@ -1 +0,0 @@
-Subproject commit de7f89849637da5a4217f0017b488cf4e6c6a44c

BIN
go/pkg/linux_amd64/flow.a


+ 28 - 0
readme.md

@@ -0,0 +1,28 @@
+# TODO
+
+# Minimal idea
+
+UI to create multipurpose tensorflow alike graphs,
+upload to the server
+pass inputs and do training
+fetch model and use it with new inputs
+distributed purpose to calculate several nodes across a network
+
+implement common AI methods(funcs) reuse them
+
+## Frontend
+
+* [ ] Deal with svg relative mouse position
+* [ ] do an event from one socket to another
+      highlighting the ones compatible for data type
+* [ ] Create something to add/remove links/nodes as in populating from the server
+* [ ] Colaborative editing through possibly websocket, by sharing states
+* [ ] const/var editor with multiple props
+* [ ] add types to sockets (litle label aside)
+
+## Backend
+
+* [ ] create http server that serializes and inspect run graphs
+      (step by step)
+* [ ] Serve registry with information about inputs/outputs
+* [ ] Protocol to build and run a graph from frontend