0


【前端可视化】 大屏可视化项目二 scale适配方案 g6流程图 更复杂的图表

项目介绍

  1. 第二个大屏可视化

,整个项目利用

  1. scale

进行按比例适配。 图表更加复杂,涉及到图表的叠加,mark,地图,g6流程图的能等

始终保持比例适配(本项目方案),始终满屏适配(项目一).
echarts绘制较为复杂图表,更深入锻炼echarts.

按比例用scale适配思路

  1. 开发项目直接使用设计图量出的尺寸填写大小
  2. 页面打开,读取当前屏幕宽,高
  3. 按当前屏幕宽高,通过scale缩放整个项目
  4. 让项目高度,横向竖向始终居中

请添加图片描述

请添加图片描述

最终实现效果

请添加图片描述

使用vite搭建vue项目

然后在项目根目录下 index.html

  1. <body><divid="app"></div><script>functionsetScale(){const designWidth=4352;const designHeight=1536;const nowWidth=document.documentElement.clientWidth //window.screnn.widthconst nowHeight=document.documentElement.clientHeight
  2. const designRatio=designWidth/designHeight;const nowRatio=nowWidth/nowHeight;const app=document.getElementById("app");//根据宽高比,决定按宽度进行scale还是高度进行scaleconst scale=nowRatio<designRatio?nowWidth/designWidth:nowHeight/designHeight
  3. app.style.transform=`scale(${scale}) translate(-50%,-50%)`}setScale();
  4. window.addEventListener("resize",setScale)</script><scripttype="module"src="/src/main.js"></script></body>

在assets静态目录下创建main.css 并在main.js中引入

  1. #app{transform-origin: 0 0;width: 4352px;height: 1536px;background:url('./backf.jpg');background-size: 100% 100%;/* 让他居中 */position: fixed;top:50%;left:50%
  2. }

整体布局和基本组件

  1. //App.vue<script setup>import{ onMounted }from'vue';import produceChart from"@/components/chartComponent/produceChart.vue"import monthPlanChart from"@/components/chartComponent/monthPlanChart.vue"import mapChart from"@/components/chartComponent/mapChart.vue"import qualityChart from"@/components/chartComponent/qualityChart.vue"import carType from"@/components/chartComponent/carType.vue"import complaintTable from"@/components/chartComponent/complaintTable.vue"import majorChart from"@/components/chartComponent/majorChart.vue"import g6chart from"@/components/chartComponent/g6chart.vue"</script><template><div class="container"><div class="title">
  2. 作战指挥室
  3. </div><div class="column-one"><produceChart></produceChart><monthPlanChart></monthPlanChart></div><div class="column-two"><mapChart></mapChart><qualityChart></qualityChart></div><div class="column-three"><carType></carType><complaintTable></complaintTable></div><div class="column-four"><majorChart></majorChart><g6chart></g6chart></div></div></template><style scoped lang="less">.container {padding: 24px 55px;width:100%;height:100%;
  4. box-sizing: border-box;display: flex;
  5. justify-content: space-between;position: relative;.title {position: absolute;left:50%;top:20;
  6. font-size: 48px;color: red;
  7. font-weight:800;transform:translateX(-50%);}.column-one,.column-four,.column-two,.column-three {display: flex;
  8. flex-direction: column;
  9. justify-content: space-between;}.column-one,.column-four {width: 1005px;height:100%;}.column-two,.column-three {width: 1036px;height:100%;}}</style>
