echarts 主要用的是this.myChart.getDataURL方法,
画布截取 是convertImageToCanvas方法
代码里的是之前写的画布截取,后来改成Echarts
画布截图参考链接https://ask.csdn.net/questions/7733013https://ask.csdn.net/questions/7733013
Vue中使用js-web-screen-shot插件实现截屏功能_时间的情敌的博客-CSDN博客
画布效果
<template>
<el-dialog title="异常情况" :visible.sync="dialogVisible" @open="openDialog" @close="closeDialog" width="900px">
<div slot="title" class="header-title">
<div class="normal-title">异常情况</div>
<div class="tip-title" v-if="showTip">
<i class="el-icon-warning-outline" />
<span>异常数据默认保存30天,重要的记录请点击弹窗右下角“保存”</span>
</div>
</div>
<!-- 折线图 -->
<div id="chart" ref="chart" v-loading="showLoading" v-if="showTip" />
<div class="image" v-if="showImage">
<img ref="img" :src="url" alt="" />
</div>
<div class="empty" v-if="showEmpty">
<div class="empty-tip">该项异常数据30天内未保存,已清除。</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button
@click="saveScreenshot"
size="small"
v-if="showTip"
>保 存</el-button
>
<el-button @click="dialogVisible = false" size="small" v-if="!showTip && !showEmpty"
>取 消</el-button
>
<el-button type="primary" @click="dialogVisible = false" size="small"
>确 定</el-button
>
</span>
<cropper ref="cropper" />
</el-dialog>
</template>
<script>
import * as echarts from "echarts";
import ScreenShort from "js-web-screen-shot";
import { visualChart } from "./visualCharts.js";
import {
GetWarningVisual,
PostImage,
PostBackUp,
PostDownloadImage,
} from "@/api/warningProcess.js";
import cropper from "./cropper.vue";
export default {
components: { cropper },
data() {
return {
dialogVisible: false,
showLoading: false,
url: "", // blob图片
myChart: "",
showTip: false, // header提示语,true:30天之内
showImage: false, // 图片展示
showEmpty: false, // 空展示
id: 0,
filename: "", // 图片名称-下载
data: [], // 图例数据
choosePointSpecies: ['风速测点', '温度测点'], //TODO:测试,选择的种类 eg:['风速测点', '温度测点']
chooseEquipmentNameLength: 1,
lineMap: {}, // 测试无用
showMarkLine:false, // 辅助线展示
choosePointMap: {}, // 测试无用
uploadlist: [], // 截图
};
},
methods: {
// 获取异常折线图数据
async getWarningVisual() {
this.data = [];
this.showLoading = true;
const { data } = await GetWarningVisual(this.id);
this.data = data.data || [];
this.showLoading = false;
this.initEcharts();
},
// 图表
initEcharts() {
let chartDom = document.getElementById("chart");
this.myChart = echarts.init(chartDom);
visualChart &&
this.myChart.setOption(
visualChart(
this.data,
this.choosePointSpecies,
this.chooseEquipmentNameLength,
this.lineMap,
this.choosePointMap,
this.showMarkLine
)
);
window.addEventListener("resize", () => {
if (this.myChart) {
this.myChart.resize();
}
});
},
// 截图操作
saveScreenshot() {
this.uploadlist = [];
// 弹窗截图,更优雅,后面详细研究,组件是cropper.vue // 实现1:弹窗截图
// this.$refs.cropper.dialogVisible = true;
// const screenShotHandler = new ScreenShort({ // 实现2:类似微信选中区域截图
// enableWebRtc: false, //是否显示选项框
// level: 99999999, //层级级别
// completeCallback: this.callback,
// closeCallback: this.closeFn,
// });
const picInfo = this.myChart.getDataURL({
// 导出的格式,可选 png, jpg, svg
// 注意:png, jpg 只有在 canvas 渲染器的时候可使用,svg 只有在使用 svg 渲染器的时候可用
type:'svg',
// 导出的图片分辨率比例,默认为 1。
pixelRatio: 1,
// 导出的图片背景色,默认使用 option 里的 backgroundColor
backgroundColor: '#fff',
// 忽略组件的列表,例如要忽略 toolbox 就是 ['toolbox']
excludeComponents: 'toolbox'
});
let file = this.base64ImgtoFile(picInfo)
this.postImage(file);
},
callback(base64data) {
let file = this.base64ImgtoFile(base64data);
this.postImage(file);
let _this = this;
var image = new Image();
image.src = base64data;
image.onload = () => {
var canvas = _this.convertImageToCanvas(image);
var url = canvas.toDataURL("image/jpeg");
_this.uploadlist.push({ image: url });
for (var i = 0; i < _this.uploadlist.length; i++) {
if (_this.uploadlist.length >= 6) {
_this.uploadhide = false;
}
}
this.$message({
type: "success",
message: "截图成功",
});
};
},
/**
* 根据图片生成画布
*/
convertImageToCanvas(image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext("2d").drawImage(image, 0, 0);
return canvas;
},
// base64编码的图片
base64ImgtoFile(dataurl, filename = "file") {
let arr = dataurl.split(",");
let mime = arr[0].match(/:(.*?);/)[1];
let suffix = mime.split("/")[1];
let bstr = atob(arr[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], `${filename}.${suffix}`, {
type: mime,
});
},
// 将base64的图片转换为file文件
convertBase64UrlToBlob(urlData) {
let bytes = window.atob(urlData.split(",")[1]); //去掉url的头,并转换为byte
//处理异常,将ascii码小于0的转换为大于0
let ab = new ArrayBuffer(bytes.length);
let ia = new Uint8Array(ab);
for (var i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], { type: "image/jpeg" });
},
// 上传截图
async postImage(file) {
const formData = new FormData();
formData.append("file", file);
formData.append("module", "warning-content");
const { data } = await PostImage(formData);
if (data.code === 200) {
this.postBackUp(data.data.fileName);
this.$message.success("图片保存成功")
}
},
// 下载截图
async PostDownloadImage() {
let params = {
module: "warning-content",
fileName: this.fileName,
};
const { data } = await PostDownloadImage(params);
// 二进制流转blob
this.url = window.URL.createObjectURL(new Blob([data]));
},
// 图片备份
async postBackUp(val) {
let params = {
warningId: this.id,
fileName: val,
};
const { data } = await PostBackUp(params);
},
// 打开弹窗
openDialog() {
if (this.showTip) {
// 30天内,展示echarts图
this.getWarningVisual();
} else {
// 展示图片
this.PostDownloadImage();
}
},
// 关闭弹框
closeDialog(){
this.url = ''
this.showTip = false;
this.showImage = false;
this.showEmpty = false;
}
},
};
</script>
<style lang="less" scoped>
#chart {
width: 850px;
height: 300px;
}
.header-title {
display: flex;
flex-direction: row;
align-items: center;
.normal-title {
font-size: 16px;
font-family: PingFang SC-Medium, PingFang SC;
font-weight: 500;
color: #18253d;
line-height: 24px;
padding-right: 20px;
}
.tip-title {
color: #959fb2;
span {
padding-left: 3px;
}
}
}
.empty {
height: 200px;
font-size: 24px;
.empty-tip{
display: flex;
justify-content: center;
padding-top: 80px;
}
}
</style>