赞
踩
很多时候web开发也会需要用到统计图,如果单纯靠我们自己那点拙劣的css和js水平设计的话,又耗时间又做得跟史一样,这时候就需要引入别人设计师为我们设计好的动态统计图——echarts
Echarts的官网是:Apache ECharts
跟引入bootstrap、Vue这些一样,你可以选择引入本地的js文件,或者用在线的CDN
本地的文件在本文顶部开头中,自己下载。如果找不到我的资源可以下载这个链接https://registry.npmjs.org/echarts/-/echarts-5.5.0.tgz,解压后找到【dist】文件夹,找到【echarts.js】文件,把它解压到你要用它的同级目录下,然后引入本地js文件到html中
- <!-- 引入刚刚下载的 ECharts 文件 -->
- <script src="echarts.js"></script>
或者不要那么麻烦,直接用在线CDN,我更偏向这种,把这段代码写到你的html文件里
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script>
例如:
- <!-- css部分 -->
- <style>
- .echarts-box {
- width: 600px;
- height: 400px;
- padding: 30px;
- margin: 0 auto;
- border: 1px solid #ccc;
- }
- </style>
-
- <!-- HTML部分 -->
- <body>
- <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
- <div class="echarts-box" id="main"></div>
- </body>
点开【示例】,会看到各种花里胡哨的图,直接选择自己喜欢的点击,样例代码都给你了,直接开始cv
但是它代码提供的只是这个样例的代码,并没有提供我们怎么去创建它并开启它的代码,要我们手动开启,也很简单:
1、echarts.init( )函数是开始创建这个样例的容器,你上面HTML已经写了一个容器了,那么现在echarts需要知道那个容器是用来存放、展示echarts图表的,你只需要用JavaScript绑定这个DOM元素然后传参给echarts.init( )函数就行了
let myChart = echarts.init(document.getElementById('main'));
2、通过【echars容器变量.setOption( )】函数显示图表
.setOption()函数需要往里传入配置数据参数,这个【配置数据参数】就是你刚刚网页上copy的那一堆代码,你可以直接copy到.setOption()里;也可以用一个变量等于你刚刚那一堆配置数据,然后再把变量放进.setOption()里
- // 指定图表的配置项和数据
- //这个案例是柱状图
- let option = {
- title: {
- text: 'ECharts柱状图示例'
- },
- tooltip: {},
- legend: {
- data: ['销量']
- },
- xAxis: {
- data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
- },
- yAxis: {},
- series: [
- {
- name: '销量',
- type: 'bar',
- data: [5, 20, 36, 10, 10, 20]
- }
- ]
- };
- // 使用刚指定的配置项和数据显示图表。
- myChart.setOption(option);
下面代码是两个完整的例子:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <style>
- .echarts-box {
- width: 600px;
- height: 400px;
- padding: 30px;
- margin: 0 auto;
- border: 1px solid #ccc;
- }
- </style>
- </head>
- <body>
- <div class="echarts-box" id="main"></div>
- <div class="echarts-box No2" id="main"></div>
-
- <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script>
- <script type="text/javascript">
- // 基于准备好的dom,初始化echarts实例
- let myChart = echarts.init(document.getElementById('main'));
-
- // 指定图表的配置项和数据
- //这个案例是柱状图
- let option = {
- title: {
- text: 'ECharts柱状图示例'
- },
- tooltip: {},
- legend: {
- data: ['销量']
- },
- xAxis: {
- data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
- },
- yAxis: {},
- series: [
- {
- name: '销量',
- type: 'bar',
- data: [5, 20, 36, 10, 10, 20]
- }
- ]
- };
- // 使用刚指定的配置项和数据显示图表。
- myChart.setOption(option);
-
-
- //这个案例是圆饼图
- let myChart2 = echarts.init(document.querySelector('.No2'))
- let option2 = {
- title: {
- text: '岑梓铭的圆饼图',
- subtext: '靓不靓啊?',
- left: 'center'
- },
- tooltip: {
- trigger: 'item'
- },
- legend: {
- orient: 'vertical',
- left: 'left'
- },
- series: [
- {
- name: 'Access From',
- type: 'pie',
- radius: '50%',
- data: [
- { value: 1048, name: '吃饭' },
- { value: 735, name: '睡觉' },
- { value: 580, name: '玩手机' },
- { value: 484, name: '学习' },
- { value: 300, name: '看美女' }
- ],
- emphasis: {
- itemStyle: {
- shadowBlur: 10,
- shadowOffsetX: 0,
- shadowColor: 'rgba(0, 0, 0, 0.5)'
- }
- }
- }
- ]
- };
- myChart2.setOption(option2)
- </script>
- </body>
- </html>
具体你需要配置什么标题、解释文字、颜色,这些你可以直接在在线示例里修改它的代码,然后慢慢找代码的哪个地方对应图表的哪个地方
具体例子还可以到这个网站去看看:echarts官网 | 中文官网
另外,在Vue中使用echart图表的话,建议刚刚那些代码写在mounted( )函数里,这样的话根据option里的配置数据(或者是绑定了data里的初始数据),当页面刚进入就能看到一个初始的图表样子。
- mounted () {
- let myChart = echarts.init(document.querySelector('#main'))
- myChart.setOption({
- // 大标题
- title: {
- text: '消费账单列表',
- left: 'center'
- },
- // 提示框
- tooltip: {
- trigger: 'item'
- },
- // 图例
- legend: {
- orient: 'vertical',
- left: 'left'
- },
- // 数据项
- series: [
- {
- name: '消费账单',
- type: 'pie',
- radius: '50%', // 半径
- data: [
- { value: 1048, name: '球鞋' },
- { value: 735, name: '防晒霜' }
- ],
- emphasis: {
- itemStyle: {
- shadowBlur: 10,
- shadowOffsetX: 0,
- shadowColor: 'rgba(0, 0, 0, 0.5)'
- }
- }
- }
- ]
- })
- },
那么如果你要动态更新的话,只需要在Vue的methods函数配置项里设置一个函数,在这个函数里再次.setOption( )就可以了动态更新了。
但是这里有一个需要注意的:你在methods的函数里设置.setOption( ),说明你已经离开mounted函数了,那就拿不到【代表echarts图表的容器】了,那怎么setOption呢?记住一点:只要要在Vue里想全局使用某个变量,就把他挂到data里。那么这里也可以把【代表echarts图表的容器】挂到data
上面的例子改一下(数据配置啥的代码省略了,一样的):
- data: {
- //挂载的全局变量
- list: [],
- name: '',
- price: ''
- },
- computed: {
- 某函数 () {
- return 统计结果
- }
- },
- created () {
- //做一些网络数据请求、数据操作
- },
- mounted () {
- //直接一个【this.变量】,甚至都不用在data里设置变量,就可以到处用它了
- this.myChart = echarts.init(document.querySelector('#main'))
- this.myChart.setOption({
- //echarts的数据配置
- })
- },
现在再拿【this.变量】去setOption()就可以更新图表了
- methods: {
- // 更新图表
- // 现在就可以用this.myChart去调用setOption()了
- this.myChart.setOption({
- // 其他项可以不用复制过来,只用设置要修改的数据项就好了
- // 数据项
- series: [
- {
- // 这里也不是一个一个数据写好去配置,而是采用动态配置
- // data: [
- // { value: 1048, name: '球鞋' },
- // { value: 735, name: '防晒霜' }
- // ]
- data: this.list.map(item => ({ value: item.price, name: item.name}))
- //这里先解释一下.map()函数是什么意思
- //.map()函数是遍历数组每个成员,然后return一个经过修改的值,作为遍历到的这个成员的新值
- //item是自定义的,代表遍历到的数组的每一个成员
- //然后()=>箭头函数如果是一个值、一句话、一个表达式,就代表这就是要return的内容
- //例子中:{ value: item.price, name: item.name }就是return这么一个对象值
- //为什么用()包住这个对象?因为对象外层是{},箭头函数会当成这是一个函数体,要用()包起来
-
- //然后为什么要修改list数组的值?
- //因为前面我们把网络数据返回的内容给到了data设的数组list
- //然后我们要去用console.log()检查这些数据有什么内容,哪些有用要,哪些没用不要
- //然后发现echarts需要的data的配置参数只有value和name这两个参数
- //那我们就只提取出list的每一个对象成员的符合value和name这两个参数要的值
- //然后把list的每一个对象成员设置成{ value: xxx, name: xxx }这种形式,就符合echarts示例所需要得到配置参数要求了
- }
- ]
- })
- },
这里先解释一下.map()函数是什么意思
.map()函数是遍历数组每个成员,然后return一个经过修改的值,作为遍历到的这个成员的新值。item是自定义的,代表遍历到的数组的每一个成员
然后()=>箭头函数如果是一个值、一句话、一个表达式,就代表这就是要return的内容
例子中:{ value: item.price, name: item.name }就是return这么一个对象值
为什么用()包住这个对象?因为对象外层是{},箭头函数会当成这是一个函数体,要用()包起来
然后为什么要修改list数组的值?
因为前面我们把网络数据返回的内容给到了data设的数组list,然后我们要去用console.log()检查这些数据有什么内容,哪些有用要,哪些没用不要
然后发现echarts需要的data的配置参数只有value和name这两个参数,那我们就只提取出list的每一个对象成员的符合value和name这两个参数要的值
然后把list的每一个对象成员设置成{ value: xxx, name: xxx }这种形式,就符合echarts示例所需要得到配置参数要求了
兄弟们我解释得很透彻很幸苦,各位好好看,点个赞
另外把整个例子完整代码放这里:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>Document</title>
- <!-- CSS only -->
- <link
- rel="stylesheet"
- href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
- />
- <style>
- .red {
- color: red!important;
- }
- .search {
- width: 300px;
- margin: 20px 0;
- }
- .my-form {
- display: flex;
- margin: 20px 0;
- }
- .my-form input {
- flex: 1;
- margin-right: 20px;
- }
- .table > :not(:first-child) {
- border-top: none;
- }
- .contain {
- display: flex;
- padding: 10px;
- }
- .list-box {
- flex: 1;
- padding: 0 30px;
- }
- .list-box a {
- text-decoration: none;
- }
- .echarts-box {
- width: 600px;
- height: 400px;
- padding: 30px;
- margin: 0 auto;
- border: 1px solid #ccc;
- }
- tfoot {
- font-weight: bold;
- }
- @media screen and (max-width: 1000px) {
- .contain {
- flex-wrap: wrap;
- }
- .list-box {
- width: 100%;
- }
- .echarts-box {
- margin-top: 30px;
- }
- }
- </style>
- </head>
- <body>
- <div id="app">
- <div class="contain">
- <!-- 左侧列表 -->
- <div class="list-box">
-
- <!-- 添加资产 -->
- <form class="my-form">
- <input v-model.trim="name" type="text" class="form-control" placeholder="消费名称" />
- <input v-model.number="price" type="text" class="form-control" placeholder="消费价格" />
- <button @click="add" type="button" class="btn btn-primary">添加账单</button>
- </form>
-
- <table class="table table-hover">
- <thead>
- <tr>
- <th>编号</th>
- <th>消费名称</th>
- <th>消费价格</th>
- <th>操作</th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="(item, index) in list" :key="item.id">
- <td>{{ index + 1 }}</td>
- <td>{{ item.name }}</td>
- <td :class="{ red: item.price > 500 }">{{ item.price.toFixed(2) }}</td>
- <td><a @click="del(item.id)" href="javascript:;">删除</a></td>
- </tr>
- </tbody>
- <tfoot>
- <tr>
- <td colspan="4">消费总计: {{ totalPrice.toFixed(2) }}</td>
- </tr>
- </tfoot>
- </table>
- </div>
-
- <!-- 右侧图表 -->
- <div class="echarts-box" id="main"></div>
- </div>
- </div>
- <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.0/dist/echarts.min.js"></script>
- <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
- <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
- <script>
- /**
- * 接口文档地址:
- * https://www.apifox.cn/apidoc/shared-24459455-ebb1-4fdc-8df8-0aff8dc317a8/api-53371058
- *
- * 功能需求:
- * 1. 基本渲染
- * (1) 立刻发送请求获取数据 created
- * (2) 拿到数据,存到data的响应式数据中
- * (3) 结合数据,进行渲染 v-for
- * (4) 消费统计 => 计算属性
- * 2. 添加功能
- * (1) 收集表单数据 v-model
- * (2) 给添加按钮注册点击事件,发送添加请求
- * (3) 需要重新渲染
- * 3. 删除功能
- * (1) 注册点击事件,传参传 id
- * (2) 根据 id 发送删除请求
- * (3) 需要重新渲染
- * 4. 饼图渲染
- * (1) 初始化一个饼图 echarts.init(dom) mounted钩子实现
- * (2) 根据数据实时更新饼图 echarts.setOption({ ... })
- */
- const app = new Vue({
- el: '#app',
- data: {
- list: [],
- name: '',
- price: ''
- },
- computed: {
- totalPrice () {
- return this.list.reduce((sum, item) => sum + item.price, 0)
- }
- },
- created () {
- // const res = await axios.get('https://applet-base-api-t.itheima.net/bill', {
- // params: {
- // creator: '小黑'
- // }
- // })
- // this.list = res.data.data
-
- this.getList()
- },
- mounted () {
- this.myChart = echarts.init(document.querySelector('#main'))
- this.myChart.setOption({
- // 大标题
- title: {
- text: '消费账单列表',
- left: 'center'
- },
- // 提示框
- tooltip: {
- trigger: 'item'
- },
- // 图例
- legend: {
- orient: 'vertical',
- left: 'left'
- },
- // 数据项
- series: [
- {
- name: '消费账单',
- type: 'pie',
- radius: '50%', // 半径
- data:[
- { value: 1048, name: '球鞋' },
- { value: 735, name: '防晒霜' }
- ],
- emphasis: {
- itemStyle: {
- shadowBlur: 10,
- shadowOffsetX: 0,
- shadowColor: 'rgba(0, 0, 0, 0.5)'
- }
- }
- }
- ]
- })
- },
-
- methods: {
- async getList () {
- const res = await axios.get('https://applet-base-api-t.itheima.net/bill', {
- params: {
- creator: '小黑'
- }
- })
- this.list = res.data.data
- console.log(res.data.data)
- console.log(this.list)
-
- // 更新图表
- this.myChart.setOption({
- // 数据项
- series: [
- {
- // data: [
- // { value: 1048, name: '球鞋' },
- // { value: 735, name: '防晒霜' }
- // ]
- data: this.list.map(item => ({ value: item.price, name: item.name}))
- //这里这么写是因为
- //看echarts的这个示例的源码的配置数据可以知道,在这个配置数据的data这里只能有value和name这两个参数
- //然后我们console.log可以看到我们拿到的对象数据里很乱,什么值都有,但是没有value这个参数名(name刚好有)
- //但是我们打印输出可以注意到,对象里的price值就对应着value要的值,name值对应name要的值
- //那么只是名字不一样,而且还有别的多余的参数,那就把获取到对象数据的list数组修改一下里面的内容
- //用map函数,item是自定义的,代表遍历到数组的每一个成员,那么item.price不就是这个对象成员的price项吗
- //这样一来list数组每个对象成员就变成{ value: xxx, name: xxx }这种形式了,就符合echarts示例所需要得到配置参数要求了
- }
- ]
- })
- },
- async add () {
- console.log(this.list)
- if (!this.name) {
- alert('请输入消费名称')
- return
- }
- if (typeof this.price !== 'number') {
- alert('请输入正确的消费价格')
- return
- }
-
- // 发送添加请求
- const res = await axios.post('https://applet-base-api-t.itheima.net/bill', {
- creator: '小黑',
- name: this.name,
- price: this.price
- })
- // 重新渲染一次
- this.getList()
-
- this.name = ''
- this.price = ''
- },
- async del (id) {
- // 根据 id 发送删除请求
- const res = await axios.delete(`https://applet-base-api-t.itheima.net/bill/${id}`)
- // 重新渲染
- this.getList()
- }
- }
- })
- </script>
- </body>
- </html>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。