vue-SVG图形

SVG图形
传送门
此实例主要涉及vue的组件,computed等知识。
上js代码:
// The raw data to observe
var stats = [ // 定义初始的数据
  { label: 'A', value: 100 },
  { label: 'B', value: 100 },
  { label: 'C', value: 100 },
  { label: 'D', value: 100 },
  { label: 'E', value: 100 },
  { label: 'F', value: 100 }
]

// A resusable polygon graph component
Vue.component('polygraph', { // 定义并注册一个图形组件
  props: ['stats'], // 传递父组件传递来的数据
  template: '#polygraph-template',  
  replace: true,
  computed: {
    // 实时响应图形中的point,通过改变stat的value,来改变图形
    points: function () {
      var total = this.stats.length
      return this.stats.map(function (stat, i) { // 遍历stats中的每个值,计算出各个点的位置
        var point = valueToPoint(stat.value, i, total)
        return point.x + ',' + point.y
      }).join(' ')
    }
  },
  components: {
    // 一个子组件,可调整stats中value的值
    'axis-label': {
      props: {
        stat: Object,
        index: Number,
        total: Number
      },
      template: '#axis-label-template',
      replace: true,
      computed: {
        point: function () {
          return valueToPoint(
            +this.stat.value + 10,
            this.index,
            this.total
          )
        }
      }
    }
  }
})

// 通过数学方法来画图
function valueToPoint (value, index, total) {
  var x     = 0
  var y     = -value * 0.8
  var angle = Math.PI * 2 / total * index
  var cos   = Math.cos(angle)
  var sin   = Math.sin(angle)
  var tx    = x * cos - y * sin + 100
  var ty    = x * sin + y * cos + 100
  return {
    x: tx,
    y: ty
  }
}

// 创建根实例
new Vue({
  el: '#demo',
  data: {
    newLabel: '',
    stats: stats
  },
  methods: {
    add: function (e) {
      e.preventDefault() // 取消事件的默认动作
      if (!this.newLabel) return
      this.stats.push({
        label: this.newLabel,
        value: 100
      })
      this.newLabel = ''
    },
    remove: function (stat) {
      if (this.stats.length > 3) {
        this.stats.$remove(stat) // $remove 是vue添加的方法,从目标数组中查找并删除元素,在内部它调用 splice()
      } else {
        alert('Can\'t delete more!')
      }
    }
  }
})
再来看看我们的html代码:
<!-- polygraph组件的template,其中包含子组件的调用 -->
<script type="text/x-template" id="polygraph-template">
  <g>
    <polygon :points="points"></polygon>
    <circle cx="100" cy="100" r="80"></circle>
    <axis-label
      v-for="stat in stats"
      :stat="stat"
      :index="$index"
      :total="stats.length">
    </axis-label>
  </g>
</script>

<!-- axis label组件的template,用于调整数值来改变图像 -->
<script type="text/x-template" id="axis-label-template">
  <text :x="point.x" :y="point.y">{{stat.label}}</text>
</script>

<!-- 根实例 -->
<div id="demo">
  <!-- 在这使用polygraph组件 -->
  <svg width="200" height="200">
    <polygraph :stats="stats"></polygraph>
  </svg>
  <!-- 可控制数值大小,并添加删除元素 -->
  <div v-for="stat in stats">
    <label>{{stat.label}}</label>
    <input type="range" v-model="stat.value" min="0" max="100">
    <span>{{stat.value}}</span>
    <button @click="remove(stat)">X</button>
  </div>
  <form id="add">
    <input name="newlabel" v-model="newLabel">
    <button @click="add">Add a Stat</button>
  </form>
  <pre id="raw">{{stats | json}}</pre>
</div>
  
<p style="font-size:12px">* input[type="range"] requires IE10 or above.</p>
最后是css代码:
body {
    font-family: Helvetica Neue, Arial, sans-serif;
}

polygon {
    fill: #42b983;
    opacity: .75;
}

circle {
    fill: transparent;
    stroke: #999;
}

text {
    font-family: Helvetica Neue, Arial, sans-serif;
    font-size: 10px;
    fill: #666;
}

label {
    display: inline-block;
    margin-left: 10px;
    width: 20px;
}

#raw {
    position: absolute;
    top: 0;
    left: 300px;
}
写到最后你会感受到编程的神奇,vue的便捷。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容

  • 节气:立夏 时间:2017年5月5 周五 出行时间:2017年5月6 周六 天气:晴 地点:趵突泉 人物:麦芽,麦...
    146195562bba阅读 400评论 0 1
  • 最高人民法院指导案例18号 中兴通讯(杭州)有限责任公司诉王鹏劳动合同纠纷案 (最高人民法院审判委员会讨论通过20...
    小好阅读 620评论 1 3
  • 亲爱的孩子,又是一个周六,外面大雨,吃完早餐,我们各自学习。妈妈看书,你写作业。之前,全家早餐讨论到自己的偶像,我...
    Grit888阅读 156评论 0 2
  • 哎呀妈,山水相依白兔精, 吓坏我,南瓜种满玉树林。 赶快跑,月夜风高乘风起, 去拿糖。万圣节日欢乐多。 夜景/作
    夜景黑色调阅读 268评论 0 0