vue-chartjs文档翻译

原文地址: https://vue-chartjs.org/zh-cn/guide/

起步

vue-chartjs 是 Vue 对于 Chart.js 的封装. 你可以很简单的创建可复用的图表组件.

介绍

vue-chartjs 让你在 Vue 中能更好的使用 Chart.js . 非常适合想要尽快启动和运行简单图表的人

它抽象了一些简单的逻辑, 但是也暴露了 Chart.js 对象, 提供了极大的灵活性.

安装

NPM

你可以在 npm 下安装 vue-chartjs. 当然, 你也需要在项目中安装 chart.js 依赖. 因为 Chart.js 是一个 peerDependency. 这种方式你可以完全控制 Chart.js 的版本

yarn add vue-chartjs chart.js or npm install vue-chartjs chart.js --save

::: tip
如果你使用的是 vue 1.x 版本, 请使用 legacy 标签. 然而, Vue 1 所支持的版本不再维护了.

yarn add vue-chartjs@legacy
:::

浏览器

你也可以直接在浏览器中使用 vue-chartjs.
先添加 Chart.js 脚本, 再添加 vue-chartjs 脚本.

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<script src="https://unpkg.com/vue-chartjs/dist/vue-chartjs.min.js"></script>

整合

Chart.js 将所有可用的图表类型, 都导出为命名组件, 并可以直接导入它们. 这些组件都是普通的 Vue 组件, 然而, 你需要扩展它.

vue-chartjs 的想法是提供容易使用的组件, 并且具有最大限度的灵活性和扩展性. 要实现这一点, 你需要创建你自己的 Chart Component 并通过 vue-chartjs 提供的组件来扩展它.

这样,Chart组件中的方法和逻辑就可以合并到您自己的图表组件中.

创建你自己的第一个图表

你需要引入一个基本图表然后扩展它. 这为处理不同数据时提供了更大的灵活性. 你可以封装你的组件以及使用props来处理数据, 或者你可以直接在组件里输入他们. 当然, 如果那样做, 你的组件就无法复用了.

你可以引入整个项目或者每个模块单独引用. 之后你需要使用extends:或者 mixins:[]. 然后在 mounted() 中调用 this.renderChart(). 这将创建你的图表实例.

import { Bar } from 'vue-chartjs'

export default {
  extends: Bar,
  mounted () {
    this.renderChart(data, options)
  }
}

:::tip
你可以使用 extends: Bar 或者 mixins: [Bar]
:::

this.renderChart() 方法由 Bar 组件提供, 接收两个对象参数.第一个是你的图表数据, 第二个是配置对象.

在这个文档中查看你需要提供的对象结构 Chart.js docs .

Vue 单文件组件

文档中很多例子都是基于javascript文件 而不是 .vue 文件. 这是因为你大多数只需要<script>.当然在 .vue 文件中你也能用的很好.

Chart.vue

<script>
import { Line } from 'vue-chartjs'

export default {
  extends: Line,
  props: ['chartdata', 'options'],
  mounted () {
    this.renderChart(this.chartdata, this.options)
  }
}
</script>

<style>
</style>

::: danger 不要使用<template>标签
不要在你的 .vue 文件中引入 <template> 标签. Vue 无法 合并模板.如果你添加了一个空的 <template> 标签, Vue 将会从你的主键里获取模板, 而不会从你 extend 中获取, 这将导致页面为空并报错.
:::

更新 Charts

如果你修改了数据集, Chart.js 是不会提供实时更新的. 当然, vue-chartjs 提供了两个 mixins 来实现.

  • reactiveProp
  • reactiveData

这两个mixins其实实现的是相同的功能. 大多数时间你将会使用reactiveProp. 它扩展了图表组件的逻辑, 并自动创建名为 chartDataprops参数, 并为这个参数添加vue watch. 当数据改变, 如果数据在数据集中改变, 它将调用update(); 如果添加了新的数据集, 它将调用renderChart().

reactiveData 创建一个本地的chartData变量, 不是props参数! 以及创建一个对这个变量的 watcher. 如果你需要单一目的的图表, 以及在图表组件中进行API调用的时候, 这将非常有用.

例子

LineChart.js

