好久没写博客了,感觉没什么技术难点需要记录,今天就把这两天遇到的比较费时费力的东西记录一下吧,代码没有注释,逻辑不难,echarts仪表盘的配置是最花时间的。老板就给了一个静态图片,取色都是用的qq 取色和Snipaste,后面发现两个软件的取色居然还不一样 。其他什么也没有, 有个别的透明图标,叫用代码画出来。还要一毛一样,沉思了,这种东西要说好弄,就是太过于繁琐了。
其他好说,下面的居住信息要和设计原稿一致。下面第一张图是boss发的图片
 这是最后的成品图片 
不啰嗦了。下面莱晒代码了
<template>
<div class="bottom">
<sub-title text="居住信息" size="18" />
<el-row>
<el-col :span="5" :push='2'>
<el-col>{{source['num_total_households']}}</el-col>
<el-col>总户数</el-col>
</el-col>
<el-col :span="5" :push='2'>
<el-col>{{source['num_Resident']}}</el-col>
<el-col>居住人数</el-col>
</el-col>
<el-col :span="5" :push='2'>
<el-col>{{source['num_owner']}}</el-col>
<el-col>业主人数</el-col>
</el-col>
<el-col :span="5" :push='2'>
<el-col>{{source['num_tenant']}}</el-col>
<el-col>租户人数</el-col>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<div class="install_first" style="height: inherit"></div>
</el-col>
<el-col :span="16">
<el-col>住房空置房</el-col>
<el-col>1257</el-col>
<el-col>数量<span>315</span></el-col>
<el-col>占比<span>25%</span></el-col>
<div></div>
<div><span></span></div>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<div class="install_second" style="height: inherit"></div>
</el-col>
<el-col :span="16">
<el-col>住房空置房</el-col>
<el-col>1257</el-col>
<el-col>数量<span>315</span></el-col>
<el-col>占比<span>25%</span></el-col>
<div></div>
<div><span></span></div>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<div class="install_third" style="height: inherit"></div>
</el-col>
<el-col :span="16">
<el-col>住房空置房</el-col>
<el-col>1257</el-col>
<el-col>数量<span>315</span></el-col>
<el-col>占比<span>25%</span></el-col>
<div></div>
<div><span></span></div>
</el-col>
</el-row>
</div>
</template>
<script>
import subTitle from "@/components/item_title.vue";
import { reside } from "@/data/datas";
const install = {
install_first: null,
install_second: null,
install_third: null
};
export default {
name: "reside",
components: { subTitle },
data() {
return {
timer: { install_first: null, install_second: null, install_third: null },
source: {},
statistics: [],
obj: {first: '', second: '', third: ''}
};
},
mounted() {
this.source = reside;
for(const key in install) this.init_charts(key);
},
methods: {
init_charts(el, val) {
install[el] = echarts.init(document.querySelector("." + el));
const option = {
series: [
{
type: "gauge",
startAngle: 90,
endAngle: -270,
progress: { show: true, width: 5, color: '#00227d' },
axisLabel: { show: false, },
axisLine: {
lineStyle: {
color: [[1, "#4bf3f9"]],
width: 5,
shadowColor: "#4bf3f9",
shadowBlur: 5
}
},
pointer: {show: false },
axisTick: {
lineStyle: {
color: "transparent",
shadowColor: "#fff",
shadowBlur: 10
}
},
splitLine: {
length: 20,
lineStyle: {
width: 30,
color: "transparent",
shadowColor: "#fff",
shadowBlur: 10
}
},
detail: {
show : true ,
borderColor: "#fff",
shadowColor: "#fff",
textStyle: {
fontWeight: "200",
fontSize: 26,
color: "#FDFDFC"
},
formatter: "{value}{per|%}",
rich: {
per: { fontSize: 12, color: '#909399' },
},
offsetCenter: ["0", "5%"]
},
data: [{ value: 100 }]
},
{
type: "gauge",
radius: "55%",
startAngle: 90,
endAngle: -270,
axisLabel: { show: false, },
axisLine: {
lineStyle: {
color: [ [80 / 100, "#00217D"],[1, "#00217D"] ],
width: 1,
shadowColor: "#1F4088",
shadowBlur: 4
}
},
pointer: {show: false },
axisLabel: {show: false },
axisTick: { show: false, },
splitLine: { show: false, },
detail: {show : false },
data: [{ value: 100}]
}
]
};
this.timer[el] = setInterval(() => {
this.obj[el.split('_')[1]] = (Math.random() * 100).toFixed(0) - 0;
option.series[0].data[0].value = this.obj[el.split('_')[1]];
let sibling = document.querySelector("." + el).parentNode.nextElementSibling;
let targetEl = sibling.lastElementChild;
let Progress = this.__Math_Integer(this.obj[el.split('_')[1]]);
targetEl.lastElementChild.style.width = "calc(" + ( Progress ) + '%' + " - 1%)";
let previousEl = targetEl.previousSibling;
previousEl.innerHTML = "";
for (let i = 0; i < Progress / 10; i++ ) previousEl.appendChild(document.createElement("span"));
install[el].setOption(option);
}, 2021);
},
__Math_Integer(base) {
const q = Math.floor((base / 10)) * 10;
const w = base % 10;
const e = Math.ceil((w / 10)) * 10;
const r = q + e;
return r < 10 ? 10 : r;
}
},
beforeDestroy() {
clearInterval(this.timer['install_first']);
clearInterval(this.timer['install_second']);
clearInterval(this.timer['install_third']);
}
};
</script>
<style lang='scss' scoped>
@mixin repeat() {
background-size: 95% 100%;
margin-left: 15px;
height: 125px;
& > .el-col {
height: inherit;
}
& > :first-child {
position: relative;
p {
position: absolute;
top: 55px;
left: 45px;
font-size: 22px;
span {
font-size: 13px;
color: $fontGrey;
}
}
}
& > :last-child {
background: url("~@/assets/imgs/商铺空置房@2x.png") no-repeat;
background-size: 100% 100%;
position: relative;
right: 0.83333%;
& > :nth-child(1) {
position: absolute;
top: 30px;
left: 10px;
}
& > :nth-child(2) {
position: absolute;
top: 30px;
right: -241px;
}
& > :nth-child(3) {
position: absolute;
top: 90px;
left: 15px;
font-size: 13px;
span {
margin-left: 30px;
font-size: 14px;
font-weight: 200;
text-shadow: 5px 5px 5px #2fa8c7;
}
}
& > :nth-child(4) {
position: absolute;
top: 90px;
left: 140px;
font-size: 13px;
span {
margin-left: 30px;
font-size: 14px;
font-weight: 200;
}
}
& > :nth-child(5) {
position: absolute;
top: 57px;
z-index: 2;
width: 100%;
height: 10px;
padding: 0 5px;
box-sizing: border-box;
/deep/ span {
display: inline-block;
width: calc(10% - .9px);
height: inherit;
border-right: 1px solid #06153f;
opacity: 0.5;
margin-bottom: 10px;
}
}
& > :nth-child(6) {
position: absolute;
top: 57px;
width: 100%;
height: 10px;
padding: 0 5px;
box-sizing: border-box;
span {
display: inline-block;
height: inherit;
background-image: linear-gradient(to right, #072652, #3BC8DE);
transition: width 1s;
margin-bottom: 10px;
}
}
}
}
.bottom {
@include border("55%");
color: $themeWhite;
& > :nth-child(2) {
text-align: center;
height: 45px;
& > .el-col {
height: inherit;
position: relative;
:first-child {
font-size: 26px;
}
:last-child {
margin-top: 5px;
color: $fontGrey;
font-size: 10px;
}
}
& > :not(:nth-child(4)):after {
content: "";
position: absolute;
right: 0px;
display: inline-block;
width: 1px;
height: inherit;
background: linear-gradient(to bottom, #072652, #034c8e, #042049);
}
}
& > :nth-child(3) {
@include repeat;
}
& > :nth-child(4) {
@include repeat;
}
& > :nth-child(5) {
@include repeat;
}
}
</style>

datas和subTitle组件内容以及scss的color变量颜色和方法
<template>
<div>
<div class="sub-title-warp" :style="{textAlign: align, fontSize: size + 'px'}">
<span>{{text}}</span>
</div>
</div>
</template>
<script>
export default {
name: "sub_title",
data() {
return {};
},
props: {
text: { type: String, default: "" },
background: { type: Boolean, default: false },
align: { type: String, default: 'left'},
size: { type: String, default: '16' }
},
mounted() {},
methods: {},
computed: {}
};
</script>
<style lang='scss' scoped>
.sub-title-warp {
max-width: 65%;
height: 39px;
line-height: 39px;
padding-left: 5px;
.icon {
display: inline-block;
width: 25px;
height: 25px;
transform: translateY(10px);
}
span {
margin-left: 5px;
font-size: inherit;
color: $titleColor;
}
}
</style>
export const reside = {
num_total_households: 1415, // 总户数
num_Resident: 1040, // 居住人数
num_owner: 1040, // 业主人数
num_tenant: 0, // 租户人数
statistics: [
{ num_vacant_room: 1257, number: 315, num_proportion: 25, str_room_type: "住房空置房" },
{ num_vacant_room: 155, number: 0, num_proportion: 0, str_room_type: "商铺空置房" },
{ num_vacant_room: 1415, number: 1100, num_proportion: 77.7, str_room_type: "整体入住率" },
]
}
$borderTheme: #025E8E;
$themeWhite: #FDFDFC;
$themeBox: rgb(6,21,63);
$ItembgColor: rgb(11,28,79);
$titleColor: #01D8E4;
$fontLightBlue: #2DFDFC;
$fontLightGreen: #2DFB99;
$fontDarkBlue: #039CAE;
$itemYellow: #F6B158;
$itemSkyblue: #58DAF6;
$itemPurple: #CF28FF;
$itemBlue: #58ABF6;
$fontGrey: #B9BBC2;
$fontrich: #909399;
$primary: #0468B5;
$warning: #C5263A;
@mixin border($h) {
border: 1px solid $borderTheme;
background-color: $themeBox;
height: #{$h};
}
@mixin queue($w, $justify) {
width: #{$w};
height: 100%;
display: flex;
flex-direction: column;
justify-content: #{$justify};
}
@mixin card() {
margin: 0 10px;
padding: 0 15px;
}
如果你认真再看,我就讲一下实现思路吧,布局都是2/8分,左边图表,右侧数据,图表里面用了两个圆来实现视觉效果的。当然我最近做了很多echarts图例,里面附表作用都是起衬托作用的。右侧是取得进度百分比值向上取整除10%来添加元素。再使用css 给元素组加上右侧border效果实现刻度分隔符。上面所有适配度根据我的画面进行配置,觉得有误差的自行排查调整,当然实际中使用了定时器,记得销毁时候清除,否则会继续执行提示错误的。
我是前端小白,如果文章觉得不错请点赞支持一下吧!
|