123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902 |
- app.controller('dashboardCtrl', ['$scope', '$http', '$timeout', '$interval', 'toaster', 'chartOptions', function ($scope, $http, $timeout, $interval, toaster, chartOptions) {
- particlesJS.load('particles-js', '/1.0/vendor/libs/particles.json', function () {
- });
- //每4个字自动换行
- function autoBreak(str) {
- var lineNumber = 4;
- var w = $(window).width()
- if (w <= 1366) {
- lineNumber = 3
- } else if (w <= 1920) {
- lineNumber = 4
- } else if (w <= 4096) {
- lineNumber = 8
- }
- var newStr = '';
- for (var index = 0; index < str.length; index++) {
- var item = str[index]
- newStr = newStr + item
- if ((index + 1) % lineNumber === 0) {
- newStr = newStr + '\n'
- }
- }
- return newStr
- }
- /*******以下为echarts*********/
- var devChartPanelMap;
- var leftChart1;
- var leftChart2;
- var leftChart3;
- var rightChart1;
- var rightChart2;
- var rightChart3;
- var bottomChart;
- $timeout(function () {
- devChartPanelMap = echarts.init(document.getElementById('devChartPanelMap'));
- leftChart1 = echarts.init(document.getElementById('leftChart1'));
- leftChart2 = echarts.init(document.getElementById('leftChart2'));
- leftChart3 = echarts.init(document.getElementById('leftChart3'));
- rightChart1 = echarts.init(document.getElementById('rightChart1'));
- rightChart2 = echarts.init(document.getElementById('rightChart2'));
- rightChart3 = echarts.init(document.getElementById('rightChart3'));
- bottomChart = echarts.init(document.getElementById('bottomChart'));
- }, 1);
- $scope.chartHasLoad = false
- $scope.loadAllChart = function () {
- loadChartData();
- $scope.chartHasLoad = true
- }
- function resizeChart() {
- clearTimeout(timer);
- // resize有尺寸改变完后会有一定的延迟,会导致echarts提前渲染,依然是按照原来的尺寸渲染
- timer = setTimeout(function () {
- devChartPanelMap && devChartPanelMap.resize();
- leftChart1 && leftChart1.resize();
- leftChart2 && leftChart2.resize();
- leftChart3.resize();
- rightChart1.resize();
- rightChart2.resize();
- rightChart3.resize();
- bottomChart.resize();
- }, 300);
- }
- $scope.showData = {
- devBusy: 0,
- devOnline: 0,
- devOffline: 0,
- unregistered: 0
- };
- $interval(function () {
- setMapTime();
- }, 1000);
- function setMapTime() {
- $scope.showData.date = moment().format("YYYY年MM月DD日")
- $scope.showData.week = moment().format('dddd')
- $scope.showData.time = moment().format("HH:mm:ss")
- }
- setMapTime();
- var timer = null;
- //resize事件绑定
- $(window).off("resize.devChart").on("resize.devChart", function () {
- resizeChart();
- });
- var colorStopList = {
- blue: ['#57FFE0', '#3469E2'],
- red: ['#FF7671', '#A14AFF'],
- yellow: ['#FFEA4F', '#F89212'],
- green: ['#61E0B1', '#00B25E'],
- gray: ['#fff', '#cfcfcf'],
- purple: ['#D3B5DF', '#8865A5'],
- }
- function getColorStop(key) {
- return {
- colorStops: [{
- offset: 0,
- color: colorStopList[key][0] // 0% 处的颜色
- }, {
- offset: 1,
- color: colorStopList[key][1] // 100% 处的颜色
- }]
- }
- }
- $scope.optionConfig = {
- //坐标系的公共风格
- getLineOptionsForMap: function (xData, textBreak) {
- var option = {
- tooltip: {
- trigger: 'axis',
- axisPointer: {
- lineStyle: {
- color: '#108EE9',
- width: .3,
- }
- }
- },
- grid: {
- x: 52,
- x2: 15,
- y: 30,
- y2: textBreak ? 32 : 28,// 自动换行的X坐标需要展示2行,空间要多一点
- },
- xAxis: [
- {
- type: 'category',
- axisLabel: {
- textStyle: {
- color: "#fff",
- fontSize: "12px"
- }
- },
- axisTick: {
- show: false,
- },
- axisLine: {
- show: false,
- },
- data: xData.map(function (str) {
- if (textBreak) {
- return autoBreak(str)
- } else {
- return str
- }
- })
- }
- ],
- yAxis: [
- {
- type: 'value',
- axisLabel: {
- textStyle: {
- color: "#fff",
- fontSize: "12px"
- }
- },
- axisTick: {
- show: false,
- },
- axisLine: {
- show: false,
- },
- splitLine: {
- show: false,
- },
- },
- ],
- series: []
- };
- return option;
- },
- // pie的公共item风格
- getPieItemStyle: function () {
- var opt = {
- normal: {
- label: {
- show: true,
- position: 'outside',
- color: '#ddd',
- formatter: function (params) {
- return params.name + ':' + params.value;
- },
- rich: {
- white: {
- color: '#ddd',
- align: 'center',
- padding: [3, 0]
- }
- }
- },
- labelLine: {
- length: 8,
- length2: 12,
- show: true,
- }
- }
- };
- return opt
- },
- // 设置公告的 pictorialBar风格
- setPictorialBarStyle: function (option, yData, hasPercent) {
- var myColor = this.getColorList();
- if (!hasPercent) {
- myColor.reverse();
- }
- option.tooltip.formatter = function (params) {
- var param = params[0];
- var name = param.name.replace(/[\n]/g, '');//去掉换行符号
- var span = '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:' + param.color + ';"></span>';
- if (hasPercent) {
- return span + name + ":占比" + param.value + "%"
- } else {
- return span + name + ":" + param.value
- }
- };
- option.series.push({
- name: '消费次数',
- type: 'pictorialBar',
- barCategoryGap: '20%',
- // 可以在线测试 symbol,http://www.runoob.com/try/try.php?filename=trysvg_path2
- // 稍尖:M200 200 c20 -10,80 -40, 85 -180c5 140,65 170,85 180l-170 0Z
- // 很尖:M200 200 c50 -10,80 -40, 85 -180c5 140,35 170,85 180l-170 0Z
- symbol: 'path://M200 200 c20 -10,80 -40, 85 -180c5 140,65 170,85 180l-170 0Z',
- label: {
- normal: {
- show: true,
- position: 'top',
- formatter: function (param) {
- if (hasPercent) {
- return param.value + "%"
- } else {
- return param.value
- }
- },
- textStyle: {
- fontSize: '12',
- color: '#fff'
- }
- }
- },
- itemStyle: {
- normal: {
- color: function (params) {
- var num = myColor.length;
- return myColor[params.dataIndex % num]
- },
- }
- },
- data: yData,
- });
- },
- // 颜色列表
- getColorList: function () {
- var myColor = ['#f845f1', '#ad46f3', '#5045f6', '#4777f5', '#44aff0', '#45dbf7', '#f6d54a', '#f69846', '#ff4343'];
- return myColor;
- },
- // 由于早期的消费可能没有数据,需要给源数据,需要补齐 0,否则折现的时间轴和数据对应错误;
- fixData: function (list) {
- // 找到所有key
- var allConsumKey = {};
- for (var index in list) {
- var item = list[index];
- var list2 = item.items;
- for (var index2 in list2) {
- var item2 = list2[index2];
- var name = item2.name;
- allConsumKey[name] = name;
- }
- }
- //修复该条数据。 这里只是多循环一次,性能问题不大。
- for (var index in list) {
- var item = list[index];
- if (!item.items) {
- item.items = []
- }
- var list2 = item.items;
- for (var key in allConsumKey) {
- var hasKeyFlag = false;
- for (var index2 in list2) {
- var item2 = list2[index2];
- var name = item2.name;
- // 如果有 key的消费数据,则找下一个key
- if (key === name) {
- hasKeyFlag = true;
- break;
- }
- }
- // 如果list2循环结束后,找不到key,则补全数据;
- if (!hasKeyFlag) {
- item.items.push({
- name: key,
- value: 0,
- });
- }
- }
- }
- },
- // 大地图
- getStaticMapOption: function (chartEntity, dataIn) {
- var data = dataIn.dataList;
- var mapName = 'china'
- var geoCoordMap = {};
- /*获取地图数据*/
- chartEntity.showLoading();
- var mapFeatures = echarts.getMap(mapName).geoJson.features;
- chartEntity.hideLoading();
- mapFeatures.forEach(function (v) {
- // 地区名称
- var name = v.properties.name;
- // 地区经纬度
- geoCoordMap[name] = v.properties.cp;
- });
- var tempSort = data.sort(function (a, b) {
- return b.value - a.value;
- })
- var tempSortLen = tempSort.length;
- // 值的范围
- var max, min;
- if (tempSortLen > 0) {
- // 值的范围
- max = tempSort[0].value
- min = tempSort[tempSortLen - 1].value;
- }
- // 地图气泡的大小范围
- var maxSize4Pin = 72,
- minSize4Pin = 30;
- var convertData = function (data) {
- var res = [];
- for (var i = 0; i < data.length; i++) {
- var geoCoord = geoCoordMap[data[i].name];
- if (geoCoord) {
- res.push({
- name: data[i].name,
- value: geoCoord.concat(data[i].value),
- });
- }
- }
- return res;
- };
- var markData = convertData(data);
- // 底点的最大尺寸
- var pointMaxSize = 25;
- var option = {
- visualMap: {
- show: false,
- min: 0,
- max: 500,
- left: 'left',
- top: 'bottom',
- text: ['高', '低'], // 文本,默认为数值文本
- calculable: true,
- seriesIndex: [1],
- inRange: {
- color: ['#044161', '#2B91B7']
- }
- },
- geo: {
- show: true,
- map: mapName,
- label: {
- normal: {
- show: false
- },
- emphasis: {
- show: false,
- }
- },
- roam: true,
- itemStyle: {
- normal: {
- areaColor: '#031525',
- borderColor: '#3B5077',
- },
- emphasis: {
- areaColor: '#2B91B7',
- }
- }
- },
- series: [{
- name: '散点',// 蓝色的小点
- type: 'scatter',
- coordinateSystem: 'geo',
- data: markData,
- symbolSize: function (val) {
- var size = val[2] / 10
- if (size > pointMaxSize) {
- size = pointMaxSize
- }
- return size;
- },
- label: {
- normal: {
- formatter: '{b}',
- position: 'right',
- show: true
- },
- emphasis: {
- show: true
- }
- },
- itemStyle: {
- normal: {
- color: '#05C3F9'
- }
- }
- }, {
- type: 'map',
- map: mapName,
- geoIndex: 0,
- aspectScale: 0.75, //长宽比
- showLegendSymbol: false, // 存在legend时显示
- label: {
- normal: {
- show: true
- },
- emphasis: {
- show: false,
- textStyle: {
- color: '#fff'
- }
- }
- },
- roam: true,
- itemStyle: {
- normal: {
- areaColor: '#031525',
- borderColor: '#3B5077',
- },
- emphasis: {
- areaColor: '#2B91B7'
- }
- },
- animation: false,
- data: data
- }, {
- // 小点上的气泡
- name: '气泡',
- type: 'scatter',
- coordinateSystem: 'geo',
- symbol: 'pin', //气泡
- symbolSize: function (val) {
- var a = val[2] / (max - min);//当前值和最大值的比例
- var size = minSize4Pin + (maxSize4Pin - minSize4Pin) * a;// 实际大小
- if (size > maxSize4Pin) {
- size = maxSize4Pin
- }
- return size;
- },
- label: {
- normal: {
- show: true,
- formatter: function (params) {
- var size = params.value[2]
- return size
- },
- textStyle: {
- color: '#fff',
- fontSize: 9,
- }
- }
- },
- itemStyle: {
- normal: {
- color: '#108EE9', //标志颜色
- }
- },
- zlevel: 6,
- data: markData,
- }, {
- // 排名前5 底部的小点变成黄色 漪涟
- name: 'Top 5',
- type: 'effectScatter',
- coordinateSystem: 'geo',
- data: convertData(data.sort(function (a, b) {
- return b.value - a.value;
- }).slice(0, 5)),
- symbolSize: function (val) {
- var size = val[2] / 10
- if (size > pointMaxSize) {
- size = pointMaxSize
- }
- return size;
- },
- showEffectOn: 'render',
- rippleEffect: {
- brushType: 'stroke'
- },
- hoverAnimation: true,
- label: {
- normal: {
- formatter: '{b}',
- position: 'right',
- show: true
- }
- },
- itemStyle: {
- normal: {
- color: 'yellow',
- shadowBlur: 10,
- shadowColor: 'yellow'
- }
- },
- zlevel: 1
- },
- ]
- };
- return option
- },
- // 经销商营收TOP
- getDealerIncomeTopChartOption: function (data) {
- var xData = [];
- var yData = [];
- for (var i = 0; i < data.length; i++) {
- var item = data[i];
- xData.push(item.name);
- yData.push(item.payIncomeTotal);
- }
- var option = this.getLineOptionsForMap(xData, true);
- this.setPictorialBarStyle(option, yData);
- return option
- },
- // 全局营收趋势
- getIncomeLineOption: function (data) {
- var payIncomeCount = 0;
- var lineCoinsCount = 0;
- var xData = [];
- var yData = {payIncome: [], lineCoins: []};
- for (var i = 0; i < data.length; i++) {
- var item = data[data.length - i - 1];
- xData.push(item.dateStr);
- yData.payIncome.push(item.payIncome);
- yData.lineCoins.push(item.lineCoins);
- payIncomeCount = payIncomeCount + item.payIncome;
- lineCoinsCount = lineCoinsCount + item.lineCoins;
- }
- var option = this.getLineOptionsForMap(xData);
- option.series = [
- {
- name: '在线收入',
- stack: '收入',
- type: 'bar',
- itemStyle: {
- color: "rgba(16,142,233,.9)",
- },
- data: yData.payIncome
- }, {
- name: '线下投币',
- stack: '收入',
- type: 'bar',
- itemStyle: {
- color: "rgba(16,142,233,.6)",
- },
- data: yData.lineCoins
- }
- ];
- return option;
- },
- // 设备类型分布Top
- getDeviceTypeStatisticsOption: function (data) {
- var xData = [];
- var yData = [];
- for (var i = 0; i < data.length; i++) {
- var item = data[i];
- xData.push(item.name);
- yData.push(item.value);
- }
- var option = this.getLineOptionsForMap(xData, true);
- this.setPictorialBarStyle(option, yData);
- return option
- },
- getUserPieOption: function (payload) {
- },
- // 全网用户
- getAllUserOption: function (list) {
- //补齐数据结构
- this.fixData(list);
- var xData = [];
- var consumeSeriesMap = {};
- var length = list.length;
- for (var index in list) {
- // 正序时间排列
- var item = list[length - 1 - index];
- xData.push(item.dateStr);
- var list2 = item.items;
- for (var index2 in list2) {
- var item2 = list2[index2];
- var name = item2.name;
- var value = item2.value;
- if (!consumeSeriesMap[name]) {
- consumeSeriesMap[name] = [];
- }
- consumeSeriesMap[name].push(value);
- }
- }
- var myColor = this.getColorList();
- var option = this.getLineOptionsForMap(xData);
- var index = 0;
- for (var key in consumeSeriesMap) {
- var dataList = consumeSeriesMap[key];
- option.series.push({
- name: key,
- type: 'line',
- itemStyle: {
- normal: {
- color: myColor[index * 2],//相邻的颜色太相似了,所以间隔一个,越界不会异常,会使用默认色
- }
- },
- data: dataList
- });
- index++;
- }
- return option;
- },
- // 设备注册趋势
- getDeviceRegOption: function (data) {
- var xData = [];
- var yData = {regList: [] };
- for (var i = 0; i < data.length; i++) {
- var item = data[data.length - i - 1];
- xData.push(item.dateStr);
- yData.regList.push(item.reg);
- }
- var option = this.getLineOptionsForMap(xData);
- option.series = [
- {
- name: '注册设备',
- stack: '设备',
- type: 'bar',
- itemStyle: {
- color: "rgba(16,142,233,.9)",
- },
- data: yData.regList
- }
- ];
- return option;
- },
- // 用户反馈全网趋势
- getFeedbackOption: function (data) {
- var xData = [];
- var yData = {refund: [], upper: [], fault: []};
- for (var i = 0; i < data.length; i++) {
- var item = data[data.length - i - 1];
- xData.push(item.dateStr);
- yData.refund.push(item.refund);
- yData.upper.push(item.upper);
- yData.fault.push(item.fault);
- }
- var option = this.getLineOptionsForMap(xData);
- option.series = [
- {
- name: '退币',
- stack: '用户反馈',
- type: 'bar',
- itemStyle: {
- color: colorStopList.yellow[0],
- },
- data: yData.refund
- }, {
- name: '上分',
- stack: '用户反馈',
- type: 'bar',
- itemStyle: {
- color: colorStopList.green[0],
- },
- data: yData.upper
- }, {
- name: '报障',
- stack: '用户反馈',
- type: 'bar',
- itemStyle: {
- color: colorStopList.red[0],
- },
- data: yData.fault
- }
- ];
- return option;
- },
- // 提现趋势
- getWithdrawOption:function (list) {
- var xData = [];
- var seriesMap = {};
- var length = list.length;
- for (var index in list) {
- // 正序时间排列
- var item = list[length - 1 - index];
- xData.push(item.dateStr);
- var list2 = item.items;
- for (var index2 in list2) {
- var item2 = list2[index2];
- var name = item2.name;
- var value = item2.value;
- if (!seriesMap[name]) {
- seriesMap[name] = [];
- }
- seriesMap[name].push(value);
- }
- }
- var myColor = this.getColorList();
- var option = this.getLineOptionsForMap(xData);
- var index = 0;
- for (var key in seriesMap) {
- var dataList = seriesMap[key];
- option.series.push({
- name: key,
- type: 'line',
- itemStyle: {
- normal: {
- color: myColor[index * 2],//相邻的颜色太相似了,所以间隔一个,越界不会异常,会使用默认色
- }
- },
- data: dataList
- });
- index++;
- }
- return option;
- }
- };
- $scope.chartActive = {
- leftChart1: false,
- leftChart2: false,
- leftChart3: false,
- rightChart1: false,
- rightChart2: false,
- rightChart3: false,
- bottomChart: false,
- };
- //按条件加载统计图 因为有的接口太慢,避免等待,直接并发
- function loadChartData() {
- //获取数据:地图设备统计
- $http.get('/superadmin/getDevMapChart', {}).then(function (data) {
- data = data.data
- var payload = data.payload
- if (payload) {
- //地图拓展api地址:https://github.com/ecomfe/echarts/tree/master/extension/bmap
- var option = $scope.optionConfig.getStaticMapOption(devChartPanelMap, payload);
- $scope.showData.devBusy = payload.busy;
- $scope.showData.devOnline = payload.online;
- $scope.showData.devOffline = payload.offline;
- $scope.showData.unregistered = payload.unregistered;
- devChartPanelMap.setOption(option);
- devChartPanelMap.resize();// 确保地图居中
- }
- }).then(function () {
- $scope.chartActive.leftChart1 = true;
- $http.get('/superadmin/getDealerIncomeTotalTop', {}).then(function (data) {
- data = data.data
- if (data.payload) {
- var option = $scope.optionConfig.getDealerIncomeTopChartOption(data.payload.dataList);
- leftChart1.setOption(option);
- }
- });
- }).then(function () {
- $scope.chartActive.leftChart2 = true;
- $http.get('/superadmin/getIncomeTrend', {}).then(function (data) {
- data = data.data
- if (data.payload.dataList) {
- var option = $scope.optionConfig.getIncomeLineOption(data.payload.dataList);
- leftChart2.setOption(option);
- }
- });
- }).then(function () {
- $scope.chartActive.leftChart3 = true;
- $http.get('/superadmin/getDeviceTypeStatistics', {}).then(function (data) {
- data = data.data
- if (data.payload.dataList) {
- var option = $scope.optionConfig.getDeviceTypeStatisticsOption(data.payload.dataList);
- leftChart3.setOption(option);
- }
- });
- }).then(function () {
- $scope.chartActive.rightChart1 = true;
- $http.get('/superadmin/getAllUserTrend', {}).then(function (data) {
- data = data.data
- if (data.payload) {
- var option = $scope.optionConfig.getAllUserOption(data.payload.dataList);
- rightChart1.setOption(option);
- }
- });
- }).then(function () {
- $scope.chartActive.rightChart2 = true;
- $http.get('/superadmin/getDeviceRegTrend', {}).then(function (data) {
- data = data.data
- if (data.payload.dataList) {
- var option = $scope.optionConfig.getDeviceRegOption(data.payload.dataList);
- rightChart2.setOption(option);
- }
- });
- }).then(function () {
- $scope.chartActive.rightChart3 = true;
- $http.get('/superadmin/getAllFeedbackTrend', {}).then(function (data) {
- data = data.data
- if (data.payload) {
- var option = $scope.optionConfig.getFeedbackOption(data.payload.dataList);
- rightChart3.setOption(option);
- }
- });
- }).then(function () {
- $scope.chartActive.bottomChart = true;
- $http.get('/superadmin/getWithdrawTrend', {}).then(function (data) {
- data = data.data
- if (data.payload) {
- var option = $scope.optionConfig.getWithdrawOption(data.payload.dataList);
- bottomChart.setOption(option);
- }
- });
- })
- }
- // 全屏事件绑定
- $scope.isFullscreen = false;
- $scope.$on('fullscreenchange', function (evt, data) {
- $timeout(function () {
- $scope.isFullscreen = screenfull.isFullscreen;
- resizeChart()
- })
- });
- }]);
|