import { Line, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins

export default {
  extends: Line,
  mixins: [reactiveProp],
  props: ['options'],
  mounted () {
    // this.chartData 在 mixin 创建.
    // 如果你需要替换 options , 请创建本地的 options 对象
    this.renderChart(this.chartData, this.options)
  }
}

RandomChart.vue

<template>
  <div class="small">
    <line-chart :chart-data="datacollection"></line-chart>
    <button @click="fillData()">Randomize</button>
  </div>
</template>

<script>
  import LineChart from './LineChart.js'

  export default {
    components: {
      LineChart
    },
    data () {
      return {
        datacollection: null
      }
    },
    mounted () {
      this.fillData()
    },
    methods: {
      fillData () {
        this.datacollection = {
          labels: [this.getRandomInt(), this.getRandomInt()],
          datasets: [
            {
              label: 'Data One',
              backgroundColor: '#f87979',
              data: [this.getRandomInt(), this.getRandomInt()]
            }, {
              label: 'Data One',
              backgroundColor: '#f87979',
              data: [this.getRandomInt(), this.getRandomInt()]
            }
          ]
        }
      },
      getRandomInt () {
        return Math.floor(Math.random() * (50 - 5 + 1)) + 5
      }
    }
  }
</script>

<style>
  .small {
    max-width: 600px;
    margin:  150px auto;
  }
</style>

::: danger 限制

Caveats
Change-Detection-Caveats
vm.$watch

:::

事件

如果你的数据改变, 响应式的 mixins 将会触发事件. 你能监听他们通过在图表组件上使用 v:on. 下列是可用的事件:

  • chart:render - 如果 mixin 执行完全重绘
  • chart:destroy - 如果 mixin 删除图表对象实例
  • chart:update - 如果 mixin 执行更新而不是重绘
  • labels:update - 如果设置了新的labels
  • xlabels:update 如果设置了新的xLabels
  • ylabels:update - 如果设置了新的yLabels

故障排查

响应式系统, 它当前状态是不健全的. 你将会遇到一些问题, 因为有很多用例和方式来传递你的数据.

Options

options 对象不是响应式的. 所以如果你动态改变图表的配置, 他们将无法被 mixin 识别.

如果你正在使用 mixin , 你需要使用options来传递你的配置. 这是非常重要的, 因为 mixin 将调用 chart.js 的 update() 方法 或者 销毁并渲染一个新的图表. 如果 mixin 渲染一个新的图表, 它将调用this.renderChart(this.chartData, this.options).

但是如果你在mounted()传递你的配置, 它们将直接被遗弃.

::: danger 错误的方式

import { Line, mixins } from 'vue-chartjs'

export default {
  components: { Line }
  mixins: [mixins.reactiveProp],
  mounted () {
    this.renderChart(this.chartData, {responsive: true})
  }
}

:::

::: tip 正确的方式

import { Line, mixins } from 'vue-chartjs'

export default {
  components: { Line }
  mixins: [mixins.reactiveProp],
  mounted () {
    this.renderChart(this.chartData, this.options)
  }
}

:::

自己的监视器

如果你对你的数据进行大量更改(而不是推新的数据), 那么最好的方式是创建自己的 watcher.
你可以自己调用 this.$data._chart.update() 或者 this.renderChart() 来实现, 当然这些完全取决于你自己.

一个简单的监视器将会是这样:

watch: {
  chartData () {
    this.$data._chart.update()
  }
}

例子

使用props的图表

你的目标因该是创建可复用的图表组件. 出于这个目的, 你应该利用 Vue.js 的props 来传递你的配置和图表数据. 这种方式, 图表自己不用关心, 关于提取数据, 只用来展示.

首先, 创建你的组件

import { Line } from 'vue-chartjs'

export default {
  extends: Line,
  props: {
    chartdata: {
      type: Object,
      default: null
    },
    options: {
      type: Object,
      default: null
    }
  },
  mounted () {
    this.renderChart(this.chartdata, this.options)
  }
}

然后, 你可以把你的组件添加到父组件里

<line-chart :chartdata="chartData" :options="chartOptions"/>

图表使用本地数据

你可以直接在你自己的图表组件里处理你的图表数据. 你只需要把它传递到 renderChart().

import { Bar } from 'vue-chartjs'

export default {
  extends: Bar,
  data: () => ({
    chartdata: {
      labels: ['January', 'February'],
      datasets: [
        {
          label: 'Data One',
          backgroundColor: '#f87979',
          data: [40, 20]
        }
      ]
    },
    options: {
      responsive: true,
      maintainAspectRatio: false
    }
  }),

  mounted () {
    this.renderChart(this.chartdata, this.options)
  }
}

Chart使用API的数据

使用API获取数据是一种常见模式. 然而, 这里有一些问题需要记住. 最常见的问题是, 你直接安装你的图表, 将异步API回调的数据传递进去. 这种方法导致的问题是, chart.js 试图去渲染你的图表, 访问图表数据, 但是你的API回调是异步的. 所以你图表在你数据到达前安装.

防止这个问题, 一个 v-if 即可.

创建你的图表组件通过一个数据参数和一个配置参数, 所以我们可以从一个容器组件中传递我们的数据和配置.

Chart.vue

import { Line } from 'vue-chartjs'

export default {
  extends: Line,
  props: {
    chartdata: {
      type: Object,
      default: null
    },
    options: {
      type: Object,
      default: null
    }
  },
  mounted () {
    this.renderChart(this.chartdata, this.options)
  }
}

然后创建一个容器组件, 用来处理你的API回调和vuex连接.
ChartContainer.vue

<template>
  <div class="container">
    <line-chart
      v-if="loaded"
      :chartdata="chartdata"
      :options="options"/>
  </div>
</template>

<script>
import LineChart from './Chart.vue'

export default {
  name: 'LineChartContainer',
  components: { LineChart },
  data: () => ({
    loaded: false,
    chartdata: null
  }),
  async mounted () {
    this.loaded = false
    try {
      const { userlist } = await fetch('/api/userlist')
      this.chartdata = userlist
      this.loaded = true
    } catch (e) {
      console.error(e)
    }
  }
}
</script>

Chart的动态样式

你可以设置 responsive: true 然后传递到 styles 对象, 这被当做内联样式应用于外层div. 这种方式你可以动态改变外层容器的高度和宽度, 这并不是chart.js 的默认行为. 使用计算属性可以很好的完成.

::: warning
你需要设置 position: relative
:::

<template>
  <div>
    <line-chart :styles="myStyles"/>
    <button @click="increase()">Increase height</button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      height: 300
    }
  },
  methods: {
    increase () {
     this.height += 10
    }
  },
  computed: {
    myStyles () {
      return {
        height: `${this.height}px`,
        position: 'relative'
      }
    }
  }
}
</script>

