m0_70156489 1 dzień temu
rodzic
commit
bc43a93b7e

+ 10 - 6
application/admin/view/dashboard/index.html

@@ -474,25 +474,24 @@
         grid-template-columns: minmax(0, 1fr) minmax(340px, 32%);
         gap: 12px;
         align-items: stretch;
-        height: 300px;
+        min-height: 300px;
     }
 
     .proc-dash-chart-row .chart-col,
     .proc-dash-chart-row .side-col {
         min-width: 0;
-        height: 100%;
+        min-height: 300px;
         overflow: visible;
     }
 
     .proc-dash-chart-row #procuremen-echart {
-        height: 100%;
-        min-height: 0;
+        /* 固定像素高度,避免 height:100% 初始化时读到 0 导致坐标系错乱 */
+        height: 300px;
         width: 100%;
         background: #fff;
         border-radius: 4px;
         box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
         box-sizing: border-box;
-        padding: 0 4px 2px 0;
     }
 
     .proc-summary-panel {
@@ -511,14 +510,19 @@
     @media (max-width: 991px) {
         .proc-dash-chart-row {
             grid-template-columns: 1fr;
-            height: auto;
+            min-height: 0;
         }
 
         .proc-dash-chart-row .chart-col {
+            min-height: 260px;
+        }
+
+        .proc-dash-chart-row #procuremen-echart {
             height: 260px;
         }
 
         .proc-dash-chart-row .side-col {
+            min-height: 0;
             height: auto;
         }
 

+ 91 - 45
public/assets/js/backend/dashboard.js

@@ -5,8 +5,18 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'echarts', 'echarts-theme']
             var procChart = null;
             var chartData = Config.procuremenChart || {};
             var chartEl = document.getElementById('procuremen-echart');
