diff --git a/package.json b/package.json index 8fee601..95e6209 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "build": "node build/build.js" }, "dependencies": { + "moment": "^2.22.2", "viser-vue": "^2.2.5", "vue": "^2.5.2", "vue-antd-ui": "^0.7.0", @@ -54,6 +55,8 @@ "html-webpack-plugin": "^2.30.1", "jest": "^22.0.4", "jest-serializer-vue": "^0.3.0", + "less": "^3.7.1", + "less-loader": "^4.1.0", "nightwatch": "^0.9.12", "node-notifier": "^5.1.2", "optimize-css-assets-webpack-plugin": "^3.2.0", diff --git a/src/components/chart/MiniArea.vue b/src/components/chart/MiniArea.vue new file mode 100644 index 0000000..ede09fd --- /dev/null +++ b/src/components/chart/MiniArea.vue @@ -0,0 +1,67 @@ +<template> + <div class="mini-chart"> + <div class="chart-content" :style="{height: 46}"> + <v-chart :force-fit="true" :height="height" :data="data" :padding="[36, 5, 18, 5]"> + <v-tooltip /> + <v-smooth-area position="x*y" /> + </v-chart> + </div> + </div> +</template> + +<script> +import moment from 'moment' + +const data = [] +const beginDay = new Date().getTime() + +const fakeY = [7, 5, 4, 2, 4, 7, 5, 6, 5, 9, 6, 3, 1, 5, 3, 6, 5] +for (let i = 0; i < fakeY.length; i += 1) { + data.push({ + x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'), + y: fakeY[i] + }) +} + +const tooltip = [ + 'x*y', + (x, y) => ({ + name: x, + value: y + }) +] + +const scale = [{ + dataKey: 'x', + min: 2 +}, { + dataKey: 'y', + title: '时间', + min: 1, + max: 22 +}] + +export default { + name: 'MiniArea', + data () { + return { + data, + scale, + tooltip, + height: 100 + } + } +} +</script> + +<style scoped> + .mini-chart { + position: relative; + width: 100% + } + .mini-chart .chart-content{ + position: absolute; + bottom: -28px; + width: 100%; + } +</style> diff --git a/src/components/chart/MiniBar.vue b/src/components/chart/MiniBar.vue new file mode 100644 index 0000000..21cd93c --- /dev/null +++ b/src/components/chart/MiniBar.vue @@ -0,0 +1,59 @@ +<template> + <div class="mini-chart"> + <div class="chart-content" :style="{height: 46}"> + <v-chart :force-fit="true" :height="height" :data="data" :padding="[36, 5, 18, 5]"> + <v-tooltip /> + <v-bar position="x*y" /> + </v-chart> + </div> + </div> +</template> + +<script> +import moment from 'moment' + +const data = [] +const beginDay = new Date().getTime() + +const fakeY = [7, 5, 4, 2, 4, 7, 5, 6, 5, 9, 6, 3, 1, 5, 3, 6, 5] +for (let i = 0; i < fakeY.length; i += 1) { + data.push({ + x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'), + y: fakeY[i] + }) +} + +const tooltip = [ + 'x*y', + (x, y) => ({ + name: x, + value: y + }) +] + +const scale = [{ + dataKey: 'x', + min: 2 +}, { + dataKey: 'y', + title: '时间', + min: 1, + max: 22 +}] + +export default { + name: 'MiniBar', + data () { + return { + data, + scale, + tooltip, + height: 100 + } + } +} +</script> + +<style lang="less" scoped> +@import "index.less"; +</style> diff --git a/src/components/chart/MiniChart.vue b/src/components/chart/MiniChart.vue deleted file mode 100644 index 9b93364..0000000 --- a/src/components/chart/MiniChart.vue +++ /dev/null @@ -1,51 +0,0 @@ -<template> - <div> - <v-chart :forceFit="true" :height="height" :data="data" :scale="scale"> - <v-tooltip /> - <v-axis /> - <v-smooth-area position="time*value" /> - </v-chart> - </div> -</template> - -<script> -import 'viser-vue' - -const data = [ - { time: 0, value: 23620 }, - { time: 2, value: 16100 }, - { time: 4, value: 15900 }, - { time: 6, value: 17409 }, - { time: 8, value: 17000 }, - { time: 10, value: 31056 }, - { time: 12, value: 31982 }, - { time: 14, value: 32040 }, - { time: 16, value: 33233 }, - { time: 18, value: 33233 }, - { time: 20, value: 33233 }, - { time: 22, value: 33233 } -] - -const scale = [{ - dataKey: 'value', - min: 10000 -}, { - dataKey: 'year', - min: 0, - max: 1 -}] -export default { - name: 'MiniChart', - data () { - return { - data, - scale, - height: 400 - } - } -} -</script> - -<style scoped> - -</style> diff --git a/src/components/chart/MiniProgress.vue b/src/components/chart/MiniProgress.vue new file mode 100644 index 0000000..d15a3eb --- /dev/null +++ b/src/components/chart/MiniProgress.vue @@ -0,0 +1,58 @@ +<template> + <div class="mini-progress"> + <a-tooltip :title="'目标值:' + target + '%'"> + <div class="target" :style="{left: target + '%'}"> + <span :style="{backgroundColor: color}" /> + <span :style="{backgroundColor: color}" /> + </div> + </a-tooltip> + <div class="wrap"> + <div class="progress" :style="{backgroundColor: color, width: percent + '%', height: height}" /> + </div> + </div> +</template> + +<script> +import ATooltip from 'vue-antd-ui/es/tooltip/Tooltip' +export default { + name: 'MiniProgress', + components: {ATooltip}, + props: ['target', 'color', 'percent', 'height'] +} +</script> + +<style lang="less" scoped> + .mini-progress { + padding: 5px 0; + position: relative; + width: 100%; + .wrap { + background-color: #f5f5f5; + position: relative; + } + .progress { + transition: all 0.4s cubic-bezier(0.08, 0.82, 0.17, 1) 0s; + border-radius: 1px 0 0 1px; + background-color: #13C2C2; + width: 0; + height: 100%; + } + .target { + position: absolute; + top: 0; + bottom: 0; + span { + border-radius: 100px; + position: absolute; + top: 0; + left: 0; + height: 4px; + width: 2px; + } + span:last-child { + top: auto; + bottom: 0; + } + } + } +</style> diff --git a/src/components/chart/index.less b/src/components/chart/index.less new file mode 100644 index 0000000..1a75597 --- /dev/null +++ b/src/components/chart/index.less @@ -0,0 +1,9 @@ +.mini-chart{ + position: relative; + width: 100%; + .chart-content{ + position: absolute; + bottom: -28px; + width: 100%; + } +} diff --git a/src/components/dashboard/ChartCard.vue b/src/components/dashboard/ChartCard.vue index 1a2c902..1c869e0 100644 --- a/src/components/dashboard/ChartCard.vue +++ b/src/components/dashboard/ChartCard.vue @@ -7,10 +7,12 @@ <slot name="action"></slot> </span> </div> - <div class="total"><span>¥ 1358.34</span></div> + <div class="total"><span>{{total}}</span></div> </div> <div class="chart-card-content"> - <slot></slot> + <div class="content-fix"> + <slot></slot> + </div> </div> <div class="chart-card-footer"> <slot name="footer"></slot> @@ -23,7 +25,7 @@ import ACard from 'vue-antd-ui/es/card/Card' export default { name: 'ChartCard', components: {ACard}, - props: ['title'] + props: ['title', 'total'] } </script> @@ -67,6 +69,13 @@ export default { .chart-card-content{ margin-bottom: 12px; position: relative; + height: 46px; + width: 100%; + } + .chart-card-content .content-fix{ + position: absolute; + left: 0; + bottom: 0; width: 100%; } </style> diff --git a/src/components/dashboard/Dashboard.vue b/src/components/dashboard/Dashboard.vue index ccdfa22..3f6adc3 100644 --- a/src/components/dashboard/Dashboard.vue +++ b/src/components/dashboard/Dashboard.vue @@ -2,7 +2,7 @@ <div> <a-row style="margin: -12px"> <a-col :sm="24" :md="12" :xl="6" style="padding: 12px 12px 24px;"> - <chart-card title="总销售额"> + <chart-card title="总销售额" total="¥ 189,345"> <a-tooltip title="指标说明" slot="action"> <a-icon type="info-circle-o" /> </a-tooltip> @@ -22,52 +22,34 @@ </chart-card> </a-col> <a-col :sm="24" :md="12" :xl="6" style="padding: 12px 12px 24px;"> - <chart-card title="总销售额"> + <chart-card title="总销售额" total="¥ 189,345"> <a-tooltip title="指标说明" slot="action"> <a-icon type="info-circle-o" /> </a-tooltip> <div> - <mini-chart /> + <mini-area /> </div> <div slot="footer">日均销售额 <span>¥ 234.56</span></div> </chart-card> </a-col> <a-col :sm="24" :md="12" :xl="6" style="padding: 12px 12px 24px;"> - <chart-card title="总销售额"> + <chart-card title="总销售额" total="¥ 189,345"> <a-tooltip title="指标说明" slot="action"> <a-icon type="info-circle-o" /> </a-tooltip> <div> - <div style="display: inline-block; font-size: 14px; line-height: 22px; margin-right: 16px"> - 同周比 - <span>12%</span> - <span style="color: #f5222d; font-size: 12px"><a-icon type="caret-up" /></span> - </div> - <div style="display: inline-block; font-size: 14px; line-height: 22px;"> - 日环比 - <span>11%</span> - <span style="color: #52c41a; font-size: 12px"><a-icon type="caret-down" /></span> - </div> + <mini-bar /> </div> <div slot="footer">日均销售额 <span>¥ 234.56</span></div> </chart-card> </a-col> <a-col :sm="24" :md="12" :xl="6" style="padding: 12px 12px 24px;"> - <chart-card title="总销售额"> + <chart-card title="营销活动说明" total="73%"> <a-tooltip title="指标说明" slot="action"> <a-icon type="info-circle-o" /> </a-tooltip> <div> - <div style="display: inline-block; font-size: 14px; line-height: 22px; margin-right: 16px"> - 同周比 - <span>12%</span> - <span style="color: #f5222d; font-size: 12px"><a-icon type="caret-up" /></span> - </div> - <div style="display: inline-block; font-size: 14px; line-height: 22px;"> - 日环比 - <span>11%</span> - <span style="color: #52c41a; font-size: 12px"><a-icon type="caret-down" /></span> - </div> + <mini-progress target="90" percent="78" color="#13C2C2" height="8px"/> </div> <div slot="footer">日均销售额 <span>¥ 234.56</span></div> </chart-card> @@ -83,10 +65,12 @@ import ACard from 'vue-antd-ui/es/card/Card' import ChartCard from './ChartCard' import ATooltip from 'vue-antd-ui/es/tooltip/Tooltip' import AIcon from 'vue-antd-ui/es/icon/icon' -import MiniChart from '../chart/MiniChart' +import MiniArea from '../chart/MiniArea' +import MiniBar from '../chart/MiniBar' +import MiniProgress from '../chart/MiniProgress' export default { name: 'dashboard', - components: {MiniChart, AIcon, ATooltip, ChartCard, ACard, ARow, ACol} + components: {MiniProgress, MiniBar, MiniArea, AIcon, ATooltip, ChartCard, ACard, ARow, ACol} } </script> diff --git a/src/router/index.js b/src/router/index.js index a68b8ec..10321a9 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,7 +1,7 @@ import Vue from 'vue' import Router from 'vue-router' import Dashboard from '@/components/dashboard/Dashboard' -import MiniChart from '@/components/chart/MiniChart' +import MiniArea from '@/components/chart/MiniArea' Vue.use(Router) @@ -20,7 +20,7 @@ export default new Router({ { path: '/chart', name: 'chart', - component: MiniChart + component: MiniArea } ] }) diff --git a/yarn.lock b/yarn.lock index f256ef2..dfb0308 100644 --- a/yarn.lock +++ b/yarn.lock @@ -413,6 +413,10 @@ arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "http://registry.npm.taobao.org/arrify/download/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" +asap@~2.0.3: + version "2.0.6" + resolved "http://registry.npm.taobao.org/asap/download/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + asn1.js@^4.0.0: version "4.10.1" resolved "http://registry.npm.taobao.org/asn1.js/download/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" @@ -1695,7 +1699,7 @@ cliui@^4.0.0: strip-ansi "^4.0.0" wrap-ansi "^2.0.0" -clone@2.x: +clone@2.x, clone@^2.1.1: version "2.1.1" resolved "http://registry.npm.taobao.org/clone/download/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" @@ -2581,7 +2585,7 @@ entities@~1.1.1: version "1.1.1" resolved "http://registry.npm.taobao.org/entities/download/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0" -errno@^0.1.3, errno@~0.1.7: +errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "http://registry.npm.taobao.org/errno/download/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" dependencies: @@ -3804,6 +3808,10 @@ ignore@^3.3.3, ignore@^3.3.5, ignore@^3.3.6: version "3.3.10" resolved "http://registry.npm.taobao.org/ignore/download/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" +image-size@~0.5.0: + version "0.5.5" + resolved "http://registry.npm.taobao.org/image-size/download/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" + import-cwd@^2.0.0: version "2.1.0" resolved "http://registry.npm.taobao.org/import-cwd/download/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" @@ -4718,6 +4726,27 @@ left-pad@^1.2.0: version "1.3.0" resolved "http://registry.npm.taobao.org/left-pad/download/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" +less-loader@^4.1.0: + version "4.1.0" + resolved "http://registry.npm.taobao.org/less-loader/download/less-loader-4.1.0.tgz#2c1352c5b09a4f84101490274fd51674de41363e" + dependencies: + clone "^2.1.1" + loader-utils "^1.1.0" + pify "^3.0.0" + +less@^3.7.1: + version "3.7.1" + resolved "http://registry.npm.taobao.org/less/download/less-3.7.1.tgz#192e9dcef456ba3181a4e8d78a200f72a75e5c30" + optionalDependencies: + errno "^0.1.1" + graceful-fs "^4.1.2" + image-size "~0.5.0" + mime "^1.4.1" + mkdirp "^0.5.0" + promise "^7.1.1" + request "^2.83.0" + source-map "~0.6.0" + leven@^2.1.0: version "2.1.0" resolved "http://registry.npm.taobao.org/leven/download/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" @@ -5229,7 +5258,7 @@ mocha-nightwatch@3.2.2: mkdirp "0.5.1" supports-color "3.1.2" -moment@^2.21.0: +moment@^2.21.0, moment@^2.22.2: version "2.22.2" resolved "http://registry.npm.taobao.org/moment/download/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" @@ -6254,6 +6283,12 @@ promise-inflight@^1.0.1: version "1.0.1" resolved "http://registry.npm.taobao.org/promise-inflight/download/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" +promise@^7.1.1: + version "7.3.1" + resolved "http://registry.npm.taobao.org/promise/download/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + dependencies: + asap "~2.0.3" + proto-list@~1.2.1: version "1.2.4" resolved "http://registry.npm.taobao.org/proto-list/download/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" @@ -7122,7 +7157,7 @@ source-map@^0.4.4: dependencies: amdefine ">=0.0.4" -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: version "0.6.1" resolved "http://registry.npm.taobao.org/source-map/download/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"