看了网上的各种方案,目前大家采用的大概有 3 种👇
方案 | 实现方式 | 优点 | 缺点 |
---|---|---|---|
vw vh | 1.按照设计稿的尺寸,将px 按比例计算转为vw 和vh | 1.可以动态计算图表的宽高,字体等,灵活性较高 2.当屏幕比例跟 ui 稿不一致时,不会出现两边留白情况 | 1.每个图表都需要单独做字体、间距、位移的适配,比较麻烦 |
scale | 1.通过 scale 属性,根据屏幕大小,对图表进行整体的等比缩放 | 1.代码量少,适配简单 2.一次处理后不需要在各个图表中再去单独适配 | 1.因为是根据 ui 稿等比缩放,当大屏跟 ui 稿的比例不一样时,会出现周边留白情况 2.当缩放比例过大时候,字体会有一点点模糊,就一点点 3.当缩放比例过大时候,事件热区会偏移。 |
rem + vw vh | 1.获得 rem 的基准值 2.动态的计算 html根元素的font-size 3.图表中通过 vw vh 动态计算字体、间距、位移等 | 1.布局的自适应代码量少,适配简单 | 1.因为是根据 ui 稿等比缩放,当大屏跟 ui 稿的比例不一样时,会出现周边留白情况 2.图表需要单个做字体、间距、位移的适配 |
以上 3 种方案在实际应用中该怎么选择视具体情况而定。
- 如果想简单,客户能同意留白,选用
scale
即可- 如果需要兼容不同比例的大屏,并且想在不同比例中都有比较好的效果,图表占满屏幕,类似于移动端的响应式,可以采用 vw vh 的方案
- 至于 rem,个人觉得就是 scale 和 vw vh 的综合,最终的效果跟
scale
差不多
接下来展示的是vw vh方案实现步骤:
实现思路
按照设计稿的尺寸,将px
按比例计算转为vw
和vh
,转换公式如下
假设设计稿尺寸为 1920*1080(做之前一定问清楚 ui 设计稿的尺寸)
即:
网页宽度=1920px
网页高度=1080px我们都知道
网页宽度=100vw
网页宽度=100vh所以,在 1920px*1080px 的屏幕分辨率下
1920px = 100vw
1080px = 100vh
这样一来,以一个宽 300px 和 200px 的 div 来说,其所占的宽高,以 vw 和 vh 为单位,计算方式如下:
vwDiv = (300px / 1920px ) * 100vw
vhDiv = (200px / 1080px ) * 100vh所以,就在 1920*1080 的屏幕分辨率下,计算出了单个 div 的宽高
当屏幕放大或者缩小时,div 还是以 vw 和 vh 作为宽高的,就会自动适应不同分辨率的屏幕
css 方案 - sass
util.scss
// 使用 scss 的 math 函数,https://sass-lang.com/documentation/breaking-changes/slash-div
@use "sass:math";
// 默认设计稿的宽度
$designWidth: 1920;
// 默认设计稿的高度
$designHeight: 1080;
// px 转为 vw 的函数
@function vw($px) {
@return math.div($px, $designWidth) * 100vw;
}
// px 转为 vh 的函数
@function vh($px) {
@return math.div($px, $designHeight) * 100vh;
}
路径配置
只需在vue.config.js
里配置一下utils.scss
的路径,就可以全局使用了
vue.config.js
const path = require("path");
function resolve(dir) {
return path.join(__dirname, dir);
}
module.exports = {
publicPath: "",
configureWebpack: {
name: "app name",
resolve: {
alias: {
"@": resolve("src"),
},
},
},
css: {
// 全局配置 utils.scs,详细配置参考 vue-cli 官网
loaderOptions: {
sass: {
prependData: `@import "@/styles/utils.scss";`,
},
},
},
};
vite:
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "@/styles/util.scss";`,
},
},
},
在 .vue 中使用
<template>
<div class="box">
</div>
</template>
<script>
export default{
name: "Box",
}
</script>
<style lang="scss" scoped="scoped">
/*
直接使用 vw 和 vh 函数,将像素值传进去,得到的就是具体的 vw vh 单位
*/
.box{
width: vw(300);
height: vh(100);
font-size: vh(16);
background-color: black;
margin-left: vw(10);
margin-top: vh(10);
border: vh(2) solid red;
}
</style>
css 方案 - less
utils.less
@charset "utf-8";
// 默认设计稿的宽度
@designWidth: 1920;
// 默认设计稿的高度
@designHeight: 1080;
.px2vw(@name, @px) {
@{name}: (@px / @designWidth) * 100vw;
}
.px2vh(@name, @px) {
@{name}: (@px / @designHeight) * 100vh;
}
.px2font(@px) {
font-size: (@px / @designWidth) * 100vw;
}
路径配置
在vue.config.js
里配置一下utils.less
const path = require("path");
function resolve(dir) {
return path.join(__dirname, dir);
}
module.exports = {
publicPath: "",
configureWebpack: {
name: "app name",
resolve: {
alias: {
"@": resolve("src"),
},
},
},
css: {
// 全局配置utils.scss
loaderOptions: {
less: {
additionalData: `@import "@/styles/utils.less";`,
},
},
},
};
在 .vue 文件中使用
<template>
<div class="box">
</div>
</template>
<script>
export default{
name: "Box",
}
</script>
<style lang="less" scoped="scoped">
/*
直接使用 vw 和 vh 函数,将像素值传进去,得到的就是具体的 vw vh单位
*/
.box{
.px2vw(width, 300);
.px2vh(height, 100);
.px2font(16);
.px2vw(margin-left, 300);
.px2vh(margin-top, 100);
background-color: black;
}
</style>
定义 js 样式处理函数
// 定义设计稿的宽高
const designWidth = 1920;
const designHeight = 1080;
// px转vw
export const px2vw = (_px) => {
return (_px * 100.0) / designWidth + 'vw';
};
export const px2vh = (_px) => {
return (_px * 100.0) / designHeight + 'vh';
};
export const px2font = (_px) => {
return (_px * 100.0) / designWidth + 'vw';
};
屏幕变化后,图表自动调整
这种使用方式有个弊端,就是屏幕尺寸发生变化后,需要手动刷新一下才能完成自适应调整
为了解决这个问题,你需要在各个图表中监听页面尺寸变化,重新调整图表,在 vue 项目中,也可以借助element-resize-detector
,最好封装个 resize 的指令,在各图表中就只要使用该指令就可以了,毕竟作为程序员,能偷懒就偷懒
1.安装 element-resize-detector
npm install element-resize-detector --save
2.引入工具包在组件中使用或者在单独的 js 中使用
import resizeDetector from 'element-resize-detector'
3.封装 directive
// directive.js
import * as ECharts from "echarts";
import elementResizeDetectorMaker from "element-resize-detector";
import Vue from "vue";
const HANDLER = "_vue_resize_handler";
function bind(el, binding) {
el[HANDLER] = binding.value
? binding.value
: () => {
let chart = ECharts.getInstanceByDom(el);
if (!chart) {
return;
}
chart.resize();
};
// 监听绑定的div大小变化,更新 echarts 大小
elementResizeDetectorMaker().listenTo(el, el[HANDLER]);
}
function unbind(el) {
// window.removeEventListener("resize", el[HANDLER]);
elementResizeDetectorMaker().removeListener(el, el[HANDLER]);
delete el[HANDLER];
}
// 自定义指令:v-chart-resize 示例:v-chart-resize="fn"
Vue.directive("chart-resize", { bind, unbind });
4.main.js 中引入
import '@/directive/directive';
5.html 代码
<template>
<div class="linechart">
<div ref="chart" v-chart-resize class="chart"></div>
</div>
</template>
这里要注意的是,图表中如果需要 tab 切换动态更新图表数据,在更新数据时一定不要用 echarts 的 dispose 方法先将图表移除,再重新绘制,因为 resize 指令中挂载到的图表实例还是旧的,就监听不到新的 chart 元素的 resize 了,更新数据只需要用 chart 的 setOption 方法重新设置配置项即可。
图表字体、间距、位移等尺寸自适应
echarts 的字体大小只支持具体数值(像素),不能用百分比或者 vw 等尺寸,一般字体不会去做自适应,当宽高比跟 ui 稿比例出入太大时,会出现文字跟图表重叠的情况
这里我们就需要封装一个工具函数,来处理图表中文字自适应了👇
-
默认情况下,这里以你的设计稿是 1920*1080 为例,即网页宽度是 1920px (做之前一定问清楚 ui 设计稿的尺寸)
-
把这个函数写在一个单独的工具文件
dataUtil.js
里面,在需要的时候调用 -
其原理是计算出当前屏幕宽度和默认设计宽度的比值,将原始的尺寸乘以该值
-
另外,其它 echarts 的配置项,比如间距、定位、边距也可以用该函数
1.编写 dataUtil.js 工具函数
// Echarts图表字体、间距自适应
export const fitChartSize = (size,defalteWidth = 1920) => {
let clientWidth = window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;
if (!clientWidth) return size;
let scale = (clientWidth / defalteWidth);
return Number((size*scale).toFixed(3));
}
/********如果你有带鱼屏的适配,需要改为以vh高度计算的********/
// 1080高度计算
export const fitChartSize = (size, defaultHeight = 1080) => {
let clientHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
if (!clientHeight) return size;
let scale = (clientHeight / defaultHeight);
return Number((size * scale).toFixed(3));
}
2.将函数挂载到原型上
import {fitChartSize} from '@src/utils/dataUtil.js'
Vue.prototype.fitChartFont = fitChartSize;
/********vue3写法********/
import { fitChartSize } from '@/utils/dataUtil.js'
// 添加全局方法
app.config.globalProperties.$fitChartSize = fitChartSize;
const { proxy } = getCurrentInstance();
proxy.$fitChartSize(2)
示例代码:
// 装卸能耗分析
<template>
<div class="all">
<div class="all_title">
<span class="all_title_txt">装卸能耗分析</span>
<img class="dateBg" src="../../assets/images/dateBg.png" alt="" oncontextmenu="return false"
draggable="false">
</div>
<div class="all_bod" id="echarts2"></div>
</div>
</template>
<script setup name="box8">
const { proxy } = getCurrentInstance();
import { ref, reactive, watch, onMounted, onUnmounted, nextTick } from "vue";
// const { fitChartSize } = proxy.$fitChartSize();
// let currentIndex = ref(0)
// let chart = ref(null);
let timeTicket = ref(null);
let timer = ref(null);
const props = defineProps({
allData: {
type: Object,
required: true
}
});
// 监听 allData 的变化
watch(() => props.allData, (newVal) => {
// console.log("echarts8接收到值", newVal)
let myData8 = [];
let tss = [];
let dcl = [];
// let myData8 = ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"];
// let tss = [60, 80, 20, 40, 60, 40, 50, 50, 60, 32, 52, 55, 60];
// let dcl = [40, 55, 50, 60, 30, 20, 60, 30, 20, 10, 30, 20];
newVal.forEach(item => {
myData8.push(item.time)
tss.push(item.energyConsumption)
dcl.push(item.thruput)
})
setTimeout(() => {
initChart(myData8, tss, dcl)
}, 500)
});
// window.addEventListener('resize', function () {
// // const innerWidth = window.innerWidth
// // const innerHeight = window.innerHeight
// // console.log("resize", proxy.$fitChartSize(14))
// chart.resize();
// });
onUnmounted(() => {
if (timer.value) clearInterval(timer.value);
})
// onMounted(() => {
// setTimeout(() => {
// console.log(6666, proxy.$fitChartSize(14))
// }, 500)
// })
// 计算样式
// const computedSize = computed(() => {
// let clientWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
// let clientHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
// let objFun = {};
// // 14寸笔记本
// if (clientWidth <= 1366) {
// console.log("14寸笔记本")
// // objFun.fontSize = 12; //文字大小
// // objFun.symbolSize = 3; //节点大小
// // objFun.borderWidth = 1; //线条宽度
// // objFun.itemWidth = 12; //legend方块宽度
// // objFun.itemHeight = 5; //legend方块高度
// // objFun.padding = [0, 50, 0, 0]; //右侧单位距离右侧距离
// // objFun.nameGap = 10;
// objFun.grid = {
// containLabel: true,
// bottom: "6%",
// top: "25%",
// left: "2%",
// right: "2%",
// };
// } // 全高清屏幕
// else if (clientWidth <= 1920) {
// console.log("全高清屏幕")
// // objFun.fontSize = 14; //文字大小
// // objFun.symbolSize = 5; //节点大小
// // objFun.borderWidth = 2; //线条宽度
// // objFun.itemWidth = 20; //legend方块宽度
// // objFun.itemHeight = 8; //legend方块高度
// // objFun.padding = [0, 55, 0, 0]; //右侧单位距离右侧距离
// // objFun.nameGap = 15;
// objFun.grid = {
// containLabel: true,
// bottom: "6%",
// top: "25%",
// left: "2%",
// right: "2%",
// };
// }// 2K
// else if (clientWidth <= 2560) {
// console.log("2K")
// // objFun.fontSize = 22; //文字大小
// // objFun.symbolSize = 8; //节点大小
// // objFun.borderWidth = 3; //线条宽度
// // objFun.itemWidth = 25; //legend方块宽度
// // objFun.itemHeight = 10; //legend方块高度
// // objFun.padding = [0, 85, 0, 0]; //右侧单位距离右侧距离
// // objFun.nameGap = 16;
// objFun.grid = {
// containLabel: true,
// bottom: "6%",
// top: "24%",
// left: "2%",
// right: "2%",
// };
// }// 4K 带鱼屏
// else if (clientWidth <= 3840 && clientHeight <= 1080) {
// console.log("4K 带鱼屏")
// // objFun.fontSize = 20; //文字大小
// // objFun.symbolSize = 9; //节点大小
// // objFun.borderWidth = 2.5; //线条宽度
// // objFun.itemWidth = proxy.$fitChartSize(22); //legend方块宽度
// // objFun.itemHeight = proxy.$fitChartSize(12); //legend方块高度
// // objFun.padding = [0, 60, 0, 0]; //右侧单位距离右侧距离
// // objFun.nameGap = proxy.$fitChartSize(15);
// objFun.grid = {
// containLabel: true,
// bottom: "6%",
// top: proxy.$fitChartSize(60),
// left: "2%",
// right: "2%",
// };
// }// 4K
// else if (clientWidth <= 3840 && clientHeight >= 1080) {
// console.log("4K尺寸")
// // objFun.fontSize = 35; //文字大小
// // objFun.symbolSize = 20; //节点大小
// // objFun.borderWidth = 5; //线条宽度
// // objFun.itemWidth = 40; //legend方块宽度
// // objFun.itemHeight = 20; //legend方块高度
// // objFun.padding = [0, 100, 0, 0]; //右侧单位距离右侧距离
// // objFun.nameGap = 30;
// objFun.grid = {
// containLabel: true,
// bottom: "6%",
// top: "21%",
// left: "2%",
// right: "2%",
// };
// }
// return objFun;
// });
// 初始化echarts
function initChart(myData8, tss, dcl) {
const chartDom = document.getElementById('echarts2');
let chart = proxy.$echarts.init(chartDom);
// let ycl = [20, 60, 65, 20, 10, 60, 80, 25, 40, 60, 20, 40];
let option = {
title: {
text: '能耗设备',
textStyle: {
fontSize: proxy.$fitChartSize(14), // 设置文字大小
color: '#fff' // 设置文字颜色
},
},
// backgroundColor: "#041D3F",
tooltip: {
trigger: "axis",
axisPointer: {
lineStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "rgba(0, 255, 233,0)",
},
{
offset: 0.5,
color: "rgba(255, 255, 255,1)",
},
{
offset: 1,
color: "rgba(0, 255, 233,0)",
},
],
global: false,
},
},
},
textStyle: {
color: "#fff",
fontSize: proxy.$fitChartSize(14), // 设置字体大小
},
confine: true, // 限制溢出屏幕外
backgroundColor: "rgba(0,0,0,0.5)", // 设置背景颜色
padding: [10, 10, 10, 10], // 设置方框的内边距
},
// grid: computedSize.value.grid,
grid: {
containLabel: true,
bottom: proxy.$fitChartSize(0),
top: proxy.$fitChartSize(55),
left: proxy.$fitChartSize(5),
right: proxy.$fitChartSize(5),
},
legend: {
show: true,
right: 0,
top: 0,
// itemWidth: computedSize.value.itemWidth,
itemWidth: proxy.$fitChartSize(22),
// itemHeight: computedSize.value.itemHeight,
itemHeight: proxy.$fitChartSize(12),
icon: 'rect',
// itemGap: 20, // 调整图例项之间的水平间距
textStyle: {
color: '#fff',
fontSize: proxy.$fitChartSize(14),
// 设置上下居中对齐
align: 'center',
// verticalAlign: 'middle',
// color: "#B6DCF5",
// padding: [0, 0, 0, 4],
},
},
xAxis: {
data: myData8,
axisLabel: {
interval: 0,
show: true,
fontSize: proxy.$fitChartSize(14),
color: "#B6DCF5",
},
axisLine: {
show: true,
lineStyle: {
show: true,
color: "rgba(54, 153, 255, .4)",
},
},
axisTick: {
show: false,
},
},
yAxis: [
{
name: "单位:KJ",
type: "value",
// nameGap: computedSize.value.nameGap,
nameGap: proxy.$fitChartSize(15),
nameTextStyle: {
color: "#B6DCF5",
fontSize: proxy.$fitChartSize(14),
align: "center",
padding: [0, 0, 0, 0],
// padding: [0, 0, 0, proxy.$fitChartSize(50)],
},
// splitNumber: 5,
axisLabel: {
show: true,
fontSize: proxy.$fitChartSize(14),
color: "#B6DCF5",
},
axisLine: {
show: false,
lineStyle: {
color: "#7FD6FF",
},
},
axisTick: {
show: false,
},
splitLine: {
lineStyle: {
color: "rgba(54, 153, 255, .4)",
type: "dashed",
},
},
}, {
name: "单位:吨",
// offset: -25,
type: "value",
// nameGap: computedSize.value.nameGap, // 控制名称和轴之间的距离
nameGap: proxy.$fitChartSize(15), // 控制名称和轴之间的距离
nameLocation: "end",
nameTextStyle: {
color: "#B6DCF5",
fontSize: proxy.$fitChartSize(14),
align: "center",
// padding: [0, 0, 0, 0],
// padding: computedSize.value.padding,
padding: [0, proxy.$fitChartSize(50), 0, 0],
// padding: computedSize.value.padding,
},
// splitNumber: 5,
axisLabel: {
show: true,
fontSize: proxy.$fitChartSize(14),
color: "#B6DCF5",
},
axisLine: {
show: false,
lineStyle: {
color: "#7FD6FF",
},
},
axisTick: {
show: false,
},
splitLine: {
lineStyle: {
color: "rgba(54, 153, 255, .4)",
type: "dashed",
},
},
}
],
series: [
{
name: "能耗",
type: "line",
showSymbol: true,
symbolSize: proxy.$fitChartSize(6), //节点圆点大小
symbol: "circle",
lineStyle: {
normal: {
color: "#FF8E3C",
// width: computedSize.value.borderWidth, //线条宽度
width: proxy.$fitChartSize(2), //线条宽度
},
},
itemStyle: {
color: "#FF8E3C",
// borderColor: "#fff",
borderWidth: 2,
},
data: tss, // 折线图的数据
},
{
name: "吞吐量",
type: "line",
showSymbol: true,
symbol: "circle",
symbolSize: proxy.$fitChartSize(6), //节点圆点大小
lineStyle: {
normal: {
color: "#00A0E9",
// width: computedSize.value.borderWidth, //线条宽度
width: proxy.$fitChartSize(2), //线条宽度
},
},
itemStyle: {
color: "#00A0E9",
// borderColor: "#fff",
// borderWidth: 2,
borderWidth: proxy.$fitChartSize(3),
},
data: dcl, // 折线图的数据
},
// {
// name: "已处理",
// type: "line",
// showSymbol: true,
// symbolSize: 8,
// symbol: "circle",
// lineStyle: {
// normal: {
// color: "#02D6B0",
// },
// },
// itemStyle: {
// color: "#02D6B0",
// borderColor: "#fff",
// borderWidth: 2,
// },
// data: ycl, // 折线图的数据
// },
],
};
// 使用刚指定的配置项和数据显示图表。
chart.setOption(option);
// 轮播核心
handleChartLoop(option, chart);
// let index = 0; // 初始化索引
// // 使用定时器定时更新 tooltip 数据
// if (timer.value) clearInterval(timer.value);
// timer.value = setInterval(() => {
// chart.dispatchAction({
// type: "showTip", // 触发 tooltip 显示
// seriesIndex: 0, // 触发 tooltip 的系列索引
// dataIndex: index, // 触发 tooltip 的数据索引
// });
// index = (index + 1) % myData8.length; // 更新索引,循环显示数据
// }, 2000); // 每隔 2 秒更新一次
// // 鼠标移入暂停轮播
// chart.on("mousemove", () => {
// console.log("清空")
// if (timer.value) clearInterval(timer.value);
// timer.value = null;
// });
// // 鼠标移出继续轮播
// chart.on("globalout", () => {
// if (timer.value) clearInterval(timer.value);
// timer.value = setInterval(() => {
// chart.dispatchAction({
// type: "showTip", // 触发 tooltip 显示
// seriesIndex: 0, // 触发 tooltip 的系列索引
// dataIndex: index, // 触发 tooltip 的数据索引
// });
// index = (index + 1) % myData8.length; // 更新索引,循环显示数据
// }, 2000); // 每隔 2 秒更新一次
// });
window.addEventListener('resize', function () {
chart.resize();
});
}
function handleChartLoop(option, myChart) {
if (!myChart) {
return;
}
let currentIndex = -1; // 当前高亮图形在饼图数据中的下标
timeTicket.value = setInterval(selectPie, 2000); // 设置自动切换高亮图形的定时器
// 取消所有高亮并高亮当前图形
function highlightPie() {
// 遍历饼图数据,取消所有图形的高亮效果
for (var idx in option.series[0].data) {
myChart.dispatchAction({
type: "downplay",
seriesIndex: 0,
dataIndex: idx,
});
}
// 高亮当前图形
myChart.dispatchAction({
type: "highlight",
seriesIndex: 0,
dataIndex: currentIndex,
});
// 显示 tooltip
myChart.dispatchAction({
type: "showTip",
seriesIndex: 0,
dataIndex: currentIndex
})
}
// 用户鼠标悬浮到某一图形时,停止自动切换并高亮鼠标悬浮的图形
myChart.on("mouseover", (params) => {
clearInterval(timeTicket.value);
currentIndex = params.dataIndex;
highlightPie();
});
// 用户鼠标移出时,重新开始自动切换
myChart.on("mouseout", (params) => {
if (timeTicket.value) {
clearInterval(timeTicket.value);
}
timeTicket.value = setInterval(selectPie, 2000);
});
// 高亮效果切换到下一个图形
function selectPie() {
var dataLen = option.series[0].data.length;
currentIndex = (currentIndex + 1) % dataLen;
highlightPie();
}
}
</script>
<style lang="scss" scoped>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
img {
-webkit-user-drag: none;
user-drag: none;
user-select: none;
-ms-user-select: none;
}
.all {
display: flex;
flex-flow: column;
justify-content: space-between;
width: 100%;
height: 100%;
// border: 1px solid red;
// background-color: pink;
.all_title {
display: flex;
align-items: center;
justify-content: space-between;
// padding: 0 40px;
padding-right: 20px;
width: 100%;
// height: 44px;
color: #A5D8FC;
font-size: 16px;
background: url("../../assets/images/smallTitBg.png") no-repeat;
background-size: 100% 100%;
height: vh(80);
.all_title_txt {
font-size: vh(25);
transform: translate(vh(40), vh(-20));
}
.dateBg {
width: vh(30);
height: vh(30);
transform: translateY(vh(-10));
}
// span {
// transform: translateY(-8px);
// }
.dateBg {
// width: 25px;
// height: 25px;
cursor: pointer;
&:hover {
opacity: .8;
}
}
}
.all_bod {
display: flex;
flex-flow: column;
width: 100%;
// height: calc(100% - 44px);
height: calc(100% - vh(80));
}
}
// 4K 带鱼屏
// @media screen and (max-width: 3840px) and (max-height: 1080px) {
// .all_title_txt {
// font-size: 28px;
// transform: translate(50px, -20px);
// }
// .today_tit {
// font-size: 30px;
// }
// .all_title {
// height: 80px;
// }
// .all_bod {
// height: calc(100% - 80px) !important;
// }
// .dateBg {
// width: 35px;
// height: 35px;
// transform: translateY(-10px);
// }
// }
// // 4K
// @media screen and (max-width: 3840px) and (min-height: 1081px) {
// .all_title_txt {
// font-size: 50px;
// transform: translate(80px, -20px);
// }
// .today_tit {
// font-size: 50px;
// }
// .all_title {
// height: 100px;
// }
// .all_bod {
// height: calc(100% - 100px) !important;
// }
// .dateBg {
// width: 55px;
// height: 55px;
// transform: translateY(-15px);
// }
// }
// // 2K
// @media screen and (max-width: 2560px) {
// .all_title_txt {
// font-size: 35px;
// transform: translate(70px, -20px);
// }
// .today_tit {
// font-size: 32px;
// }
// .all_title {
// height: 100px;
// }
// .all_bod {
// height: calc(100% - 100px) !important;
// }
// .dateBg {
// width: 40px;
// height: 40px;
// transform: translateY(-15px);
// }
// }
// // 全高清屏幕
// @media screen and (max-width: 1920px) {
// .all_title_txt {
// font-size: 16px;
// transform: translate(30px, -10px);
// }
// .today_tit {
// font-size: 16px;
// }
// .all_title {
// height: 50px;
// }
// .all_bod {
// height: calc(100% - 50px) !important;
// }
// .dateBg {
// width: 25px;
// height: 25px;
// transform: translateY(-5px);
// }
// }
// // 14寸笔记本
// @media screen and (max-width: 1366px) {
// .all_title_txt {
// font-size: 14px;
// transform: translate(30px, -10px);
// }
// .today_tit {
// font-size: 16px;
// }
// .all_title {
// height: 50px;
// }
// .all_bod {
// height: calc(100% - 50px) !important;
// }
// .dateBg {
// width: 20px;
// height: 20px;
// transform: translateY(-5px);
// }
// }</style>
3.这样你可以在.vue文件中直接使用this.fitChartSize()调用
<template>
<div class="chartsdom" ref="chart" v-chart-resize></div>
</template>
<script>
export default {
name: "dashboardChart",
data() {
return {
option: null,
};
},
mounted() {
this.getEchart();
},
methods: {
getEchart() {
let myChart = this.$echarts.init(this.$refs.chart);
const option = {
backgroundColor: "transparent",
tooltip: {
trigger: "item",
formatter: "{a} <br/>{b} : {c}%",
},
grid: {
left: this.fitChartSize(10),
right: this.fitChartSize(20),
top: this.fitChartSize(20),
bottom: this.fitChartSize(10),
containLabel: true,
},
calculable: true,
series: [
{
color: ["#0db1cdcc"],
name: "计划投入",
type: "funnel",
width: "45%",
height: "70%",
x: "5%",
minSize: "10%",
funnelAlign: "right",
center: ["50%", "50%"], // for pie
data: [
{
value: 30,
name: "下单30%",
},
{
value: 55,
name: "咨询55%",
},
{
value: 65,
name: "点击65%",
},
{
value: 60,
name: "访问62%",
},
{
value: 80,
name: "展现80%",
},
].sort(function (a, b) {
return a.value - b.value;
}),
roseType: true,
label: {
normal: {
formatter: function () {},
position: "inside",
},
},
itemStyle: {
normal: {
borderWidth: 0,
shadowBlur: this.fitChartSize(20),
shadowOffsetX: 0,
shadowOffsetY: this.fitChartSize(5),
shadowColor: "rgba(0, 0, 0, 0.3)",
},
},
},
{
color: ["#0C66FF"],
name: "实际投入",
type: "funnel",
width: "45%",
height: "70%",
x: "50%",
minSize: "10%",
funnelAlign: "left",
center: ["50%", "50%"], // for pie
data: [
{
value: 35,
name: "下单35%",
},
{
value: 40,
name: "咨询40%",
},
{
value: 70,
name: "访问70%",
},
{
value: 90,
name: "点击90%",
},
{
value: 95,
name: "展现95%",
},
].sort(function (a, b) {
return a.value - b.value;
}),
roseType: true,
label: {
normal: {
position: "inside",
},
},
itemStyle: {
normal: {
borderWidth: 0,
shadowBlur: this.fitChartSize(20),
shadowOffsetX: 0,
shadowOffsetY: this.fitChartSize(5),
shadowColor: "rgba(0, 0, 0, 0.3)",
},
},
},
],
};
myChart.setOption(option, true);
},
},
beforeDestroy() {},
};
</script>
<style lang="scss" scoped>
.chartsdom {
width: 100%;
height: 100%;
}
</style>