将布局容器作为基础组件
  1. // src/components/baseComponent/bottomChartContent.vue<script setup>const{ title }=defineProps(['title'])</script><template><div class="bottomChartContent"><div class="title">{{ title }}</div><div class="soltContainer"><slot></slot></div></div></template><style scoped lang="less">.bottomChartContent {width:100%;height: 558px;background:url('../../assets/backpart2.png');
  2. background-size:100%100%;display: flex;
  3. flex-direction: column;.title {
  4. font-size: 32px;color: white;width:100%;
  5. text-align: center;}.soltContainer {width:100%;flex:1}}</style>//components/baseComponent/topChartContent.vue<script setup>const{ title }=defineProps(['title'])</script><template><div class="topChartContainer"><div class="title">{{ title }}</div><div class="soltContainer"><slot></slot></div></div></template><style scoped lang="less">.topChartContainer {width:100%;height: 878px;background:url('../../assets/backpart1.png');
  6. background-size:100%100%;display: flex;
  7. flex-direction: column;.title {
  8. font-size: 32px;color: white;width:100%;
  9. text-align: center;
  10. padding-top: 78px;}.soltContainer {width:100%;flex:1}}</style>

请求封装

  1. // request/index.jsimport axios from"axios";const request = axios.create({timeout:3000,baseURL:import.meta.env.VITE_BASE_URL,})
  2. request.interceptors.request.use((config)=>{const token = localStorage.getItem("token");if(token){
  3. config.auth = token;}return config
  4. })
  5. request.interceptors.response.use((res)=>{if(res.data.code !==200){alert(res.data.msg ||'请求失败')}return res;},()=>{alert("请求失败")})exportdefault request
  6. // api/index.jsimport request from"@/request";exportfunctiongetProduceStatus(){returnrequest("/produceStatus");}exportfunctiongetPlanData(){returnrequest("/planData");}exportfunctiongetMapData(){returnrequest("/mapData");}exportfunctiongetQualityData(){returnrequest("/qualityData");}exportfunctiongetCarSaleData(){returnrequest("/carSaleData");}exportfunctiongetComplainData(){returnrequest("/complainData");}exportfunctiongetMajorData(){returnrequest("/majorData");}

