Vue3+Element+Echarts 绘制统计图表

php学习交流吧

共 21657字,需浏览 44分钟

 · 2023-05-16

近期有需求要按照小时、月份、季度、年份做数据统计柱状图和折线图

echarts开发文档:

https://echarts.apache.org/handbook/zh/get-started/

首先需要引入echarts.js

      
        
          <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.2/dist/echarts.min.js">
          </script>
        
      
    

效果图:

e739d9ca862b74f23338ca9b06d5148f.webp

柱状图js部分代码:

      
        appConfig.components['views/components/BarHeapChart'] = Vue.defineComponent({
      
      
          // 在 JavaScript 中是 camelCase 的
      
      
          props: {
      
      
            className: {
      
      
              type: String,
      
      
              default: 'chart'
      
      
            },
      
      
            width: {
      
      
              type: String,
      
      
              default: '100%'
      
      
            },
      
      
            height: {
      
      
              type: String,
      
      
              default: '500px'
      
      
            },
      
      
            xAxisData: {
      
      
              type: Array,
      
      
              default: () => {
      
      
                return ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
      
      
              }
      
      
            },
      
      
            seriesData: {
      
      
              type: Array,
      
      
              default: () => {
      
      
                return [{
      
      
      
                  type: 'bar',
      
      
      
                  smooth: true,
      
      
                  data: [820, 932, 901, 934, 1290, 1330, 1320],
      
      
                }]
      
      
              }
      
      
            }
      
      
          },
      
      
          watch: {
      
      
            xAxisData: {
      
      
              deep: true,
      
      
              handler(val) {
      
      
                this.xAxisData = val
      
      
              }
      
      
            },
      
      
            seriesData: {
      
      
              deep: true,
      
      
              handler(val) {
      
      
                this.seriesData = val
      
      
                this.disposeChart()
      
      
                this.initChart()
      
      
              }
      
      
            }
      
      
          },
      
      
        
          
data: function() { return { chart: null } }, mounted: function() { this.$nextTick(() => { this.initChart() }) }, beforeDestroy() { this.disposeChart() },
computed: {
}, methods: { disposeChart() { if (!this.chart) { return } this.chart.dispose() this.chart = null }, initChart() { this.chart = echarts.init(this.$el, 'roma') this.drawChart() }, drawChart() { this.chart.setOption({ tooltip: { trigger: 'axis', axisPointer: { type: 'cross', label: { backgroundColor: '#6a7985' } } }, legend: { left: 'center' }, toolbox: { feature: { saveAsImage: {} } }, grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true }, xAxis: [{ type: 'category', boundaryGap: false, data: this.xAxisData }], yAxis: [{ type: 'value' }], series: this.seriesData }) } }, template: ` <div :class="className" :style="{minHeight:height,width:width}"/> ` })


折线图js部分代码:

      
        appConfig.components['views/components/LineHeapChart'] = Vue.defineComponent({
      
      
          // 在 JavaScript 中是 camelCase 的
      
      
          props: {
      
      
            className: {
      
      
              type: String,
      
      
              default: 'chart'
      
      
            },
      
      
            width: {
      
      
              type: String,
      
      
              default: '100%'
      
      
            },
      
      
            height: {
      
      
              type: String,
      
      
              default: '500px'
      
      
            },
      
      
            xAxisData: {
      
      
              type: Array,
      
      
              default: () => {
      
      
                return ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
      
      
              }
      
      
            },
      
      
            seriesData: {
      
      
              type: Array,
      
      
              default: () => {
      
      
                return [{
      
      
      
                  type: 'line',
      
      
      
                  smooth: true,
      
      
                  data: [820, 932, 901, 934, 1290, 1330, 1320],
      
      
                }]
      
      
              }
      
      
            }
      
      
          },
      
      
          watch: {
      
      
            xAxisData: {
      
      
              deep: true,
      
      
              handler(val) {
      
      
                this.xAxisData = val
      
      
              }
      
      
            },
      
      
            seriesData: {
      
      
              deep: true,
      
      
              handler(val) {
      
      
                this.seriesData = val
      
      
                this.disposeChart()
      
      
                this.initChart()
      
      
              }
      
      
            }
      
      
          },
      
      
        
          
data: function() { return { chart: null } }, mounted: function() { this.$nextTick(() => { this.initChart() }) }, beforeDestroy() { this.disposeChart() },
computed: {
}, methods: { disposeChart() { if (!this.chart) { return } this.chart.dispose() this.chart = null }, initChart() { this.chart = echarts.init(this.$el, 'roma') this.drawChart() }, drawChart() { this.chart.setOption({ tooltip: { trigger: 'axis', axisPointer: { type: 'cross', label: { backgroundColor: '#6a7985' } } }, legend: { left: 'center' }, toolbox: { feature: { saveAsImage: {} } }, grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true }, xAxis: [{ type: 'category', boundaryGap: false, data: this.xAxisData }], yAxis: [{ type: 'value' }], series: this.seriesData }) } }, template: ` <div :class="className" :style="{minHeight:height,width:width}"/> ` })


前端渲染代码:

      
        
          

