最终效果
还是一个比较完美的效果。随浏览器的大小变化。(但是得刷新一下)
对比之前:
解决方案
-
legend等大小,根据宽度去调整。
fitChartSize()
-
由于是个圆,饼图半径由宽高的最小项决定。因此饼图内的文字大小,也要去判断宽高之间的相对大小。
fitChartSize3()
也得据此去zoom饼图外面那个圆环(图片)的大小。
scale()
radius: ['34%', '46%'], // 半径为可视区尺寸(容器高宽中较小一项)的 34% 长度。
center: ['21%', '53%'], // 第一项是相对于容器宽度,第二项是相对于容器高度。
3. 调整echart实例的大小。fitChartSize2()
还写了一个根据高度调整大小的。
棘手的事情
最麻烦的地方在于,我该如何确定圆环的位置?应该让圆环跟随着饼图的位置。饼图的圆心可以确定,半径也可以确定,都是百分比。但问题是,是占哪个值的百分比呢?
占画布宽度。画布宽度是多少呢?
按照我的理解,应该就是clientWidth才对。但是事实说,不是。
代码中标注蓝色的一行,是我测试出来的式子。虽然我并不是很理解为什么。在测试的时候发现,在设计图尺寸固定的情况下,我的画布高度的px是一个定值。无论我如何放缩我的浏览器,它的高度总是固定不变。(通过调试开发者工具中的css参数得知,利用相对定位,移动元素从上到下所需的px值不变。)比如,我的设计图尺寸的高度是268px,则画布高度为298px。换句话说,通过相对定位top:298px,就可以把元素死死固定在画布的底上。
而宽度则不是如此。依照这个规律,clientHeight/298将会等于clientWidth/画布宽度。所以我心心念念的 画布宽度就等于298 * clientWidth / clientHeight。
一测试,果然圆环死死跟随着饼图。
但为什么是298呢?在继续寻找规律的时候发现(通过改设计图尺寸高度,画布高度也会随之变化,不再是298了),设计图尺寸高度与画布高度存在一定的关系,即
设计图尺寸高度*画布高度 为一个定值。大概是80000这个值。即 画布高度 = 80000 / 设计图尺寸高度 ,再联系上面那个公式,得出,
画布宽度 = (80000 / 设计图尺寸高度) * clientWidth / clientHeight。
function change(x, y) {
let div = document.getElementById("main");
div.style.width = x + "px";
div.style.height = y + "px";
var myOption = myChart.getOption();
myChart.resize();
}
// 需要传入设计图尺寸y1
function onResize() {
console.log('onLoad----')
let [w,h] = [fitChartSize(BeginSize[0]), fitChartSize2(BeginSize[1])]
change(w, h)
// change(window.innerWidth, window.innerHeight)
console.log('scale: ',scale())
document.getElementsByClassName('pie')[0].style.zoom = scale()*90+'%'
// let x = 298 * w / h // 实际width 画布宽度
let y = 80000/268 //268是我的设计图尺寸y1
let x2 = y * w / h
document.getElementsByClassName('pie')[0].style.left = x2*0.21 - 0.23*(x2 > y ? y : x2) - 7 +'px'
}
代码
// fit.js
(这张设计图的尺寸为 380*268)
/* Echarts图表字体、间距自适应 */
const fitChartSize = (size, defalteWidth = 380) => {
const clientWidth = window.innerWidth || document.documentElement.clientWidth
// console.log('clientWidth: ',clientWidth);
if (!clientWidth) return size
const scale = (clientWidth / defalteWidth)
return Number((size * scale).toFixed(3))
}
// height
const fitChartSize2 = (size, defalteHeight = 268) => {
const clientHeight = window.innerHeight || document.documentElement.clientHeight
// console.log('clientHeight: ',clientHeight)
if (!clientHeight) return size
const scale = (clientHeight / defalteHeight)
return Number((size * scale).toFixed(3))
}
const scale = (defalteWidth=380, defalteHeight=268) => {
if(window.innerWidth < window.innerHeight){
return Number((window.innerWidth / defalteWidth).toFixed(3))
} else {
return Number((window.innerHeight / defalteHeight).toFixed(3))
}
// return [(window.innerWidth / 1920), (window.innerHeight / 1080)]
}
const fitChartSize3 = (size, defalteWidth=380, defalteHeight=268) => {
if(window.innerWidth < window.innerHeight){
// width
return Number((size * window.innerWidth / defalteWidth).toFixed(3))
} else {
// height
return Number((size * window.innerHeight / defalteHeight).toFixed(3))
}
// return [(window.innerWidth / 1920), (window.innerHeight / 1080)]
}
4. 监听事件
window.onresize = onResize
window.onload = onResize
end
绕了一大圈解决了这个问题。果然80%的精力都在解决20%的事情🥶
但我还是没有明白80000这个数字是怎么来的。求好心人救救我。