几个echarts最基本的属性

  1. import*as echarts from'echarts';// 基于准备好的dom,初始化echarts实例 需要一个容器var myChart = echarts.init(document.getElementById('main'));// 绘制图表
  2. myChart.setOption({//标题title:{text:'ECharts 入门示例'},//图例,说明legend:{top:'5%',left:'center'},//提示tooltip:{trigger:'item'},//x轴数据xAxis:{data:['衬衫','羊毛衫','雪纺衫','裤子','高跟鞋','袜子']},//y轴数据yAxis:{},//内容series:[{name:'销量',type:'bar',data:[5,20,36,10,10,20]}]});

复杂的嵌套圆环图

  1. <script setup>import topChartContent from'../baseComponent/topChartContent.vue';import{ getProduceStatus }from'@/api'import{ onMounted }from'vue';import*as echarts from"echarts"const ringnameArr =['计划生产','已接订单','已经完成']functiondrawRing(data, dom, name){//已完成const finish = data.finish;//未完成就是总数处以完成const unfinish = data.total - data.finish;const opt ={title:{text: name +'\n'+ data.finish,left:'center',top:'center',textStyle:{color:"white",fontSize:32}},series:[{type:"pie",left:20,right:20,radius:['60%','80%'],label:{show:false},data:[{value: finish,itemStyle:{color:"#017ed8"}},{value: unfinish,itemStyle:{color:"rgba(6,34,73,0.8)"}}]},{name:"out",type:"pie",radius:['75%','78%'],label:{show:false,},data:[100],itemStyle:{color:"rgba(8,67,120,0.5)"}},{name:"out",type:"pie",radius:['48%','50%'],label:{show:false,},data:[100],itemStyle:{color:"rgba(8,67,120,0.5)"}}]}const echartobj = echarts.init(dom);
  2. echartobj.setOption(opt)}onMounted(()=>{getProduceStatus().then((res)=>{const data = res.data.data;
  3. data.forEach((ringData, index)=>{drawRing(ringData, document.getElementById('ring'+ index), ringnameArr[index])})})})</script><template><topChartContent title="生产销售完成情况"><div class="produceChart"><div class="ring" v-for="(item, index) in ringnameArr":id="'ring' + index"></div></div></topChartContent></template><style scoped lang="less">.produceChart {width:100%;height:100%;display: flex;.ring {flex:1}}</style>

复杂的折线图

  1. <script setup>import bottomChartContent from'../baseComponent/bottomChartContent.vue';import{ getPlanData }from'@/api'import{ onMounted }from'vue';import*as echarts from"echarts"import{ axisBaseStyle }from'@/chartConfig.js'const commonLineStyle ={type:"line",smooth:true,lineStyle:{width:5}}functiondrawLine(data, dom){const finishArr =[];const targetArr =[];const xAxisData =[];const markLine =[]
  2. data.forEach((month)=>{
  3. xAxisData.push(month.month);
  4. finishArr.push(month.finish);
  5. targetArr.push(month.target);
  6. markLine.push({type:"line",lineStyle:{color:'#537598',width:5},data:[[month.month, month.target],[month.month, month.finish]]})})const opt ={color:["#2499f8","#ff9900"],tooltip:{formatter(obj){const month = obj.data[0];const dataitem = data.find((item)=>{if(item.month === month){return item;}})let _target = dataitem.target;let _finish = dataitem.finish;let percent =(_finish / _target)*100return`${month} 完成率 ${percent.toFixed(0)}%`},textStyle:{fontSize:26}},grid:{top:"20%",bottom:"30%",left:'15%'},legend:{top:'35px',textStyle:{color:"white",fontSize:26}},yAxis:{...axisBaseStyle,splitLine:{lineStyle:{color:"#045597",width:4}}},xAxis:{...axisBaseStyle,type:"category",data: xAxisData
  7. },series:[{...commonLineStyle,name:"计划生产",data: targetArr,},{...commonLineStyle,name:"实际生产",data: finishArr,},...markLine
  8. ]}const echartobj = echarts.init(dom);
  9. echartobj.setOption(opt)}onMounted(()=>{getPlanData().then((res)=>{drawLine(res.data.data, document.getElementById('monthPlan'))})})</script><template><bottomChartContent title="月计划完成情况"><div id="monthPlan"></div></bottomChartContent></template><style scoped lang="less">
  10. #monthPlan {width:100%;height:100%;}</style>

echart绘制地图效果

拿到数据。 搜索阿里云datav

  1. https://datav.aliyun.com/portal/school/atlas/area_selector?spm=a2crr.23498931.0.0.176a15ddAwYvpV

点击可视化学院复制数据

  1. <script setup>import{ getMapData }from'@/api'import{ onMounted }from'vue';import*as echarts from"echarts"import chinajson from"../../assets/china.json"
  2. echarts.registerMap("china", chinajson)functiondrawMap(data, dom){let _sortData = data.sort((pre, now)=>{return now.value - pre.value;})
  3. _sortData = _sortData.map((item)=>{return[...item.position,
  4. item.value,
  5. item.name
  6. ]})const top5Arr = _sortData.splice(0,5);const top5Marker = top5Arr.map((item, index)=>{return{name: item[3],coord:[item[0], item[1]],value: index
  7. }})const opt ={geo:{top:"25%",map:"china",scaleLimit:{min:1.5,max:10},emphasis:{itemStyle:{areaColor:"#016bb5"},label:{show:false}},itemStyle:{areaColor:"#016bb5"},roam:true,},series:[{type:"scatter",coordinateSystem:"geo",symbolSize:(dataItem)=>{const value =Number(dataItem[2]);return value /30;},itemStyle:{color:'rgba(255,255,0,0.8)',},data: _sortData
  8. },{type:"effectScatter",coordinateSystem:"geo",markPoint:{symbol:"pin",itemStyle:{color:"red"},symbolSize:60,label:{fontSize:26,formatter(val){return val.data.value +1;}},data: top5Marker
  9. },symbolSize:30,itemStyle:{color:'white',},data: top5Arr
  10. }]}const echartobj = echarts.init(dom);
  11. echartobj.setOption(opt)}onMounted(()=>{getMapData().then((res)=>{drawMap(res.data.data, document.getElementById("mapContent"))})})</script><template><div id="mapContent"></div></template><style scoped lang="less">
  12. #mapContent {width:100%;height: 878px;
  13. padding-top: 88px;
  14. box-sizing: border-box;}</style>

echarts绘制等高堆叠柱状图

  1. <script setup>import bottomChartContent from'../baseComponent/bottomChartContent.vue';import{ getQualityData }from'@/api'import{ onMounted }from'vue';import*as echarts from"echarts"import{ axisBaseStyle }from'@/chartConfig.js'functiondrawBar(data, dom){const goodArr =[];const badArr =[]const xAxisData =[];
  2. data.forEach((item)=>{
  3. xAxisData.push(item.month);const total = item.good + item.bad;
  4. goodArr.push(item.good / total);
  5. badArr.push(item.bad / total)})const opt ={color:["#2499f8",'#fe9901'],grid:{bottom:"30%"},xAxis:{...axisBaseStyle,type:"category",data: xAxisData
  6. },yAxis:{...axisBaseStyle,splitLine:{show:false},axisLabel:{fontSize:28,color:"white",formatter(val){return val *1000}}},series:[{type:"bar",stack:"total",data: goodArr,label:{show:true,color:"white",fontSize:26,formatter(value){const originData = data.find((item)=>{if(item.month === value.name){return item;}})return originData.good
  7. }}},{type:'bar',stack:"total",data: badArr,label:{show:true,fontSize:26,color:"red",formatter(value){const originData = data.find((item)=>{if(item.month === value.name){return item;}})return originData.bad
  8. }}}]}const echartobj = echarts.init(dom);
  9. echartobj.setOption(opt)}onMounted(()=>{getQualityData().then((res)=>{drawBar(res.data.data, document.getElementById('quality'))})})</script><template><bottomChartContent title="质量指标分析"><div id="quality"></div></bottomChartContent></template><style scoped lang="less">
  10. #quality {width:100%;height:100%;}</style>

echarts旭日图和表格

  1. <script setup>import{ getCarSaleData }from'@/api'import{ onMounted }from'vue';import*as echarts from"echarts"import chinajson from"../../assets/china.json"
  2. echarts.registerMap("china", chinajson)functiondrawCarType(data, dom){let _data =[];
  3. _data = data.map((item)=>{return{name: item.carType,value: item.value,children: item.children
  4. }})const opt ={color:['#ff9900','#99cc66','#0066ff'],series:[{type:"sunburst",radius:['40%','80%'],label:{rotate:'tangential',color:"white",fontSize:24},data: _data
  5. }]}const echartobj = echarts.init(dom);
  6. echartobj.setOption(opt)}onMounted(()=>{getCarSaleData().then((res)=>{drawCarType(res.data.data, document.getElementById("carType"))})})</script><template><div id="carType"></div></template><style scoped lang="less">
  7. #carType {width:100%;height: 878px;
  8. padding-top: 88px;
  9. box-sizing: border-box;}</style>

