Vue3+Element+Echarts 绘制统计图表

共 21657字,需浏览 44分钟

 ·

2023-05-16 11:20



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




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();








}















浏览 202
点赞
评论
收藏
分享

手机扫一扫分享

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

手机扫一扫分享

分享
举报