|
@@ -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;
|
|
|
+ },
|
|
|
+};
|