-            if (chartEl) {
-                procChart = Echarts.init(chartEl, 'walden');
+
+            function toNumArr(arr) {
+                if (!$.isArray(arr)) {
+                    return [];
+                }
+                return arr.map(function (v) {
+                    var n = parseInt(v, 10);
+                    return isNaN(n) || n < 0 ? 0 : n;
+                });
+            }
+
+            function buildOption() {
                 var labels = chartData.labels || [];
                 var seriesMeta = [
                     {name: '待确认', key: 'confirm', color: '#f0ad4e'},
@@ -14,22 +24,27 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'echarts', 'echarts-theme']
                     {name: '已完结', key: 'completed', color: '#27C24C'}
                 ];
                 var maxVal = 0;
+                var seriesData = {};
                 seriesMeta.forEach(function (meta) {
-                    (chartData[meta.key] || []).forEach(function (v) {
-                        var n = parseInt(v, 10) || 0;
+                    var nums = toNumArr(chartData[meta.key]);
+                    seriesData[meta.key] = nums;
+                    nums.forEach(function (n) {
                         if (n > maxVal) {
                             maxVal = n;
                         }
                     });
                 });
-                procChart.setOption({
+                // 顶部留白,避免折线贴顶;至少显示到 2,刻度更易读
+                var yMax = maxVal <= 0 ? 2 : Math.max(maxVal + 1, Math.ceil(maxVal * 1.2));
+
+                return {
                     color: seriesMeta.map(function (m) {
                         return m.color;
                     }),
                     title: {
                         text: '近7天单数',
-                        left: 0,
-                        top: 0,
+                        left: 8,
+                        top: 8,
                         textStyle: {
                             fontSize: 13,
                             fontWeight: 600,
@@ -47,17 +62,17 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'echarts', 'echarts-theme']
                         data: seriesMeta.map(function (m) {
                             return m.name;
                         }),
-                        top: 0,
-                        right: 0,
+                        top: 8,
+                        right: 12,
                         itemWidth: 10,
                         itemHeight: 10,
                         textStyle: {fontSize: 11}
                     },
                     grid: {
-                        left: 2,
-                        right: 14,
-                        top: 36,
-                        bottom: 10,
+                        left: 16,
+                        right: 20,
+                        top: 44,
+                        bottom: 16,
                         containLabel: true
                     },
                     xAxis: {
@@ -68,67 +83,98 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'echarts', 'echarts-theme']
                         axisLabel: {
                             fontSize: 11,
                             color: '#888',
-                            margin: 4,
-                            interval: 0,
-                            showMinLabel: true,
-                            showMaxLabel: true,
-                            alignMinLabel: 'left',
-                            alignMaxLabel: 'right'
+                            margin: 8,
+                            interval: 0
                         },
                         axisLine: {lineStyle: {color: '#e8e8e8'}}
                     },
                     yAxis: {
                         type: 'value',
-                        minInterval: 1,
                         min: 0,
-                        max: maxVal <= 1 ? 2 : null,
-                        splitNumber: maxVal <= 2 ? 2 : 4,
-                        axisLabel: {fontSize: 11, color: '#888'},
+                        max: yMax,
+                        minInterval: 1,
+                        splitNumber: Math.min(5, yMax),
+                        axisLabel: {
+                            fontSize: 11,
+                            color: '#888',
+                            formatter: function (v) {
+                                return parseInt(v, 10) || 0;
+                            }
+                        },
                         splitLine: {lineStyle: {color: '#f0f0f0', type: 'dashed'}}
                     },
                     series: seriesMeta.map(function (meta) {
                         return {
                             name: meta.name,
                             type: 'line',
-                            smooth: true,
+                            // 轻度平滑:避免 true 时稀疏数据贝塞尔过冲(贴底/右上尖刺)
+                            smooth: 0.25,
+                            clip: true,
                             showSymbol: true,
                             symbol: 'circle',
-                            symbolSize: function (val) {
-                                return (parseInt(val, 10) || 0) > 0 ? 6 : 0;
-                            },
+                            symbolSize: 6,
+                            connectNulls: false,
                             lineStyle: {width: 2, color: meta.color},
                             itemStyle: {color: meta.color, borderWidth: 2, borderColor: '#fff'},
                             emphasis: {focus: 'series', lineStyle: {width: 3}},
-                            data: chartData[meta.key] || []
+                            data: seriesData[meta.key]
                         };
                     })
-                });
+                };
             }
 
-            $(window).resize(function () {
-                if (procChart) {
-                    procChart.resize();
+            function safeResize() {
+                if (!procChart || !chartEl) {
+                    return;
                 }
-            });
+                var w = chartEl.clientWidth;
+                var h = chartEl.clientHeight;
+                if (w < 40 || h < 40) {
+                    return;
+                }
+                procChart.resize({width: w, height: h});
+            }
 
-            setTimeout(function () {
-                if (procChart) {
-                    procChart.resize();
+            function renderChart() {
+                if (!chartEl) {
+                    return;
                 }
-            }, 120);
+                if (!procChart) {
+                    procChart = Echarts.init(chartEl, 'walden');
+                }
+                procChart.setOption(buildOption(), true);
+                safeResize();
+            }
+
+            if (chartEl) {
+                renderChart();
+            }
+
+            $(window).on('resize.procuremenDash', function () {
+                safeResize();
+            });
+
+            // 侧栏折叠 / 标签切换后容器尺寸变化,需再 resize
+            $(document).on('expanded.pushMenu collapsed.pushMenu', function () {
+                setTimeout(safeResize, 280);
+            });
+            $(document).on('shown.bs.tab click', '.nav-addtabs a, [addtabs]', function () {
+                setTimeout(safeResize, 120);
+            });
 
+            setTimeout(safeResize, 120);
+            setTimeout(safeResize, 400);
             setTimeout(function () {
-                if (procChart) {
-                    procChart.resize();
+                // 尺寸仍异常时强制按容器重绘一次
+                if (chartEl && procChart && (chartEl.clientHeight < 80 || chartEl.clientWidth < 80)) {
+                    renderChart();
+                } else {
+                    safeResize();
                 }
-            }, 400);
+            }, 800);
 
             $(document).on('click', '.btn-refresh', function () {
-                setTimeout(function () {
-                    if (procChart) {
-                        procChart.resize();
-                    }
-                }, 0);
+                setTimeout(safeResize, 0);
             });
         }
     };