Prechádzať zdrojové kódy

造价对比,调整

MaiXinRong 2 rokov pred
rodič
commit
6f5363ea19

+ 8 - 2
app/public/js/budget_compare.js

@@ -16,6 +16,9 @@ $(document).ready(() => {
     const compareSpread = SpreadJsObj.createNewSpread($('#cost-compare')[0]);
     const compareSheet = compareSpread.getActiveSheet();
 
+    const getStackedBarTip = function (data) {
+        return data.stackedBarTips.join('\n');
+    };
     const spreadSetting = {
         cols: [
             {title: '项目节编号', colSpan: '1', rowSpan: '2', field: 'code', hAlign: 0, width: 150, formatter: '@', cellType: 'tree'},
@@ -36,7 +39,7 @@ $(document).ready(() => {
             {title: '决算|数量1/数量2', colSpan: '3|1', rowSpan: '1|1', field: 'final_dgn_qty', hAlign: 2, width: 80, bc_type: 'number', visible: false},
             {title: '|经济指标', colSpan: '|1', rowSpan: '|1', field: 'final_dgn_price', hAlign: 2, width: 80, type: 'Number', bc_type: 'number', visible: false},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'final_tp', hAlign: 2, width: 80, type: 'Number', bc_type: 'number', visible: false},
-            {title: '数据对比', colSpan: '1', rowSpan: '2', field: 'stackedBar', hAlign: 0, width: 300, cellType: 'stackedBar', stackedBarCover: false, bc_type: 'grid', visible: false},
+            {title: '数据对比', colSpan: '1', rowSpan: '2', field: 'stackedBar', hAlign: 0, width: 300, cellType: 'stackedBar', stackedBarCover: false, bc_type: 'grid', visible: false, getTip: getStackedBarTip},
             {title: '增幅%|数量1/数量2', colSpan: '2|1', rowSpan: '1|1', field: 'grow_dgn_qty', hAlign: 2, width: 80},
             {title: '|金额', colSpan: '|1', rowSpan: '|1', field: 'grow_tp', hAlign: 2, width: 80, type: 'Number'},
         ],
@@ -93,6 +96,7 @@ $(document).ready(() => {
         calcStackedBar(tree) {
             const calcField = this.stackedBarField;
             const calcFieldColor = { 'gu_tp': '#657798', 'gai_tp': '#EE6666', 'yu_tp': '#74CBED', 'total_price': '#FAC858', 'final_tp': '#62DAAB' };
+            const calcFieldCaption = { 'gu_tp': '估算', 'gai_tp': '概算', 'yu_tp': '预算', 'total_price': '台账', 'final_tp': '决算' };
             const calc = function(node, base){
                 // const parent = tree.getParent(node);
                 // if (!parent) {
@@ -102,8 +106,10 @@ $(document).ready(() => {
                 //     }
                 // }
                 node.stackedBar = [];
+                node.stackedBarTips = [];
                 for (const cf of calcField) {
                     node.stackedBar.push({color: calcFieldColor[cf], percent: ZhCalc.div(node[cf], base), field: cf});
+                    node.stackedBarTips.push(`${calcFieldCaption[cf]}: ${node[cf] || 0}`);
                 }
                 if (node.children) {
                     for (const child of node.children) {
@@ -114,7 +120,7 @@ $(document).ready(() => {
             let commonBase = 0;
             tree.children.forEach(x => {
                 for (const cf of calcField) {
-                    commonBase = Math.max(x[cf], commonBase);
+                    commonBase = Math.max(x[cf] || 0, commonBase);
                 }
             });
             for (const child of tree.children) {

+ 90 - 0
app/public/js/spreadjs_rela/spreadjs_zh.js

@@ -2539,6 +2539,7 @@ const SpreadJsObj = {
             const stackedBarCellType = function(){};
             stackedBarCellType.prototype = new spreadNS.CellTypes.Text();
             const indent = 3, defaultR = 0.05, minHeight = 2;
+            const tipsMaxHintWidth = 200, tipsIndent = 15, tipsBorderIndent = 10;
             /**
              * 画一个长条
              * @param {Object} canvas - 画布
@@ -2608,6 +2609,95 @@ const SpreadJsObj = {
                     drawBarbefore99(canvas, left, top, width, height, ZhCalc.mul(height, defaultR, 2), bd.color);
                 }
             };
+
+            proto.getTextDisplayWidth = function(hitinfo, str, font) {
+                const xs = hitinfo.sheet.getParent().xs;
+                const ctx = xs.childNodes[0].getContext("2d");
+                if (font && font !== '') {
+                    ctx.font = font;
+                } else {
+                    ctx.font = hitinfo.cellStyle.font;
+                }
+                return ctx.measureText(str).width;
+            };
+            proto.showTip = function (hitinfo, text) {
+                return text && text !== '';
+            };
+            /**
+             * 获取点击信息
+             * @param {Number} x
+             * @param {Number} y
+             * @param {Object} cellStyle
+             * @param {Object} cellRect
+             * @param {Object} context
+             * @returns {{x: *, y: *, row: *, col: *|boolean|*[]|number|{}|UE.dom.dtd.col, cellStyle: *, cellRect: *, sheet: *|StyleSheet, sheetArea: *}}
+             */
+            proto.getHitInfo = function (x, y, cellStyle, cellRect, context) {
+                return {
+                    x: x,
+                    y: y,
+                    row: context.row,
+                    col: context.col,
+                    cellStyle: cellStyle,
+                    cellRect: cellRect,
+                    sheet: context.sheet,
+                    sheetArea: context.sheetArea,
+                    ctx: context.sheet.getParent().xs,
+                };
+            };
+            /**
+             * 鼠标进入单元格事件 - 显示悬浮提示
+             * @param {Object} hitinfo - 见getHitInfo返回值
+             */
+            proto.processMouseEnter = function (hitinfo) {
+                let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
+                const col = hitinfo.sheet.zh_setting.cols[hitinfo.col];
+                if (col.getTip && Object.prototype.toString.apply(col.getTip) === "[object Function]") {
+                    const sortData = SpreadJsObj.getSortData(hitinfo.sheet);
+                    text = col.getTip(sortData[hitinfo.row]);
+                }
+                const pos = SpreadJsObj.getObjPos(hitinfo.sheet.getParent().qo);
+                if (pos && this.showTip(hitinfo, text)) {
+                    if (!this._toolTipElement) {
+                        let div = $('#autoTip')[0];
+                        if (!div) {
+                            div = document.createElement("div");
+                            $(div).css("position", "absolute")
+                                .css("border", "1px #C0C0C0 solid")
+                                .css("box-shadow", "1px 2px 5px rgba(0,0,0,0.4)")
+                                .css("font", "9pt Arial")
+                                .css("background", "white")
+                                .css("padding", 5)
+                                .css("z-index", 999)
+                                .css("max-width", tipsMaxHintWidth)
+                                .css("word-wrap", "break-word")
+                                .attr("id", 'autoTip');
+                            document.body.insertBefore(div, null);
+                        }
+                        const validWidth = $(window).width() - (pos.x + hitinfo.x + tipsIndent) - tipsBorderIndent;
+                        const textWidth = this.getTextDisplayWidth(hitinfo, text, "9pt Arial");
+                        if (validWidth >= tipsMaxHintWidth || textWidth <= validWidth) {
+                            $(div).html(text).css("top", pos.y + hitinfo.y + tipsIndent).css("left", pos.x + hitinfo.x + tipsIndent);
+                        } else if (textWidth > tipsMaxHintWidth) {
+                            $(div).html(text).css("top", pos.y + hitinfo.y + tipsIndent).css("left", pos.x + hitinfo.x - tipsIndent - tipsMaxHintWidth);
+                        } else {
+                            $(div).html(text).css("top", pos.y + hitinfo.y + tipsIndent).css("left", pos.x + hitinfo.x - tipsIndent - textWidth);
+                        }
+                        this._toolTipElement = div;
+                        $(div).show("fast");
+                    }
+                }
+            };
+            /**
+             * 鼠标移出单元格事件 - 隐藏悬浮提示
+             * @param {Object} hitinfo - 见getHitInfo返回值
+             */
+            proto.processMouseLeave = function (hitinfo) {
+                if (this._toolTipElement) {
+                    $(this._toolTipElement).hide();
+                    this._toolTipElement = null;
+                }
+            };
             return new stackedBarCellType();
         },
     },