|  | @@ -0,0 +1,273 @@
 | 
	
		
			
				|  |  | +//本文档是图形输出的接口实现
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const JpcFigureOutput = {
 | 
	
		
			
				|  |  | +    offsetX: 0,
 | 
	
		
			
				|  |  | +    offsetY: 0,
 | 
	
		
			
				|  |  | +    scaleFactor: 1,
 | 
	
		
			
				|  |  | +	_iniCavas: function(canvas, width, height) {
 | 
	
		
			
				|  |  | +		if (canvas) {
 | 
	
		
			
				|  |  | +			let ctx = canvas.getContext('2d');
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	},
 | 
	
		
			
				|  |  | +	_draw: function(ctx, figure, saveAsData = false) {
 | 
	
		
			
				|  |  | +		if (figure.imageData) {
 | 
	
		
			
				|  |  | +			//直接图形输出
 | 
	
		
			
				|  |  | +            ctx.putImageData(figure.imageData, figure.area.Left + this.offsetX, figure.area.Top + this.offsetY);
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			let width = figure.area.Right - figure.area.Left;
 | 
	
		
			
				|  |  | +			let height = figure.area.Bottom - figure.area.Top;
 | 
	
		
			
				|  |  | +			let xSteps = figure.coordinateAxis.axisX.steps;
 | 
	
		
			
				|  |  | +			let ySteps = figure.coordinateAxis.axisY.steps;
 | 
	
		
			
				|  |  | +			let xStepW = width / xSteps;
 | 
	
		
			
				|  |  | +			let yStepH = height / ySteps;
 | 
	
		
			
				|  |  | +			ctx.save();
 | 
	
		
			
				|  |  | +            ctx.translate(0.5,0.5);
 | 
	
		
			
				|  |  | +            ctx.beginPath();
 | 
	
		
			
				|  |  | +            if (figure.coordinateAxis.axisX.isShowLine) {
 | 
	
		
			
				|  |  | +                //画竖线
 | 
	
		
			
				|  |  | +                for (let idx = 0; idx < xSteps; idx++) {
 | 
	
		
			
				|  |  | +                    ctx.lineWidth = 1;
 | 
	
		
			
				|  |  | +                    ctx.strokeStyle = 'black';
 | 
	
		
			
				|  |  | +                    ctx.moveTo(Math.round(figure.area.Left + xStepW * (idx + 1) + this.offsetX), figure.area.Bottom + this.offsetY);
 | 
	
		
			
				|  |  | +                    ctx.lineTo(Math.round(figure.area.Left + xStepW * (idx + 1) + this.offsetX), figure.area.Top + this.offsetY);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            if (figure.coordinateAxis.axisY.isShowLine) {
 | 
	
		
			
				|  |  | +                //画横线
 | 
	
		
			
				|  |  | +                for (let idx = 0; idx < ySteps; idx++) {
 | 
	
		
			
				|  |  | +                    ctx.lineWidth = 1;
 | 
	
		
			
				|  |  | +                    ctx.strokeStyle = 'black';
 | 
	
		
			
				|  |  | +                    ctx.moveTo(figure.area.Left + this.offsetX, Math.round(figure.area.Bottom - yStepH * (idx + 1) + this.offsetY));
 | 
	
		
			
				|  |  | +                    ctx.lineTo(figure.area.Right + this.offsetX, Math.round(figure.area.Bottom - yStepH * (idx + 1) + this.offsetY));
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            ctx.stroke();
 | 
	
		
			
				|  |  | +            for (let ctIdx = 0; ctIdx < figure.contents.length; ctIdx++) {
 | 
	
		
			
				|  |  | +				const content = figure.contents[ctIdx];
 | 
	
		
			
				|  |  | +				ctx.beginPath();
 | 
	
		
			
				|  |  | +                for (let idx = 0; idx < content.values.length; idx++) {
 | 
	
		
			
				|  |  | +					let xPos = figure.area.Left + xStepW * idx + xStepW / 2 + this.offsetX;
 | 
	
		
			
				|  |  | +					let yPos = figure.area.Bottom - (content.values[idx] / content.maxValue) * height + this.offsetY;
 | 
	
		
			
				|  |  | +                    ctx.lineWidth = 1;
 | 
	
		
			
				|  |  | +                    ctx.strokeStyle = content.color;
 | 
	
		
			
				|  |  | +                    if (content.style === 'dash') ctx.setLineDash([10, 5]);
 | 
	
		
			
				|  |  | +                    switch (figure.config.dispType) {
 | 
	
		
			
				|  |  | +						case 'line':
 | 
	
		
			
				|  |  | +							//折线图
 | 
	
		
			
				|  |  | +							if (idx === 0) {
 | 
	
		
			
				|  |  | +								ctx.moveTo(xPos, yPos);
 | 
	
		
			
				|  |  | +							} else {
 | 
	
		
			
				|  |  | +								ctx.lineTo(xPos, yPos);
 | 
	
		
			
				|  |  | +							}
 | 
	
		
			
				|  |  | +						break;
 | 
	
		
			
				|  |  | +						case 'pole':
 | 
	
		
			
				|  |  | +							//柱图
 | 
	
		
			
				|  |  | +						break;
 | 
	
		
			
				|  |  | +						default:
 | 
	
		
			
				|  |  | +							//....
 | 
	
		
			
				|  |  | +						break;
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				ctx.stroke();
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			ctx.restore();
 | 
	
		
			
				|  |  | +            if (saveAsData) {
 | 
	
		
			
				|  |  | +                //保存当前图形数据
 | 
	
		
			
				|  |  | +                figure.imageData = ctx.getImageData(figure.area.Left + this.offsetX, figure.area.Top + this.offsetY, width, height);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	},
 | 
	
		
			
				|  |  | +	drawToCanvas: function(canvas, currentPageData) {
 | 
	
		
			
				|  |  | +		//预览用
 | 
	
		
			
				|  |  | +		if (canvas && currentPageData) {
 | 
	
		
			
				|  |  | +			const ctx = canvas.getContext("2d");
 | 
	
		
			
				|  |  | +			if (currentPageData.figure_cells && currentPageData.figure_cells.length > 0) {
 | 
	
		
			
				|  |  | +				for (let figure of currentPageData.figure_cells) {
 | 
	
		
			
				|  |  | +					this._draw(ctx, figure, false);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	},
 | 
	
		
			
				|  |  | +    _drawPdf: function(doc, figure) {
 | 
	
		
			
				|  |  | +        const PDF_SCALE = 0.75;
 | 
	
		
			
				|  |  | +        if (figure.imageData) {
 | 
	
		
			
				|  |  | +			//直接图形输出
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			let width = figure.area.Right - figure.area.Left;
 | 
	
		
			
				|  |  | +			let height = figure.area.Bottom - figure.area.Top;
 | 
	
		
			
				|  |  | +			let xSteps = figure.coordinateAxis.axisX.steps;
 | 
	
		
			
				|  |  | +			let ySteps = figure.coordinateAxis.axisY.steps;
 | 
	
		
			
				|  |  | +			let xStepW = width / xSteps;
 | 
	
		
			
				|  |  | +			let yStepH = height / ySteps;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (figure.coordinateAxis.axisX.isShowLine) {
 | 
	
		
			
				|  |  | +                //画竖线
 | 
	
		
			
				|  |  | +                for (let idx = 0; idx < xSteps; idx++) {
 | 
	
		
			
				|  |  | +                    doc.setLineWidth(0.8);
 | 
	
		
			
				|  |  | +                    doc.setDrawColor('black');
 | 
	
		
			
				|  |  | +                    doc.line((Math.round(figure.area.Left + xStepW * (idx + 1) + this.offsetX)) * PDF_SCALE, (figure.area.Bottom + this.offsetY) * PDF_SCALE,
 | 
	
		
			
				|  |  | +                             (Math.round(figure.area.Left + xStepW * (idx + 1) + this.offsetX)) * PDF_SCALE, (figure.area.Top + this.offsetY) * PDF_SCALE);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            if (figure.coordinateAxis.axisY.isShowLine) {
 | 
	
		
			
				|  |  | +                //画横线
 | 
	
		
			
				|  |  | +                for (let idx = 0; idx < ySteps; idx++) {
 | 
	
		
			
				|  |  | +                    doc.setLineWidth(0.8);
 | 
	
		
			
				|  |  | +                    doc.setDrawColor('black');
 | 
	
		
			
				|  |  | +                    doc.line((figure.area.Left + this.offsetX) * PDF_SCALE, (Math.round(figure.area.Bottom - yStepH * (idx + 1) + this.offsetY)) * PDF_SCALE,
 | 
	
		
			
				|  |  | +                            (figure.area.Right + this.offsetX) * PDF_SCALE, (Math.round(figure.area.Bottom - yStepH * (idx + 1) + this.offsetY)) * PDF_SCALE);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            for (let ctIdx = 0; ctIdx < figure.contents.length; ctIdx++) {
 | 
	
		
			
				|  |  | +				const content = figure.contents[ctIdx];
 | 
	
		
			
				|  |  | +                let preXPos = 0, preYPos = 0;
 | 
	
		
			
				|  |  | +                for (let idx = 0; idx < content.values.length; idx++) {
 | 
	
		
			
				|  |  | +					let xPos = figure.area.Left + xStepW * idx + xStepW / 2 + this.offsetX;
 | 
	
		
			
				|  |  | +					let yPos = figure.area.Bottom - (content.values[idx] / content.maxValue) * height + this.offsetY;
 | 
	
		
			
				|  |  | +                    doc.setLineWidth(0.8);
 | 
	
		
			
				|  |  | +                    doc.setDrawColor(content.color);
 | 
	
		
			
				|  |  | +                    if (content.style === 'dash') doc.setLineDash([10, 5]);
 | 
	
		
			
				|  |  | +                    switch (figure.config.dispType) {
 | 
	
		
			
				|  |  | +						case 'line':
 | 
	
		
			
				|  |  | +							//折线图
 | 
	
		
			
				|  |  | +							if (idx > 0) {
 | 
	
		
			
				|  |  | +								// ctx.lineTo(xPos, yPos);
 | 
	
		
			
				|  |  | +                                doc.line(preXPos * PDF_SCALE, preYPos * PDF_SCALE, xPos * PDF_SCALE, yPos * PDF_SCALE);
 | 
	
		
			
				|  |  | +							}
 | 
	
		
			
				|  |  | +                            preXPos = xPos;
 | 
	
		
			
				|  |  | +                            preYPos = yPos;
 | 
	
		
			
				|  |  | +						break;
 | 
	
		
			
				|  |  | +						case 'pole':
 | 
	
		
			
				|  |  | +							//柱图
 | 
	
		
			
				|  |  | +						break;
 | 
	
		
			
				|  |  | +						default:
 | 
	
		
			
				|  |  | +							//....
 | 
	
		
			
				|  |  | +						break;
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +	drawToPdf: function(doc, currentPageData) {
 | 
	
		
			
				|  |  | +		//导出PDF用
 | 
	
		
			
				|  |  | +		if (doc && currentPageData) {
 | 
	
		
			
				|  |  | +			if (currentPageData.figure_cells && currentPageData.figure_cells.length > 0) {
 | 
	
		
			
				|  |  | +				for (let figure of currentPageData.figure_cells) {
 | 
	
		
			
				|  |  | +					this._drawPdf(doc, figure);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	},
 | 
	
		
			
				|  |  | +    _drawSvg: function(figure, isHtoV, actArea) {
 | 
	
		
			
				|  |  | +        let rst = [];
 | 
	
		
			
				|  |  | +        if (figure.imageData) {
 | 
	
		
			
				|  |  | +			//直接图形输出
 | 
	
		
			
				|  |  | +		} else {
 | 
	
		
			
				|  |  | +			let width = figure.area.Right - figure.area.Left;
 | 
	
		
			
				|  |  | +			let height = figure.area.Bottom - figure.area.Top;
 | 
	
		
			
				|  |  | +			let xSteps = figure.coordinateAxis.axisX.steps;
 | 
	
		
			
				|  |  | +			let ySteps = figure.coordinateAxis.axisY.steps;
 | 
	
		
			
				|  |  | +			let xStepW = width / xSteps;
 | 
	
		
			
				|  |  | +			let yStepH = height / ySteps;
 | 
	
		
			
				|  |  | +            if (figure.coordinateAxis.axisX.isShowLine) {
 | 
	
		
			
				|  |  | +                //画竖线
 | 
	
		
			
				|  |  | +                for (let idx = 0; idx < xSteps; idx++) {
 | 
	
		
			
				|  |  | +                    rst.push("<line x1='" + Math.round(figure.area.Left + xStepW * (idx + 1) + this.offsetX) + "' y1='" + (figure.area.Bottom + this.offsetY) +
 | 
	
		
			
				|  |  | +                            "' x2='" + Math.round(figure.area.Left + xStepW * (idx + 1) + this.offsetX) + "' y2='" + (figure.area.Top + this.offsetY) +
 | 
	
		
			
				|  |  | +                            "' style='stroke:rgb(0,0,0);stroke-width:1'" + HtoVStr + "/>")
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            if (figure.coordinateAxis.axisY.isShowLine) {
 | 
	
		
			
				|  |  | +                //画横线
 | 
	
		
			
				|  |  | +                for (let idx = 0; idx < ySteps; idx++) {
 | 
	
		
			
				|  |  | +                    rst.push("<line x1='" + (figure.area.Left + this.offsetX) + "' y1='" + Math.round(figure.area.Bottom - yStepH * (idx + 1) + this.offsetY) +
 | 
	
		
			
				|  |  | +                            "' x2='" + (figure.area.Right + this.offsetX) + "' y2='" + Math.round(figure.area.Bottom - yStepH * (idx + 1) + this.offsetY) +
 | 
	
		
			
				|  |  | +                            "' style='stroke:rgb(0,0,0);stroke-width:1'" + HtoVStr + "/>")
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            let HtoVStr = "";
 | 
	
		
			
				|  |  | +            if (isHtoV) {
 | 
	
		
			
				|  |  | +                //引用了padding后,top坐标不用考虑offset了
 | 
	
		
			
				|  |  | +                HtoVStr = ` transform="translate(${(actArea.Bottom - actArea.Top + 2)},0) rotate(90)"`;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            for (let ctIdx = 0; ctIdx < figure.contents.length; ctIdx++) {
 | 
	
		
			
				|  |  | +				const content = figure.contents[ctIdx];
 | 
	
		
			
				|  |  | +                let pointStr = '';
 | 
	
		
			
				|  |  | +                let stroke_dasharray = '';
 | 
	
		
			
				|  |  | +                // ctx.strokeStyle = content.color;
 | 
	
		
			
				|  |  | +                if (content.style === 'dash') stroke_dasharray = `10 5`;
 | 
	
		
			
				|  |  | +                for (let idx = 0; idx < content.values.length; idx++) {
 | 
	
		
			
				|  |  | +					let xPos = figure.area.Left + xStepW * idx + xStepW / 2 + this.offsetX;
 | 
	
		
			
				|  |  | +					let yPos = figure.area.Bottom - (content.values[idx] / content.maxValue) * height + this.offsetY;
 | 
	
		
			
				|  |  | +                    if (idx > 0) pointStr = pointStr + ',';
 | 
	
		
			
				|  |  | +                    pointStr = pointStr + `${xPos},${yPos}`;
 | 
	
		
			
				|  |  | +                    switch (figure.config.dispType) {
 | 
	
		
			
				|  |  | +						case 'line':
 | 
	
		
			
				|  |  | +							//折线图
 | 
	
		
			
				|  |  | +							if (idx === content.values.length - 1) {
 | 
	
		
			
				|  |  | +								// ctx.moveTo(xPos, yPos);
 | 
	
		
			
				|  |  | +                                rst.push("<polyline points='" + pointStr +
 | 
	
		
			
				|  |  | +                                        "' style='fill:none;stroke:" + content.color + ";stroke-width:1;stroke-dasharray:" + stroke_dasharray + "'" + HtoVStr + "/>")
 | 
	
		
			
				|  |  | +							}
 | 
	
		
			
				|  |  | +						break;
 | 
	
		
			
				|  |  | +						case 'pole':
 | 
	
		
			
				|  |  | +							//柱图
 | 
	
		
			
				|  |  | +						break;
 | 
	
		
			
				|  |  | +						default:
 | 
	
		
			
				|  |  | +							//....
 | 
	
		
			
				|  |  | +						break;
 | 
	
		
			
				|  |  | +					}
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +        return rst;
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +	toSvgData: function(currentPageData, isHtoV, actArea) {
 | 
	
		
			
				|  |  | +		//打印用
 | 
	
		
			
				|  |  | +        let rst = [];
 | 
	
		
			
				|  |  | +		if (currentPageData) {
 | 
	
		
			
				|  |  | +			if (currentPageData.figure_cells && currentPageData.figure_cells.length > 0) {
 | 
	
		
			
				|  |  | +				for (let figure of currentPageData.figure_cells) {
 | 
	
		
			
				|  |  | +					rst = rst.concat(this._drawSvg(figure, isHtoV, actArea));
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +        return rst;
 | 
	
		
			
				|  |  | +	},
 | 
	
		
			
				|  |  | +	toImageData: function(canvas, pageData) {
 | 
	
		
			
				|  |  | +		//导出Excel用
 | 
	
		
			
				|  |  | +		if (canvas && pageData) {
 | 
	
		
			
				|  |  | +			const ctx = canvas.getContext("2d");
 | 
	
		
			
				|  |  | +            for (let currentPageData of pageData.items) {
 | 
	
		
			
				|  |  | +                if (currentPageData.figure_cells && currentPageData.figure_cells.length > 0) {
 | 
	
		
			
				|  |  | +                    for (let fIdx = 0; fIdx < currentPageData.figure_cells.length; fIdx++) {
 | 
	
		
			
				|  |  | +                        this._draw(ctx, currentPageData.figure_cells[fIdx], true);
 | 
	
		
			
				|  |  | +                        // if (fIdx === currentPageData.figure_cells.length - 1) {
 | 
	
		
			
				|  |  | +                        //     this._draw(ctx, currentPageData.figure_cells[fIdx], true);
 | 
	
		
			
				|  |  | +                        // } else {
 | 
	
		
			
				|  |  | +                        //     this._draw(ctx, currentPageData.figure_cells[fIdx], false);
 | 
	
		
			
				|  |  | +                        // }
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	},
 | 
	
		
			
				|  |  | +    getBase64: function(canvas, currentPageData) {
 | 
	
		
			
				|  |  | +        let rst = null;
 | 
	
		
			
				|  |  | +        if (canvas && currentPageData) {
 | 
	
		
			
				|  |  | +            const ctx = canvas.getContext("2d");
 | 
	
		
			
				|  |  | +            if (currentPageData.figure_cells && currentPageData.figure_cells.length > 0) {
 | 
	
		
			
				|  |  | +                for (let fIdx = 0; fIdx < currentPageData.figure_cells.length - 1; fIdx++) {
 | 
	
		
			
				|  |  | +                    if (fIdx === currentPageData.figure_cells.length - 1) {
 | 
	
		
			
				|  |  | +                        canvas.width = figure.area.Right - figure.area.Left;
 | 
	
		
			
				|  |  | +                        canvas.height = figure.area.Bottom - figure.area.Top;
 | 
	
		
			
				|  |  | +                        ctx.putImageData(figure.imageData, 0, 0);
 | 
	
		
			
				|  |  | +                        rst = canvas.toDataURL();
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        return rst;
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +};
 |