Browse Source

Initial dev

luis 7 năm trước cách đây
commit
6a6fe0583b

+ 6 - 0
browser/vue-flow/.babelrc

@@ -0,0 +1,6 @@
+{
+  "presets": [
+    ["env", { "modules": false }],
+    "stage-3"
+  ]
+}

+ 9 - 0
browser/vue-flow/.editorconfig

@@ -0,0 +1,9 @@
+root = true
+
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 2
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true

+ 3 - 0
browser/vue-flow/.eslintrc.js

@@ -0,0 +1,3 @@
+module.exports = {
+  extends: [ 'standard', 'plugin:vue/recommended']
+}

+ 2 - 0
browser/vue-flow/.flowconfig

@@ -0,0 +1,2 @@
+[ignore]
+.*/node_modules/*

+ 12 - 0
browser/vue-flow/.gitignore

@@ -0,0 +1,12 @@
+.DS_Store
+node_modules/
+dist/
+npm-debug.log
+yarn-error.log
+
+# Editor directories and files
+.idea
+*.suo
+*.ntvs*
+*.njsproj
+*.sln

+ 18 - 0
browser/vue-flow/README.md

@@ -0,0 +1,18 @@
+# vue-svg
+
+> vue-svg-test
+
+## Build Setup
+
+``` bash
+# install dependencies
+npm install
+
+# serve with hot reload at localhost:8080
+npm run dev
+
+# build for production with minification
+npm run build
+```
+
+For detailed explanation on how things work, consult the [docs for vue-loader](http://vuejs.github.io/vue-loader).

+ 11 - 0
browser/vue-flow/index.html

@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <title>vue-svg</title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script src="/dist/build.js"></script>
+  </body>
+</html>

+ 45 - 0
browser/vue-flow/package.json

@@ -0,0 +1,45 @@
+{
+  "name": "vue-svg",
+  "description": "vue-svg-test",
+  "version": "1.0.0",
+  "author": "luis <stdiopt@gmail.com>",
+  "license": "MIT",
+  "private": true,
+  "scripts": {
+    "dev": "cross-env NODE_ENV=development webpack-dev-server --open --hot",
+    "build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
+  },
+  "dependencies": {
+    "vue": "^2.5.11"
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not ie <= 8"
+  ],
+  "devDependencies": {
+    "babel-core": "^6.26.0",
+    "babel-loader": "^7.1.2",
+    "babel-preset-env": "^1.6.0",
+    "babel-preset-stage-3": "^6.24.1",
+    "cross-env": "^5.0.5",
+    "css-loader": "^0.28.7",
+    "eslint": "^4.14.0",
+    "eslint-config-node": "^2.0.0",
+    "eslint-config-standard": "^11.0.0-beta.0",
+    "eslint-plugin-node": "^5.2.1",
+    "eslint-plugin-promise": "^3.6.0",
+    "eslint-plugin-standard": "^3.0.1",
+    "eslint-plugin-vue": "^4.0.0-beta.4",
+    "file-loader": "^1.1.4",
+    "flow": "^0.2.3",
+    "flow-bin": "^0.62.0",
+    "html-webpack-plugin": "^2.30.1",
+    "node-sass": "^4.5.3",
+    "sass-loader": "^6.0.6",
+    "vue-loader": "^13.0.5",
+    "vue-template-compiler": "^2.4.4",
+    "webpack": "^3.6.0",
+    "webpack-dev-server": "^2.9.1"
+  }
+}

+ 190 - 0
browser/vue-flow/src/App.vue

@@ -0,0 +1,190 @@
+<template>
+  <div id="app">
+    <h3>An app with svg</h3>
+    <input
+      type="text"
+      v-model="nodes[nodes.length-1].label">
+    <s-svg
+      width="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'
+
+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}`
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+#app {
+  font-family: 'Avenir', Helvetica, Arial, sans-serif;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  text-align: center;
+  color: #2c3e50;
+  margin-top: 60px;
+}
+
+#app svg {
+  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>

BIN
browser/vue-flow/src/assets/logo.png


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

@@ -0,0 +1,24 @@
+<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>

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

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

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

@@ -0,0 +1,193 @@
+<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>

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

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

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

@@ -0,0 +1,100 @@
+<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>

+ 7 - 0
browser/vue-flow/src/main.js

@@ -0,0 +1,7 @@
+import Vue from 'vue'
+import App from './App.vue'
+
+window.app = new Vue({
+  el: '#app',
+  render: h => h(App)
+})

+ 111 - 0
browser/vue-flow/webpack.config.js

@@ -0,0 +1,111 @@
+var path = require('path')
+var webpack = require('webpack')
+var HtmlWebpackPlugin = require('html-webpack-plugin')
+
+var outfile = 'vue-edi-table.js'
+
+module.exports = {
+  entry: './src/main.js',
+  output: {
+    path: path.resolve(__dirname, './dist'),
+    publicPath: '/dist',
+    filename: outfile
+    // libraryTarget: 'commonjs2'
+  },
+  module: {
+    rules: [
+      {
+        test: /\.css$/,
+        use: [
+          'vue-style-loader',
+          'css-loader'
+        ]
+      },
+      {
+        test: /\.vue$/,
+        loader: 'vue-loader',
+        options: {
+          loaders: {
+          }
+          // other vue-loader options go here
+        }
+      },
+      {
+        test: /\.(js|jsx)$/,
+        loader: 'babel-loader',
+        exclude: /node_modules/
+      },
+      {
+        test: /\.(png|jpg|gif|svg)$/,
+        loader: 'file-loader',
+        options: {
+          name: '[name].[ext]?[hash]'
+        }
+      },
+      {
+        test: /\.(ttf|woff)$/,
+        loader: 'file-loader',
+        options: {
+          name: '[name].[ext]?[hash]'
+        }
+      }
+    ]
+  },
+  resolve: {
+    alias: {
+      '@': path.join(__dirname, 'src'),
+      'vue$': 'vue/dist/vue.esm.js'
+    },
+    extensions: ['.vue', '*', '.js', '.json', '.jsx']
+  },
+  devServer: {
+    host: '0.0.0.0',
+    port: 8081,
+    disableHostCheck: true,
+    historyApiFallback: true,
+    noInfo: true,
+    overlay: true,
+    clientLogLevel: 'none'
+  },
+  performance: {
+    hints: false
+  },
+  devtool: '#eval-source-map'
+}
+
+if (process.env.NODE_ENV === 'development') {
+  Object.assign(module.exports, {
+    entry: './src/main.js',
+    output: {
+      path: path.resolve(__dirname, './docs'),
+      // publicPath: '/vue-edi-table/',
+      publicPath: '/',
+      filename: 'index.js'
+    }
+  })
+  module.exports.plugins = (module.exports.plugins || []).concat([
+    new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html' })
+  ])
+}
+
+if (process.env.NODE_ENV === 'production') {
+  module.exports.devtool = '#source-map'
+  // http://vue-loader.vuejs.org/en/workflow/production.html
+  module.exports.plugins = (module.exports.plugins || []).concat([
+    new webpack.DefinePlugin({
+      'process.env': {
+        NODE_ENV: '"production"'
+      }
+    }),
+    new webpack.optimize.UglifyJsPlugin({
+      sourceMap: true,
+      compress: {
+        warnings: false
+      }
+    }),
+    new webpack.LoaderOptionsPlugin({
+      minimize: true
+    })
+  ])
+  module.exports.externals = { 'vue': 'vue' }
+}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 5644 - 0
browser/vue-flow/yarn.lock


+ 4 - 0
go/.gitignore

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

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

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

BIN
go/pkg/linux_amd64/flow.a


+ 1 - 0
go/src/flow

@@ -0,0 +1 @@
+Subproject commit 7d8bf49e51ca5e346c44a99bbb7c2efaf873516d