自定义/新的图表

有时候你需要扩展Chart.js默认的图表. 这里有许多例子, 来教你如何扩展和修改默认的图表, 或者创建自己的图表类型.

vue-chartjs, 你可以使用同样的方式来做到这一点

// 1. 引入Chart.js, 你可以使用全局的图表对象
import Chart from 'chart.js'
// 2. 引入 `generateChart()`方法创建vue组件.
import { generateChart } from 'vue-chartjs'

// 3. 扩展一个默认图表
// http://www.chartjs.org/docs/latest/developers/charts.html
Chart.defaults.LineWithLine = Chart.defaults.line;
Chart.controllers.LineWithLine = Chart.controllers.line.extend({ /* 自定义 */})

// 4. 生成 vue-chartjs 组件
// 第一个参数是 图表id, 第二个参数是 图表类型.
const CustomLine = generateChart('custom-line', 'LineWithLine')

// 5. 像使用默认的vue-chartjs图表一样, 扩展自定义组件

export default {
  extends: CustomLine,
  mounted () {
    // ....
  }
}

资源

你可以在这里找到一些资源,比如关于如何使用vue-chartjs的教程

编码参考

Props

这里有一些vue-chartjs提供的基本参数定义. 因为你是 extend 他们的, 所以他们是不可见的, 但是你可以覆盖他们:

参数名 描述
width 图表宽度
height 图表高度
chart-id canvas的id
css-classes css类的字符串
styles css 样式对象
plugins chartjs 插件数组

事件

如果 reactiveData 或者 reactiveProp mixin 被附加, 下面事件将会被调用:

事件 描述
chart:render 如果 mixin 执行完全重绘
chart:destroy 如果 mixin 删除图表对象实例
chart:update 如果 mixin 执行更新而不是重绘
labels:update 如果设置了新的labels
xlabels:update 如果设置了新的xLabels
ylabels:update 如果设置了新的yLabels

全局方法

全局方法需要被引入才能使用.

generateChart

  • 类型: Function
  • 参数: chart-id, chart-type
  • 使用:
import { generateChart } from 'vue-chartjs'
// 第一个参数是 图表id, 第二个参数是 图表类型.
const CustomLine = generateChart('custom-line', 'LineWithLine')

实例方法

实例方法可以在你图表组件内部使用.

generateLegend()

用来生成HTML说明的工具函数.

  • 类型: Function
  • 参数: none
  • 使用:
import { Line } from 'vue-chartjs'

export default {
  extends: Line,
  props: ['datasets', 'options']
  data: () => ({
    htmlLegend: null
  })
  mounted () {
    this.renderChart(this.datasets, this.options)
    this.htmlLegend = this.generateLegend()
  }
}

addPlugin

在 Chart.js 你可以定义全局和内联插件. 全局插件在没有 vue-chartjs也可以工作. 就像这个文档Chart.js docs 描述的.

如果你需要添加内联插件, vue-chartjs 暴露出来了一个工具方法 addPlugin()
你可以在renderChart()方法前调用addPlugin().

  • 类型: Function
  • 参数: Array 插件数组
  • 使用:
mounted () {
  this.addPlugin({
    id: 'my-plugin',
    beforeInit: function (chart) {
      ....
    }
  })
}

renderChart()

创建一个 Chart.js 实例, 并渲染图表

  • 类型: Function
  • 参数: Chart Data, Chart Options
  • 使用:
mounted () {
  this.renderChart({
    labels: ['January', 'February'],
    datasets: [
      {
        label: 'Data One',
        backgroundColor: '#f87979',
        data: [40, 20]
      }
    ]},
    {
      responsive: true
    }
  )
}

Chart.js 对象

你可以在你的图表组件里, 通过 this.$data._chart 访问 Chart.js 对象

Canvas

你可以通过 this.$refs.canvas 访问 canvas

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

推荐阅读更多精彩内容

  • 基于Vue的一些资料 内容 UI组件 开发框架 实用库 服务端 辅助工具 应用实例 Demo示例 element★...
    尝了又尝阅读 1,119评论 0 1
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    小姜先森o0O阅读 9,225评论 0 72
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    柴东啊阅读 15,803评论 2 140
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    你猜_3214阅读 10,967评论 0 118
  • UI组件 element- 饿了么出品的Vue2的web UI工具套件 Vux- 基于Vue和WeUI的组件库 m...
    王喂马_阅读 6,380评论 1 77