(function(){ const importComponents = { 'views/components/BarHeapChart':'BarHeapChart', 'views/components/LineHeapChart':'LineHeapChart', }; appConfig.components['views/index'] = autoLoadjs(Object.keys(importComponents)).then(function(){
const components = {} Object.keys(importComponents).map(function(key){ components[importComponents[key]] = appConfig.components[key] })
return Vue.defineComponent({ components: components, data:function() { return { tableData: [], listQuery:{ search_date:'', date_mode:'day' }, } }, mounted:function() { this.initData() }, methods:{ initData:function(){ const that = this //开启table加载效果 this.$network("/admin/index/echarts", this.listQuery,{ completeEvent:function(res){ } }).then(function(res){ var data = res.data || {} that.tableData = data }) }, }, template : ` <el-row :gutter="20"> <el-col :span="21"> <el-form-item name="activeState"> <el-radio-group v-model="listQuery.date_mode" fill="#5a8bff" @change="initData(true)"> <el-radio-button label="day">按天筛选</el-radio-button> <el-radio-button label="week">按周筛选</el-radio-button> <el-radio-button label="month">按月筛选</el-radio-button> <el-radio-button label="month60">按季度筛选</el-radio-button> <el-radio-button label="year">按年筛选</el-radio-button> </el-radio-group> </el-form-item> </el-col>
<el-col :span="21"> <el-form-item name="activeState"> <el-date-picker type="daterange" value-format="YYYY-MM-DD" v-model="listQuery.search_date" @change="initData(true)" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"> </el-date-picker> </el-form-item> </el-col> </el-row> <el-row :gutter="20"> <el-col :span="8"> <el-card class="box-card"> <h3>订单金额</h3> <div> <i class="el-icon-s-shop" style="color: purple"></i> <span>{{tableData.total_money}}</span> </div> </el-card> </el-col> <el-col :span="8"> <el-card class="box-card"> <h3>订单数量</h3> <div> <i class="el-icon-user-solid" style="color: green"></i> <span>{{tableData.total_order}}</span> </div> </el-card> </el-col> <el-col :span="8"> <el-card class="box-card"> <h3>访客</h3> <div> <i class="el-icon-s-flag" style="color: red"></i> <span>{{tableData.user}}</span> </div> </el-card> </el-col> </el-row>

<BarHeapChart ref="BarHeapChart" :xAxisData="tableData.x_axis_data" :seriesData="tableData.series_data"/> <LineHeapChart ref="LineHeapChart" :xAxisData="tableData.x_axis_data" :seriesData="tableData.series_data" /> ` }) })
})()


最后调PHP后端接口获取最新数据:

      
        
          //获取统计信息
        
      
      
            public function echarts()
      
      
        {
      
      
                $input_data = input();
      
      
                list($x_axis_data1, $series_data1) = LocationUserModel::echarts($input_data);
      
      
        
          
$fnc = function($name,$data){ return [ "name"=> $name, "type"=> 'line', "symbolSize"=> 12,
"data"=> $data ]; };
return $this->_resData(1,'获取成功',[ 'x_axis_data'=>$x_axis_data1, 'series_data'=>[$fnc('订单数量',$series_data1)], 'total_order'=>LocationUserModel::where('state','<>',2)->count(), 'total_money'=>LocationUserModel::where('is_pay',1)->where('state','<>',2)->count(), 'user'=>UserModel::count() ]); }


LocationUserModel模型方法:

      
        
          //列表统计
        
      
      
            public static function echarts(array $php_input)
      
      
        {
      
      
                $date_mode = $php_input['date_mode'] ?? 'day';
      
      
                $where = [];
      
      
                $group = 'op_time';
      
      
                $field = ' count(*) as count_num ';
      
      
                if ($date_mode == 'day') { //按小时计算
      
      
                    $where[] = ['create_time', '>=', strtotime(date('Y-m-d'))];
      
      
                    $field .= ' ,FROM_UNIXTIME(create_time,\'%H\') as op_time';
      
      
                } elseif ($date_mode == 'week') {
      
      
                    $where[] = ['create_time', '>=', strtotime(date('Y-m-d')) - 7 * 84600];
      
      
                    $field .= ' ,FROM_UNIXTIME(create_time,\'%Y-%m-%d\') as op_time';
      
      
                } elseif ($date_mode == 'month') {
      
      
                    $field .= ' ,FROM_UNIXTIME(create_time,\'%Y-%m-%d\') as op_time';
      
      
                    $where[] = ['create_time', '>=', strtotime(date('Y-m-d')) - 30 * 84600];
      
      
                } elseif ($date_mode == 'month60') {
      
      
                    $field .= ' ,FROM_UNIXTIME(create_time,\'%Y-%m-%d\') as op_time';
      
      
                    $where[] = ['create_time', '>=', strtotime(date('Y-m-d')) - 60 * 84600];
      
      
                } elseif ($date_mode == 'year') {
      
      
                    $field .= ' ,FROM_UNIXTIME(create_time,\'%Y-%m-%d\') as op_time';
      
      
                    $where[] = ['create_time', '>=', strtotime(date('Y-m-d')) - 365 * 84600];
      
      
                }
      
      
                $date_list = get_op_time($date_mode);
      
      
                $list = [];
      
      
                foreach ($date_list as $vo) {
      
      
                    $list[$vo] = [
      
      
                        'name' => $vo,
      
      
                        'value' => 0
      
      
                    ];
      
      
                }
      
      
        
          
Db::table('location_user')->field($field)->where($where) ->group($group)->select()->each(function ($item) use (&$list, $date_list) { $key = $item['op_time']; $list[$key]['value'] = $item['count_num']; });
return [array_column($list, 'name'), array_column($list, 'value')]; // self::field($field)->where($where)->gourp($group)->select();
}


浏览 83
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报