Vue.js
ItIron2020
昨天我们完成了专案的基本建置并建立一个简单的chart做为暖身练习,今天我们要接续chart的实作,从资料处理一直到呈现图表,过程其实相当的简单,甚至称不上与vue有太大的关系XD 放轻松跟我来吧~! gogogo~!
从昨天的LineChart示范我们知道要建立图表必须将资料以阵列的方式传进去,每个图表都需要
两个阵列阵列帮忙,我们最终需要产出六个图表,由於日期会是共用的,所以最终我们需要六个变数储存六组阵列,分别是
arrPositive: [],
arrHoptialized: [],
arrInIcu: [],
arrOnVentilators: [],
arrRecovered: [],
arrDeaths: []
我们首先要做的就是迭代我们利用axios拿到的资料,将我们所需的资料推进对应的阵列中! 在App.vue中,请你先引入dayjs
import dayjs from 'dayjs'
接着将data的部分新增以下的属性
data() {
return {
arrPositive: [],
arrHoptialized: [],
arrInIcu: [],
arrOnVentilators: [],
arrRecovered: [],
arrDeaths: [],
}
}
并修改created的部分
async created() {
// 利用解构的方式取出axios拿到的data
let { data } = await axios.get(
'https://api.covidtracking.com/v1/us/daily.json'
)
// 只取最近一个月的资料
data = data.slice(0, 30)
// 迭代阵列中的每个元素
data.forEach((item) => {
// 利用dayjs将原本的20201010改为2020/10/10
const date = dayjs(`${item.date}`).format('YYYY/MM/DD')
// 利用解构的方式取出data内我们需要的值
const {
positive,
hospitalizedCurrently,
inIcuCurrently,
recovered,
onVentilatorCurrently,
death,
} = item
// 将值推进对应的阵列,每一个值都需要对应一个日期,所以要以物件的方式传入
this.arrPositive.push({ date, total: positive })
this.arrHoptialized.push({ date, total: hospitalizedCurrently })
this.arrDeaths.push({ date, total: death })
this.arrRecovered.push({ date, total: recovered })
this.arrOnVentilators.push({ date, total: onVentilatorCurrently })
this.arrInIcu.push({ date, total: inIcuCurrently })
})
},
打开我们的vue-devtool检查一下取得的资料,很好! 一切都如同我们所想
现在我们已经有可用的资料了,马上就先来打造确诊人数的图表吧! 我们需要在App.vue将我们整理好的资料传入LineChart组件,因此我们要先回到LineChart组件做一些props的设定,我们要传入的属性有
请你将LineChart的内容改为以下
<script>
import { Line } from 'vue-chartjs'
export default {
extends: Line,
// 加入基本的资料验证
props: {
label: {
type: String,
},
chartData: {
type: Array,
},
options: {
type: Object,
},
chartColorOptions: {
type: Object,
},
},
mounted() {
// 从传入的资料中取出数字与日期,并将其反转(因为我们拿到的是最新到最旧的资料)
const dates = this.chartData.map((d) => d.date).reverse()
const totals = this.chartData.map((d) => d.total).reverse()
this.renderChart(
{
labels: dates,
datasets: [
{
label: this.label,
data: totals,
...this.chartColorOptions
},
],
},
this.options
)
},
}
</script>
处理完後我们回到App.vue,我们先在data内加入图表选项,我们希望图表响应式、根据画面变化大小,更多的设定你一样可以在官方文件中找到!
data() {
return {
arrPositive: [],
arrHoptialized: [],
arrInIcu: [],
arrOnVentilators: [],
arrRecovered: [],
arrDeaths: [],
chartOptions: { // 新增这里
responsive: true,
maintainAspectRatio: false,
},
}
},
接着我们改写一下我们的template,主要有着以下的改动
有关於vuetify的组件使用,都可以在官方文件上找到对应的说明,我这边就不赘述罗!
<template>
<v-app>
<v-main>
<v-container>
<v-card>
<v-container>
<h1>COVID-19 Tracking Dashboard</h1>
<v-row v-if="arrPositive.length">
<v-col cols="12">
<LineChart
label="Positive"
:chartData="arrPositive"
:options="chartOptions"
:chartColorOptions="{
borderColor: '#EF5350',
backgroundColor: 'rgba(255, 56, 96, 0.1)',
}"
/>
</v-col>
</v-row>
</v-container>
</v-card>
</v-container>
</v-main>
</v-app>
</template>
顺利的话你就会看到以下的画面,我们真的弄好第一个图表罗!
其他的图表你自然可以如法炮制,直接复制6组一模一样的程序码,再修改传入的资料即可
<v-row v-if="arrPositive.length">
<v-col cols="12">
<h2>{{ chartData.label }}</h2>
<LineChart
:chartData="chartData.data"
:options="chartOptions"
:label="chartData.label"
:chartColorOptions="chartData.chartColorOptions"
/>
</v-col>
</v-row>
这样的东西复制贴上六次也是可以的!
不过做为一个文明人,DRY(don't repeat yourself)是个我们崇尚的基本原则! 当然要想想更好的方式来处理! 我们需要将所有要印出的资料整理成一个阵列,这个阵列会包含
这样最後我们只要透过一个v-for就能印出所有图表罗!
请你在computed的部分增加一个renderData的属性,并写入以下的内容,对照着注解看我想会比较清楚我在干什麽~!
computed: {
renderData() {
// 利用解构的方式从this中取出我们要用到的所有阵列
const {
arrPositive,
arrHoptialized,
arrInIcu,
arrOnVentilators,
arrRecovered,
arrDeaths,
} = this
// 建立所有的labels
const labels = [
'Positive',
'Hoptialized',
'InIcu',
'OnVentilators',
'Recovered',
'Deaths',
]
// 将所有要输出的阵列整理为一个,做为最终迭代的对象
const displayedDataArr = [
arrPositive,
arrHoptialized,
arrInIcu,
arrOnVentilators,
arrRecovered,
arrDeaths,
]
// 设置每个图表的背景与边界颜色
const chartColorOptions = [
{
borderColor: '#EF5350',
backgroundColor: 'rgba(255, 56, 96, 0.1)',
},
{
borderColor: '#FFF176',
backgroundColor: 'rgba(191, 182, 63, 0.1)',
},
{
borderColor: '#FFB74D',
backgroundColor: 'rgba(239, 109, 9, 0.1)',
},
{
borderColor: '#B3E5FC',
backgroundColor: 'rgba(9, 140, 239, 0.1)',
},
{
borderColor: '#00E676',
backgroundColor: 'rgba(11, 227, 47, 0.1)',
},
{
borderColor: '#E30B86',
backgroundColor: 'rgba(239, 9, 140, 0.1)',
},
]
// 最终整理成一个阵列,每一个元素都包含标签名称、资料以及图表颜色的设定
return displayedDataArr.map((data, index) => ({
label: labels[index],
data,
chartColorOptions: chartColorOptions[index],
}))
},
},
资料处理好後我们回到template的地方,做出以下的修改
<template>
<v-app>
<v-main>
<v-container>
<v-card>
<v-container>
<h1>COVID-19 Tracking Dashboard</h1>
<v-row v-if="arrPositive.length"> // 修改以下的部分
<v-col
cols="12"
v-for="chartData in renderData"
:key="chartData.id"
>
<LineChart
:label="chartData.label"
:chartData="chartData.data"
:options="chartOptions"
:chartColorOptions="chartData.chartColorOptions"
/>
</v-col>
</v-row>
</v-container>
</v-card>
</v-container>
</v-main>
</v-app>
</template>
很好! 画面如我们预期的一样,有着6个不同颜色、内容的图表罗!
今天我们成功的整理了利用axios取得的资料,并透过props传递给子层的LineChart让它能正确显示我们要的资料,最後则藉由新建立一个computed属性进行v-for迭代,避免我们做重复的复制贴上~! 内容稍微多了一点,其中有些逻辑要配合注解去观看会比较好懂! 基本上我们的应用程序已经有着该有的功能,明天我们只要做最後的一点点优化就可以上架罗! 那就明天见吧!
此文章同步发布於个人部落格,有兴趣的大大也可以来参观一下:D
>>: [DAY 27] 章节3-7: 对立的鸡群们- k-means(k平均分类演算法) (1/2)
前言 上一篇我们讨论DDD的战术设计,它建议引用各种设计模式,提高生产力,因此接下来,就来介绍各种设...
天亮了 昨晚是平安夜 关於迷雾森林故事 苏醒 在发牌之前我们先稍微小小调整一下房间的介面 我对你 想...
稍早介绍了书上以及网路上的远程控制的方法 可是就是没有实际操作 今天就试用了XRDP 这个只要用远端...
角色情境 小明同时学会输入指令操作着终端机、 以及透过滑鼠操作着图像化介面的 Sourcetree ...
今天来介绍一下渗透测试常用的环境与工具,正所谓工欲善其事,必先利其器。准备好自己熟悉、习惯的作业系统...