123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- <template>
- <div :style="{ padding: '0 0 32px 32px' }">
- <h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
- <v-chart :force-fit="true" :height="height" :data="data" :scale="scale" :width="width" :padding="padding" :onClick="handleClick">
- <v-tooltip :show-title="false" :item-tpl="tooltipOpts.itemTpl" />
- <v-legend />
- <v-coord type="rect" direction="LT" />
- <v-pyramid :position="funnelOpts.position" :color="funnelOpts.color" :label="funnelOpts.label" :tooltip="funnelOpts.tooltip" />
- <v-guide v-for="(obj, index) in data"
- type="text"
- :key="index"
- :top="true"
- :position="getPosition(obj)"
- :content="getContent(obj)"
- :vStyle="style"
- />
- </v-chart>
- </div>
- </template>
- <script>
- import { DataSet } from '@antv/data-set'
- import { ChartEventMixins } from './mixins/ChartMixins'
- export default {
- mixins: [ChartEventMixins],
- props: {
- title: {
- type: String,
- default: ''
- },
- height: {
- type: Number,
- default: 254
- },
- width: {
- type: Number,
- default: 254
- },
- field: {
- type: String,
- default: 'count'
- },
- xField: {
- type: String,
- default: 'action'
- },
- dataSource: {
- type: Array,
- default: () => [
- { action: '浏览网站', pv: 50000 },
- { action: '放入购物车', pv: 35000 },
- { action: '生成订单', pv: 25000 },
- { action: '支付订单', pv: 15000 },
- { action: '完成交易', pv: 8000 }
- ]
- }
- },
- data() {
- return {
- padding: [20, '20%', 60, '20%'],
- tooltipOpts: {
- showTitle: false,
- itemTpl: '<li data-index={index} style="margin-bottom:4px;">' +
- '<span style="background-color:{color};" class="g2-tooltip-marker"></span>' +
- '{name}<br/>' +
- '<span style="padding-left: 16px">{name}:{pv}</span><br/>' +
- '<span style="padding-left: 16px">占比:{percent}</span><br/>' +
- '</li>'
- },
- scale: {
- dataKey: 'percent',
- nice: false
- },
- funnelOpts: {
- position: this.xField + '*percent',
- color: [this.xField, ['#0050B3', '#1890FF', '#40A9FF', '#69C0FF', '#BAE7FF']],
- label: [this.xField + '*' + this.field, (action, pv) => {
- return action + ' ' + pv
- }, {
- offset: 35,
- labelLine: {
- lineWidth: 1,
- stroke: 'rgba(0, 0, 0, 0.15)'
- }
- }],
- tooltip: [this.xField + '*' + this.field + '*percent', (action, pv, percent) => ({
- name: action,
- percent: Math.floor(percent * 100) + '%',
- pv: pv
- })]
- },
- style: {
- fill: '#fff',
- fontSize: '12',
- textAlign: 'center',
- shadowBlur: 2,
- shadowColor: 'rgba(0, 0, 0, .45)'
- }
- }
- },
- methods: {
- getPosition: (obj) => {
- return {
- action: obj.action,
- percent: 'median'
- }
- },
- getContent: (obj) => {
- return parseInt(String(obj.percent * 100)) + '%'
- }
- },
- computed: {
- data() {
- const that = this
- const dv = new DataSet.View().source(this.dataSource)
- dv.transform({
- type: 'percent',
- field: this.field,
- dimension: this.xField,
- as: 'percent'
- })
- dv.transform({
- type: 'sort',
- callback(a, b) {
- return b[that.field] - a[that.field]
- }
- })
- return dv.rows
- }
- }
- }
- </script>
|