| | |
| | | return { |
| | | summary: { |
| | | taskCount: 0, |
| | | taskStartTime: null, |
| | | taskStartTime$: "", |
| | | taskEndTime: null, |
| | | taskEndTime$: "", |
| | | taskDurationMs: null, |
| | | avgTaskBeatDurationMs: null, |
| | | avgTotalDurationMs: null, |
| | | avgStationDurationMs: null, |
| | | avgCraneDurationMs: null, |
| | |
| | | window.html2canvas(visualRoot, this.buildCaptureOptions(visualRoot)), |
| | | window.html2canvas(detailRoot, this.buildCaptureOptions(detailRoot)) |
| | | ]).then(function (results) { |
| | | var visualAvoidSplitBounds = self.collectAvoidSplitBounds(visualRoot, results[0], [ |
| | | ".quality-banner", |
| | | ".chart-card" |
| | | ]); |
| | | self.appendCanvasSlicesToPdf(pdf, results[0], { |
| | | margin: 8, |
| | | startY: 8, |
| | | addNewPage: false |
| | | addNewPage: false, |
| | | avoidSplitBounds: visualAvoidSplitBounds |
| | | }); |
| | | self.appendDetailTableToPdf(pdf, results[1], detailRoot, detailTable, 8); |
| | | pdf.save(self.buildPdfFileName()); |
| | |
| | | while (renderedHeight < canvas.height) { |
| | | var currentPageHeightPx = Math.max(1, Math.floor((pageHeight - margin - currentY) * pxPerMm)); |
| | | var sliceHeight = Math.min(currentPageHeightPx, canvas.height - renderedHeight); |
| | | sliceHeight = this.resolveSliceHeight(renderedHeight, sliceHeight, settings.avoidSplitBounds); |
| | | pageCanvas.width = canvas.width; |
| | | pageCanvas.height = sliceHeight; |
| | | pageContext.fillStyle = "#ffffff"; |
| | |
| | | renderedHeight += sliceHeight; |
| | | currentY = margin; |
| | | } |
| | | }, |
| | | collectAvoidSplitBounds: function (rootElement, rootCanvas, selectors) { |
| | | if (!rootElement || !rootCanvas || !selectors || !selectors.length) { |
| | | return []; |
| | | } |
| | | var rootRect = rootElement.getBoundingClientRect(); |
| | | if (!rootRect.width) { |
| | | return []; |
| | | } |
| | | var scale = rootCanvas.width / rootRect.width; |
| | | var elements = []; |
| | | selectors.forEach(function (selector) { |
| | | Array.prototype.push.apply(elements, Array.prototype.slice.call(rootElement.querySelectorAll(selector))); |
| | | }); |
| | | return elements.map(function (element) { |
| | | var rect = element.getBoundingClientRect(); |
| | | return { |
| | | top: Math.max(0, Math.round((rect.top - rootRect.top) * scale)), |
| | | bottom: Math.max(0, Math.round((rect.bottom - rootRect.top) * scale)) |
| | | }; |
| | | }).filter(function (item) { |
| | | return item.bottom > item.top; |
| | | }).sort(function (a, b) { |
| | | return a.top - b.top; |
| | | }); |
| | | }, |
| | | resolveSliceHeight: function (renderedHeight, desiredHeight, avoidSplitBounds) { |
| | | if (!avoidSplitBounds || !avoidSplitBounds.length) { |
| | | return desiredHeight; |
| | | } |
| | | var sliceEnd = renderedHeight + desiredHeight; |
| | | var adjustedHeight = desiredHeight; |
| | | avoidSplitBounds.forEach(function (bound) { |
| | | if (bound.top <= renderedHeight) { |
| | | return; |
| | | } |
| | | if (bound.top >= sliceEnd || bound.bottom <= sliceEnd) { |
| | | return; |
| | | } |
| | | var candidateHeight = bound.top - renderedHeight; |
| | | if (candidateHeight > 0 && candidateHeight < adjustedHeight) { |
| | | adjustedHeight = candidateHeight; |
| | | } |
| | | }); |
| | | return adjustedHeight > 0 ? adjustedHeight : desiredHeight; |
| | | }, |
| | | appendDetailTableToPdf: function (pdf, rootCanvas, detailRoot, detailTable, margin) { |
| | | var tbody = detailTable && detailTable.tBodies && detailTable.tBodies[0]; |
| | |
| | | } |
| | | }, |
| | | legend: { data: ["站点耗时", "堆垛机耗时", "总耗时"] }, |
| | | grid: { left: 50, right: 20, top: 40, bottom: 70 }, |
| | | grid: { left: 88, right: 20, top: 40, bottom: 70, containLabel: true }, |
| | | xAxis: { |
| | | type: "category", |
| | | data: rows.map(function (item) { return String(item.wrkNo); }), |
| | |
| | | } |
| | | }, |
| | | legend: { data: ["平均总耗时", "平均站点耗时", "平均堆垛机耗时"] }, |
| | | grid: { left: 50, right: 20, top: 40, bottom: 70 }, |
| | | grid: { left: 88, right: 20, top: 40, bottom: 70, containLabel: true }, |
| | | xAxis: { |
| | | type: "category", |
| | | data: rows.map(function (item) { return item.bucketLabel; }), |
| | |
| | | return lines.join("<br>"); |
| | | } |
| | | }, |
| | | grid: { left: 50, right: 20, top: 20, bottom: 40 }, |
| | | grid: { left: 88, right: 20, top: 20, bottom: 68, containLabel: true }, |
| | | xAxis: { |
| | | type: "category", |
| | | data: rows.map(function (item) { return item.name; }) |
| | | data: rows.map(function (item) { return item.name; }), |
| | | axisLabel: { |
| | | interval: 0, |
| | | rotate: rows.length > 6 ? 30 : 0 |
| | | } |
| | | }, |
| | | yAxis: { |
| | | type: "value", |
| | |
| | | if (!isFinite(num)) { |
| | | return "0s"; |
| | | } |
| | | var text = String(num); |
| | | if (text.indexOf(".") >= 0) { |
| | | text = text.replace(/0+$/, "").replace(/\.$/, ""); |
| | | } |
| | | return text + "s"; |
| | | return this.formatDurationBySeconds(num); |
| | | }, |
| | | formatDuration: function (value) { |
| | | if (value === null || value === undefined || value === "") { |
| | |
| | | if (ms < 1000) { |
| | | return Math.round(ms) + " ms"; |
| | | } |
| | | var totalSeconds = Math.floor(ms / 1000); |
| | | var hours = Math.floor(totalSeconds / 3600); |
| | | var minutes = Math.floor((totalSeconds % 3600) / 60); |
| | | var seconds = totalSeconds % 60; |
| | | return this.formatDurationBySeconds(ms / 1000); |
| | | }, |
| | | formatDurationBySeconds: function (seconds) { |
| | | var totalSeconds = Number(seconds || 0); |
| | | if (!isFinite(totalSeconds)) { |
| | | return "0s"; |
| | | } |
| | | var safeSeconds = Math.max(0, totalSeconds); |
| | | if (safeSeconds < 60) { |
| | | return this.trimTrailingZeros(safeSeconds) + "s"; |
| | | } |
| | | var hours = Math.floor(safeSeconds / 3600); |
| | | var minutes = Math.floor((safeSeconds % 3600) / 60); |
| | | var remainSeconds = safeSeconds - hours * 3600 - minutes * 60; |
| | | var secondText = this.trimTrailingZeros(remainSeconds); |
| | | if (hours > 0) { |
| | | return hours + "h " + this.pad(minutes) + "m " + this.pad(seconds) + "s"; |
| | | return hours + "h" + this.pad(minutes) + "m" + this.padSeconds(secondText) + "s"; |
| | | } |
| | | if (minutes > 0) { |
| | | return minutes + "m " + this.pad(seconds) + "s"; |
| | | return minutes + "m" + this.padSeconds(secondText) + "s"; |
| | | }, |
| | | trimTrailingZeros: function (value) { |
| | | var text = String(Number(Number(value).toFixed(3))); |
| | | if (text.indexOf(".") >= 0) { |
| | | text = text.replace(/0+$/, "").replace(/\.$/, ""); |
| | | } |
| | | return seconds + "s"; |
| | | return text; |
| | | }, |
| | | padSeconds: function (value) { |
| | | var text = String(value); |
| | | if (text.indexOf(".") >= 0) { |
| | | var parts = text.split("."); |
| | | return (parts[0].length < 2 ? "0" + parts[0] : parts[0]) + "." + parts[1]; |
| | | } |
| | | return text.length < 2 ? "0" + text : text; |
| | | } |
| | | } |
| | | }); |