横向进度图

  1. <script setup>import topChartContent from'../baseComponent/topChartContent.vue';import{ getMajorData }from'@/api'import{ onMounted }from'vue';import*as echarts from"echarts"import{ axisBaseStyle }from'@/chartConfig.js'functiondrawMajor(data, dom){const yAxisData =[];const arr1 =[];const arr2 =[];const arr3 =[];const arr4 =[];const allArr =[arr1, arr2, arr3, arr4]const nameArr =['项目投标','投标进度','项目进行','项目交付']
  2. data.forEach((item)=>{const process = item.processState;
  3. yAxisData.push(item.name);
  4. process.forEach((processItem)=>{const category ={"项目投标":(val)=>{
  5. arr1.push({value: val,label:{show: val >0}})},"投标进度":(val)=>{
  6. arr2.push({value: val,label:{show: val >0}})},"项目进行":(val)=>{
  7. arr3.push({value: val,label:{show: val >0}})},"项目交付":(val)=>{
  8. arr4.push({value: val,label:{show: val >0}})}}
  9. category[processItem.stepName](processItem.finishPercent)})})const opt ={legend:{bottom:120,textStyle:{color:'white',fontSize:32},itemHeight:30,itemWidth:50,itemGap:50},grid:{left:"15%",bottom:'25%'},yAxis:{...axisBaseStyle,type:"category",data: yAxisData
  10. },xAxis:{splitLine:{show:false},axisLabel:{show:false}},series:[]}for(let i =0; i <4; i++){
  11. opt.series.push({type:"bar",name: nameArr[i],label:{show:true,formatter(val){if(val.value !==0){return val.value +"%"}},fontSize:28,color:'white'},stack:'total',data: allArr[i]})}
  12. console.log(opt);const echartobj = echarts.init(dom);
  13. echartobj.setOption(opt)}onMounted(()=>{getMajorData().then((res)=>{drawMajor(res.data.data, document.getElementById("majorContainer"))})})</script><template><topChartContent title="重大业务进度"><div id="majorContainer"></div></topChartContent></template><style scoped lang="less">
  14. #majorContainer {width:100%;height:100%;}</style>

