1 <!DOCTYPE html>
2 <html lang="en">
3
4 <head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <meta http-equiv="X-UA-Compatible" content="ie=edge">
8 <title>Dashboard</title>
9 <style>
10 *{margin:0;padding:0;}
11 /* TV Start */
12 .RealTimeListTV {
13 width: 100%;
14 height: 100%;
15 overflow: scroll;
16 background: #030129 url('./image/tvBg.jpg') no-repeat;
17 background-size: 100% auto;
18 padding: 136px 0 0 0;
19 text-align: center;
20 position: relative;
21 box-sizing: border-box;
22 }
23 .RealTimeListTV .title {
24 font-size: 76px;
25 color: #fff;
26 letter-spacing: 6px;
27 }
28 .RealTimeListTV .totalValue {
29 font-size: 150px;
30 color: #fff;
31 letter-spacing: 6px;
32 }
33 .RealTimeListTV .totalValue .decoration {
34 width: 524px;
35 height: 136px;
36 display: block;
37 margin: 0 auto;
38 background: url('./image/lineH.png') no-repeat;
39 }
40 .RealTimeListTV .BusinessUnitList {
41 display: flex;
42 justify-content: space-between;
43 overflow: hidden;
44 line-height: 50px;
45 padding: 0 200px;
46 list-style: none;
47 }
48 .BusinessUnitList li {
49 float: left;
50 color: #fff;
51 position: relative;
52 letter-spacing: 6px;
53 }
54 .BusinessUnitList li .name {
55 font-size: 30px;
56 }
57 .BusinessUnitList li .value {
58 font-size: 36px;
59 }
60 .BusinessUnitList li .line {
61 width: 47px;
62 height: 48px;
63 background: url('./image/line.png') no-repeat;
64 position: absolute;
65 left: -70px;
66 top: 0;
67 }
68 .main{
69 margin: 50px auto 0;
70 }
71 /* TV End */
72
73
74 /* WEB Start */
75 .RealTimeListWEB{
76 width: 1280px;
77 background: #030129 url('./image/webBg.png') no-repeat;
78 background-size: 100% auto;
79 padding: 40px 0 0 0;
80 text-align: center;
81 position: relative;
82 box-sizing: border-box;
83 margin:0 auto;
84 }
85
86 .RealTimeListWEB .title{
87 font-size: 46px;
88 color: #fff;
89 letter-spacing: 6px;
90 }
91 .RealTimeListWEB .totalValue {
92 font-size: 80px;
93 color: #fff;
94 letter-spacing: 6px;
95 }
96 .RealTimeListWEB .BusinessUnitList{
97 list-style: none;
98 margin-top:110px;
99 }
100 .RealTimeListWEB .BusinessUnitList::after{
101 content:".";
102 clear:both;
103 display:block;
104 height:0;
105 overflow:hidden;
106 visibility:hidden;
107 }
108
109
110 .RealTimeListWEB .BusinessUnitList li{
111 width: 20%;
112 padding-bottom: 30px;
113 letter-spacing: 3px;
114 }
115 .RealTimeListWEB .BusinessUnitList li .line{
116 left: 25px;
117 top: -8px;
118 width: 32px;
119 height: 32px;
120 }
121 .RealTimeListWEB .BusinessUnitList li .name,.RealTimeListWEB .BusinessUnitList li .value{
122 font-size: 20px;
123 padding-bottom: 20px;
124 }
125 .echartsList{
126 margin-top: 200px;
127 }
128 /* WEB End */
129
130 /* comment */
131 .lageBoxNone,.smallBoxNone{
132 display: none;
133 }
134 @media screen and (min-width:3000px) and (max-width:5000px) {
135 .lageBoxNone{
136 display: block;
137 }
138 }
139 @media only screen and (max-width: 2999px) {
140 .smallBoxNone{
141 display: block;
142 }
143 }
144
145
146 </style>
147 </head>
148
149 <body>
150
151 <!-- 电视尺寸 -->
152 <div class="RealTimeListTV lageBoxNone">
153 <div class="title">总销售额</div>
154 <div class="totalValue">$<span>0.00</span><span class="decoration"></span></div>
155 <ul class="BusinessUnitList">
156 <li> <span class="line"></span> <p class="name">SW事业部</p> <p class="value">$0.00</p></li>
157 <li> <span class="line"></span> <p class="name">SP事业部</p> <p class="value">$0.00</p></li>
158 <li> <span class="line"></span> <p class="name">JFN事业部</p> <p class="value">$0.00</p></li>
159 <li> <span class="line"></span> <p class="name">PJ事业部</p> <p class="value">$0.00</p></li>
160 <li> <span class="line"></span> <p class="name">Pi事业部</p> <p class="value">$0.00</p></li>
161 <li> <span class="line"></span> <p class="name">AG事业部</p> <p class="value">$0.00</p></li>
162 <li> <span class="line"></span> <p class="name">HA事业部</p> <p class="value">$0.00</p></li>
163 <li> <span class="line"></span> <p class="name">Q事业部</p> <p class="value">$0.00</p></li>
164 <li> <span class="line"></span> <p class="name">N事业部</p> <p class="value">$0.00</p></li>
165 <li> <span class="line"></span> <p class="name">GS事业部</p> <p class="value">$0.00</p></li>
166 </ul>
167 <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
168 <div style="padding:0 50px;">
169 <div id="main" class="main" style="width: 100%;height:1500px;"></div>
170 </div>
171
172 </div>
173
174 <!-- pc尺寸 -->
175 <div class="RealTimeListWEB smallBoxNone">
176 <div class="title">总销售额</div>
177 <div class="totalValue">$<span>0.00</span></div>
178 <ul class="BusinessUnitList">
179 <li> <span class="line"></span> <p class="name">SW事业部</p> <p class="value">$0.00</p></li>
180 <li> <span class="line"></span> <p class="name">SP事业部</p> <p class="value">$0.00</p></li>
181 <li> <span class="line"></span> <p class="name">JFN事业部</p> <p class="value">$0.00</p></li>
182 <li> <span class="line"></span> <p class="name">PJ事业部</p> <p class="value">$0.00</p></li>
183 <li> <span class="line"></span> <p class="name">Pi事业部</p> <p class="value">$0.00</p></li>
184 <li> <span class="line"></span> <p class="name">AG事业部</p> <p class="value">$0.00</p></li>
185 <li> <span class="line"></span> <p class="name">HA事业部</p> <p class="value">$0.00</p></li>
186 <li> <span class="line"></span> <p class="name">Q事业部</p> <p class="value">$0.00</p></li>
187 <li> <span class="line"></span> <p class="name">N事业部</p> <p class="value">$0.00</p></li>
188 <li> <span class="line"></span> <p class="name">GS事业部</p> <p class="value">$0.00</p></li>
189 </ul>
190 <!-- 为ECharts准备一个具备大小(宽高)的Dom -->
191 <div class="echartsList">
192 <div id="main1" class="main" style="width: 1200px;height:450px;display: none;"></div>
193 <div id="main2" class="main" style="width: 1200px;height:450px;display: none;"></div>
194 <div id="main3" class="main" style="width: 1200px;height:450px;display: none;"></div>
195 <div id="main4" class="main" style="width: 1200px;height:450px;display: none;"></div>
196 <div id="main5" class="main" style="width: 1200px;height:450px;display: none;"></div>
197 <div id="main6" class="main" style="width: 1200px;height:450px;display: none;"></div>
198 <div id="main7" class="main" style="width: 1200px;height:450px;display: none;"></div>
199 <div id="main8" class="main" style="width: 1200px;height:450px;display: none;"></div>
200 <div id="main9" class="main" style="width: 1200px;height:450px;display: none;"></div>
201 <div id="main10" class="main" style="width: 1200px;height:450px;display: none;"></div>
202 <div id="main11" class="main" style="width: 1200px;height:450px;display: none;"></div>
203 <div id="main12" class="main" style="width: 1200px;height:450px;display: none;"></div>
204 <div id="main13" class="main" style="width: 1200px;height:450px;display: none;"></div>
205 <div id="main14" class="main" style="width: 1200px;height:450px;display: none;"></div>
206 <div id="main15" class="main" style="width: 1200px;height:450px;display: none;"></div>
207 </div>
208 </div>
209
210 </body>
211 <script src='./js/jquery-3.1.0.min.js'></script>
212 <script src="./js/echarts.min.js"></script>
213 <script src="./js/eventsource.min.js"></script>
214
215 <script type="text/javascript">
216 /*
217 堆叠条形图 公共配置
218 xData: x轴数据 type=category arr 必填
219 yData: y轴数据 type=value arr 必填
220 HistogramW: 单个柱状图的宽度 str 如果不传默认是60
221 */
222 // 基于准备好的dom,初始化echarts实例
223 function StackedBarChart(xData, yData, HistogramW) {
224 var yData1 = [],
225 yData2 = [],
226 yData3 = [],
227 yData4 = [],
228 HistogramW = HistogramW ? HistogramW : '60px';
229 for (var i = 0, len = yData.length; i < len; i++) {
230 var cur = yData[i];
231 yData1.push(cur * 0.1 >>> 0);
232 yData2.push(cur * 0.2 >>> 0);
233 yData3.push(cur * 0.3 >>> 0);
234 yData4.push(cur * 0.4 >>> 0);
235 }
236 return {
237 textStyle: {
238 color: '#fff',
239 fontSize: '42px'
240 },
241 tooltip: {
242 trigger: 'axis',
243 axisPointer: { // 坐标轴指示器,坐标轴触发有效
244 type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
245 },
246 show: false
247 },
248 grid: {
249 left: '3%',
250 right: '4%',
251 bottom: '3%',
252 containLabel: true
253 },
254 xAxis: [{
255 type: 'category',
256 axisLine: { // x轴的颜色和宽度
257 lineStyle: {
258 color: '#373750',
259 width: 5 //这里是坐标轴的宽度,可以去掉
260 }
261 },
262 axisLabel: {
263 interval:0,
264 rotate:40
265 },
266 data: xData
267 }],
268 yAxis: [{
269 type: 'value',
270 axisLabel: {
271 show: true,
272 textStyle: {
273 color: '#fff'
274 }
275 },
276 // 控制网格线是否显示
277 splitLine: {
278 show: true,
279 // 改变轴线颜色
280 lineStyle: {
281 // 使用深浅的间隔色
282 color: ['#24243f']
283 }
284 }
285
286 }],
287 series: [
288
289 {
290 type: 'bar', // 柱状图
291 stack: '站点总销售额', // 数据堆叠,同个类目轴上系列配置相同的stack值可以堆叠放置
292 itemStyle: {
293 normal: {
294 color: new echarts.graphic.LinearGradient(
295 0, 0, 0, 1,
296 [{
297 offset: 0,
298 color: '#5fa2bc'
299 },
300 {
301 offset: 0.7,
302 color: '#9fe595'
303 }
304 ]
305 )
306 }
307 },
308
309 barMaxWidth: HistogramW,
310 data: yData1
311 },
312 {
313 type: 'bar',
314 stack: '站点总销售额',
315 itemStyle: {
316 normal: {
317 color: new echarts.graphic.LinearGradient(
318 0, 0, 0, 1,
319 [{
320 offset: 0,
321 color: '#fae093'
322 },
323 {
324 offset: 0.7,
325 color: '#f99c72'
326 }
327 ]
328 )
329 }
330 },
331 data: yData2
332 },
333 {
334 type: 'bar',
335 stack: '站点总销售额',
336 itemStyle: {
337 normal: {
338 color: new echarts.graphic.LinearGradient(
339 0, 0, 0, 1,
340 [{
341 offset: 0,
342 color: '#ff79aa'
343 },
344 {
345 offset: 0.7,
346 color: '#e9566d'
347 }
348 ]
349 )
350 }
351 },
352 data: yData3
353 },
354 {
355 // 只在最后一组数据中显示 label,由于最后一组数据的值来自 total * 0.4,
356 // 由此逆推出总数为 data / 0.4,
357 // >>> 用于去除小数部分
358 label: {
359 show: true,
360 position: 'top',
361 formatter: function (param) {
362 return Math.round(yData[param.dataIndex]);
363 }
364 },
365 type: 'bar',
366 stack: '站点总销售额',
367 itemStyle: {
368 normal: {
369 color: new echarts.graphic.LinearGradient(
370 0, 0, 0, 1,
371 [{
372 offset: 0,
373 color: '#94c8d3'
374 },
375 {
376 offset: 0.7,
377 color: '#6a71e4'
378 }
379 ]
380 )
381 }
382 },
383 data: yData4
384 },
385
386 ]
387 };
388 }
389
390 function SetXYStyle(arr) {
391 return arr.map(function(item) {
392 return {
393 value: item,
394 textStyle: {
395 fontSize: 22
396 }
397 }
398 })
399 }
400 /* 设置电视echarts图表尺寸 */
401 var totalH = window.innerHeight || document.body.clientHeight || document.documentElement.clientHeight,
402 titleH = $('.title').outerHeight(true),
403 totalValueH = $('.totalValue').outerHeight(true),
404 businessUnitListH = $('.BusinessUnitList').outerHeight(true),
405 mainH = totalH - titleH - totalValueH - businessUnitListH - 136 - 50 ;
406 $('#main').css('height',mainH+'px');
407
408
409
410 /*---------------- Echarts ---------------- */
411 var is_pc = true,
412 params = 'is_pc=yes',
413 w = window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;
414 if (w > 3000) {
415 is_pc = false;
416 params = 'is_tv=yes'
417 }
418
419 var source = new EventSource('/rest/dashboard/fetch?' + params, { withCredentials: false, format: 'json' });
420
421 // open事件 连接一旦建立,就会触发open事件,可以定义相应的回调函数。
422 source.onopen = function (event) {
423 // handle open event
424 console.log('onopen', event)
425 };
426
427 // error事件 如果发生通信错误(比如连接中断),就会触发error事件。
428 source.onerror = function (event) {
429 // handle error event
430 var data = event.data;
431 if (typeof data == 'string') {
432 data = data.replace(/\n/g,'')
433 }
434 console.log('onerror', data)
435 };
436
437 // 自定义事件
438 source.addEventListener("whole_total", function (event) {
439 var data = event.data;
440 var origin = event.origin;
441 var lastEventId = event.lastEventId;
442 // handle message
443 if (typeof data == 'string') {
444 data = data.replace(/\n/g,'')
445 }
446
447 $(".RealTimeListTV .totalValue span").eq(0).text(data)
448 $(".RealTimeListWEB .totalValue span").eq(0).text(data)
449 }, false);
450
451 // 自定义事件
452 source.addEventListener("depart_total", function (event) {
453 // handle message
454 var data = event.data;
455 // console.log('depart_total', data)
456 if (typeof data == 'string') {
457 data = data.replace(/\n/g,'')
458 data = JSON.parse(data);
459 }
460
461 var html = '';
462 for (var i=0; i < data.length; i++) {
463 html += '<li>';
464 html += ' <span class="line"></span>';
465 html += ' <p class="name">' + data[i]['name'] + '</p>';
466 html += ' <p class="value">$' + data[i]['data'] + '</p>';
467 html += '</li>';
468 }
469
470 $('.RealTimeListTV .BusinessUnitList').html(html);
471 $('.RealTimeListWEB .BusinessUnitList').html(html);
472
473 }, false);
474
475 // 自定义事件
476 source.addEventListener("site_total", function (event) {
477
478 var data = event.data;
479
480 if (typeof data == 'string') {
481 data = data.replace(/\n/g,'')
482 data = JSON.parse(data);
483 }
484 console.log('data.length', data.length)
485
486 // 循环15个一组, 重新渲染
487 if (is_pc) {
488 /*---------------- WEB Echarts ---------------- */
489 for (var i = 0; i < data.length; i++) {
490 var id = 'main' + (i + 1);
491 $('#' + id).show()
492 var myChart = echarts.init(document.getElementById(id)),
493 xData = data[i].xData,
494 yData = data[i].yData;
495 myChart.setOption(StackedBarChart(xData, yData, '40'));
496 }
497
498 for (var i=data.length; i<15; i++) {
499 var id = 'main' + (i + 1);
500 $('#' + id).hide()
501 }
502 // 渲染30个一排
503 } else {
504 /* ---------------- TV Echarts ---------------- */
505 var myChart = echarts.init(document.getElementById('main')),
506 xData = data[0].xData
507 yData = data[0].yData;
508 // 使用刚指定的配置项和数据显示图表。
509 myChart.setOption(StackedBarChart(SetXYStyle(xData),yData));
510 }
511
512 }, false);
513
514 var last_hart_time = Math.round((new Date()).getTime() / 1000);
515
516 // 自定义事件
517 source.addEventListener("hart", function (event) {
518 var data = event.data;
519 var origin = event.origin;
520 var lastEventId = event.lastEventId;
521 // handle message
522
523 if (typeof data == 'string') {
524 data = data.replace(/\n/g,'')
525 data = JSON.parse(data)
526 }
527 var max_delay_seconds = data.max_delay || 5
528 var now_hart_time = Math.round((new Date()).getTime() / 1000);
529 if(now_hart_time - last_hart_time > max_delay_seconds) {
530 $.ajax({
531 url: '/rest/dashboard/hartReply',
532 method: 'POST',
533 data: { uid: data['uid'], token: data['token'] },
534 dataType: 'json',
535 success: function (result) {
536 last_hart_time = now_hart_time
537 console.log('reply')
538 }
539 })
540 }
541 console.log('hart')
542 }, false);
543
544 // 自定义事件
545 source.addEventListener("close", function (event) {
546 var data = event.data;
547 var origin = event.origin;
548 var lastEventId = event.lastEventId;
549 // handle message
550 if (typeof data == 'string') {
551 data = data.replace(/\n/g,'')
552 }
553
554 // close方法用于关闭连接。
555 source.close();
556 console.log('close', event)
557 }, false);
558
559
560 </script>
561
562 </html>