g6关系图绘制

  1. <script setup>import bottomChartContent from'../baseComponent/bottomChartContent.vue';import{ onMounted }from'vue';import g6 from"@antv/g6"const baseNodeConfig ={type:"rect",labelCfg:{style:{fill:"white",fontSize:24}},style:{fill:'#1967af'},size:[120,50]}const lineStyle ={stroke:'#ff9900',lineWidth:5,endArrow:{path: g6.Arrow.vee(10,10,10),d:10}}onMounted(()=>{const data ={nodes:[{...baseNodeConfig,x:100,y:100,type:"rect",id:"接单",label:"接单"},{...baseNodeConfig,x:300,y:100,type:"rect",id:'生产',label:"生产",anchorPoints:[[1,0.5],[1,1],[0,0.5]],},{...baseNodeConfig,x:500,y:100,type:"rect",id:'检测',label:"检测"},{...baseNodeConfig,x:700,y:100,type:"rect",id:'销售',label:"销售"},{...baseNodeConfig,x:900,y:100,type:"rect",id:'售后',label:"售后",anchorPoints:[[0,0.5],[1,0.5]],},{...baseNodeConfig,x:800,y:300,type:"rect",anchorPoints:[[1,0],[0,0]],id:'回厂',label:"回厂"},],edges:[{source:"接单",target:'生产',style:{...lineStyle
  2. }},{source:"生产",target:'检测',style:{...lineStyle
  3. }},{source:"检测",target:'销售',style:{...lineStyle
  4. }},{source:"销售",target:'售后',style:{...lineStyle
  5. }},{source:"售后",target:'回厂',sourceAnchor:1,targetAnchor:0,type:"arc",style:{...lineStyle,endArrow:{path: g6.Arrow.vee(10,-10,2)}}},{source:"回厂",target:'生产',sourceAnchor:1,targetAnchor:1,type:"arc",style:{...lineStyle,endArrow:{path: g6.Arrow.vee(10,-4,2)}}}]}const graph =newg6.Graph({container:'g6container'})
  6. graph.data(data);
  7. graph.render();})</script><template><bottomChartContent title="产线示意图"><div id="g6container"></div></bottomChartContent></template><style scoped lang="less">
  8. #g6container {width:100%;height:100%;}</style>

如果对你有所帮助 就点个关注吧

本篇文章是

  1. https://www.bilibili.com/video/BV1PE421w7iJ/?p=7&spm_id_from=pageDriver&vd_source=e73709c9a1618b4c6dfd58c6c40d8986

的笔记

标签: 前端 流程图 css

本文转载自: https://blog.csdn.net/weixin_63625059/article/details/141003886
版权归原作者 ZhaiMou 所有, 如有侵权,请联系我们删除。

“【前端可视化】 大屏可视化项目二 scale适配方案 g6流程图 更复杂的图表”的评论:

还没有评论