Commit b6935922 authored by wuhao's avatar wuhao 🎯

xcf

parent 900a8b1a
{
"name": "techui",
"private": true,
"private": false,
"version": "0.0.0",
"type": "module",
"scripts": {
......
This diff is collapsed.
/*
* @Author: wuhao930406 1148547900@qq.com
* @Date: 2023-08-08 09:18:08
* @LastEditors: wuhao930406 1148547900@qq.com
* @LastEditTime: 2023-08-16 11:25:04
* @FilePath: /vue3portal/src/main.js
* @Description:
*
* Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
*/
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
......@@ -12,10 +22,12 @@ import vue3api from '@/plugins/vue3api'
import common from '@/plugins/common'
const app=createApp(App)
techUILite(app).then(()=>{
app.use(router)
app.use(store)
app.use(vue3api)
app.use(common)
app.mount('#app')
})
app.use(techUILite);
app.use(router)
app.use(store)
app.use(vue3api)
app.use(common)
app.mount('#app');
/*
* @Author: wuhao930406 1148547900@qq.com
* @Date: 2023-08-08 09:18:08
* @LastEditors: wuhao930406 1148547900@qq.com
* @LastEditTime: 2023-08-16 11:29:38
* @FilePath: /vue3portal/src/router.js
* @Description:
*
* Copyright (c) 2023 by ${git_name_email}, All Rights Reserved.
*/
import { createRouter, createWebHistory,createWebHashHistory,useRoute } from 'vue-router'
import{ defineAsyncComponent } from"vue"
......@@ -11,69 +21,69 @@ const router = createRouter({
{
path: "/",
name: "layout",
redirect:"/dashboardA-en",
},
{
path: "/dashboardA-en",
name: "dashboardA-en",
component:()=>import("@/viewsEN/dashboardA/dashboardA-index.vue"),
},
{
path: "/dashboardB-en",
name: "dashboardB-en",
component:()=>import("@/viewsEN/dashboardB/dashboardB-index.vue"),
},
{
path: "/dashboardC-en",
name: "dashboardC-en",
component:()=>import("@/viewsEN/dashboardC/dashboardC-index.vue"),
},
{
path: "/dashboardD-en",
name: "dashboardD-en",
component:()=>import("@/viewsEN/dashboardD/dashboardD-index.vue"),
},
{
path: "/dashboardA-cn",
name: "dashboardA-cn",
component:()=>import("@/viewsCN/dashboardA/dashboardA-index.vue"),
},
{
path: "/dashboardB-cn",
name: "dashboardB-cn",
component:()=>import("@/viewsCN/dashboardB/dashboardB-index.vue"),
redirect:"/dashboardC-cn",
},
// {
// path: "/dashboardA-en",
// name: "dashboardA-en",
// component:()=>import("@/viewsEN/dashboardA/dashboardA-index.vue"),
// },
// {
// path: "/dashboardB-en",
// name: "dashboardB-en",
// component:()=>import("@/viewsEN/dashboardB/dashboardB-index.vue"),
// },
// {
// path: "/dashboardC-en",
// name: "dashboardC-en",
// component:()=>import("@/viewsEN/dashboardC/dashboardC-index.vue"),
// },
// {
// path: "/dashboardD-en",
// name: "dashboardD-en",
// component:()=>import("@/viewsEN/dashboardD/dashboardD-index.vue"),
// },
// {
// path: "/dashboardA-cn",
// name: "dashboardA-cn",
// component:()=>import("@/viewsCN/dashboardA/dashboardA-index.vue"),
// },
// {
// path: "/dashboardB-cn",
// name: "dashboardB-cn",
// component:()=>import("@/viewsCN/dashboardB/dashboardB-index.vue"),
// },
{
path: "/dashboardC-cn",
name: "dashboardC-cn",
component:()=>import("@/viewsCN/dashboardC/dashboardC-index.vue"),
},
{
path: "/dashboardD-cn",
name: "dashboardD-cn",
component:()=>import("@/viewsCN/dashboardD/dashboardD-index.vue"),
},
// {
// path: "/dashboardD-cn",
// name: "dashboardD-cn",
// component:()=>import("@/viewsCN/dashboardD/dashboardD-index.vue"),
// },
{
path: "/dashboardA-hk",
name: "dashboardA-hk",
component:()=>import("@/viewsHK/dashboardA/dashboardA-index.vue"),
},
{
path: "/dashboardB-hk",
name: "dashboardB-hk",
component:()=>import("@/viewsHK/dashboardB/dashboardB-index.vue"),
},
{
path: "/dashboardC-hk",
name: "dashboardC-hk",
component:()=>import("@/viewsHK/dashboardC/dashboardC-index.vue"),
},
{
path: "/dashboardD-hk",
name: "dashboardD-hk",
component:()=>import("@/viewsHK/dashboardD/dashboardD-index.vue"),
},
// {
// path: "/dashboardA-hk",
// name: "dashboardA-hk",
// component:()=>import("@/viewsHK/dashboardA/dashboardA-index.vue"),
// },
// {
// path: "/dashboardB-hk",
// name: "dashboardB-hk",
// component:()=>import("@/viewsHK/dashboardB/dashboardB-index.vue"),
// },
// {
// path: "/dashboardC-hk",
// name: "dashboardC-hk",
// component:()=>import("@/viewsHK/dashboardC/dashboardC-index.vue"),
// },
// {
// path: "/dashboardD-hk",
// name: "dashboardD-hk",
// component:()=>import("@/viewsHK/dashboardD/dashboardD-index.vue"),
// },
]
});
......
......@@ -4,7 +4,7 @@ import router from '@/router.js'
export default createStore({
state: {
lang:"en"
lang:"cn"
},
mutations: {
......
<script setup>
import layout from "./layout.vue"
const state=reactive({
APConfig:{
// backgroundFillAll:true,
// backgroundName:"A1",
height:930,
userSelect:true,
chartCount:9
}
})
</script>
<template>
<adaptivePanel :config="state.APConfig"><layout></layout></adaptivePanel>
</template>
<style lang="less">
</style>
\ No newline at end of file
<script setup>
import echartBarHoriz from "./portlet/echart-barHoriz.vue"
import echartLine from "./portlet/echart-line.vue"
import echartBarHorizScroll from "./portlet/echart-barHorizScroll.vue"
import echartGaugeTriple from "./portlet/echart-gaugeTriple.vue"
import echartSunburst from "./portlet/echart-sunburst.vue"
import counterGrid from "./portlet/counter-grid.vue"
import echartMap from "./portlet/echart-map.vue"
import mainNav from "@/common/mainNav.vue"
import externalLinks from "@/common/externalLinks.vue"
const comps = {
echartBarHoriz,
echartLine,
echartBarHorizScroll,
echartGaugeTriple,
echartSunburst,
echartMap,
counterGrid,
}
const state = reactive({
systemTitleConfig: {
width: 1000
},
panelTitleConfig: {
width: 160,
},
dialogConfig: {
show: false,
width: '60%',
height: '60%',
title: "对话框标题",
titleWidth: 350,
},
// panelTitleConfig:{
// width:180,
// theme:true
// },
areas: [
{
name: "left", portlets: [
{ id: "l2", title: "收支情况", component: "echartBarHoriz", border: "aYinTechBorderA1", hideTitle: true },
{ id: "l3", title: "业务收益情况", component: "echartLine", border: "aYinTechBorderA1", hideTitle: true },
{ id: "l1", title: "销售任务", component: "echartBarHorizScroll", border: "aYinTechBorderA1", hideTitle: true },
]
},
{
name: "right", portlets: [
{ id: "r1", title: "销售情况", component: "counterGrid", border: "blank", hideTitle: true },
{ id: "r2", title: "任务完成情况", component: "echartGaugeTriple", border: "aYinTechBorderA1", hideTitle: true },
{ id: "r3", title: "业务利润占比", component: "echartSunburst", border: "aYinTechBorderA1" },
]
},
]
})
const { systemTitleConfig, panelTitleConfig, areas } = toRefs(state)
const getConfig = (item) => {
const { id } = item
if (id == 'r3') {
return {
directionAlt: true,
rotate: "z",
opacity: 0.7
}
} else if (id.includes("l")) {
return {
title: item.title,
titleWidth: 120,
decoration: false,
decorationAlt: true,
rotate: "y",
opacity: 0.7
}
} else {
return {
title: item.title,
titleWidth: 120,
decoration: false,
opacity: .7
}
}
}
onMounted(() => {
})
</script>
<template>
<div class="screen1080A">
<mainNav></mainNav>
<externalLinks></externalLinks>
<div :class="`area-box area-${area.name}`" v-for="area in areas" :key="area.id">
<div class="portlet-wrapper" v-for="item in area.portlets" :key="item.id">
<component v-if="item.border" :is='item.border' :config="getConfig(item)">
<panelTitleA1 v-if="!item.hideTitle" :config="panelTitleConfig">{{ item.title }}</panelTitleA1>
<component :is='comps[item.component]'></component>
</component>
<template v-else>
<component :is='item.component'></component>
<i>{{ item.component }}</i>
</template>
</div>
</div>
<systemTitleA2 :config="systemTitleConfig">TechUI数据可视化成型工具</systemTitleA2>
<echartMap></echartMap>
</div>
</template>
<style lang="less">
.screen1080A {
z-index: 1;
padding: 60px 30px 30px 30px;
height: 100%; //url(../common/images/bg.png)
.techButtonA2 {
z-index: 10;
.poa;
bottom: 20px;
left: 50%;
.fixc("x");
}
.i() {
.poa;
bottom: 0;
right: 10px;
font-size: 12px;
opacity: .1;
.fc(@wh);
z-index: 10;
}
display: grid;
grid-template-columns: repeat(24, 1fr);
grid-template-rows:repeat(24, 1fr);
grid-gap: 30px;
.area-box {
.bdr(5px);
pointer-events: visible;
position: relative;
z-index: 10;
.board-3d-wrap {
.poa;
.fullbox;
}
//<row-start> / <column-start> / <row-end> / <column-end>;
.blank,
.portlet-wrapper {
.por;
>i {
.i;
}
}
.border-content {
>i {
.i;
}
}
&.area-left {
grid-area: 1 / 1 / 25 / 7;
}
&.area-right {
grid-area: 1 / 19 / 25 / 25;
.portlet-wrapper {
&:nth-child(3) {
grid-area: 3 / 1 /5/ 2
}
}
}
&.area-left {
display: grid;
grid-template-columns: repeat(1, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-gap: 20px;
}
&.area-right {
display: grid;
grid-template-columns: repeat(1, 1fr);
grid-template-rows: repeat(4, 1fr);
grid-gap: 20px;
}
}
.content-tabs {
.poa;
top: -40px;
left: 80px;
right: 80px;
text-align: center;
height: 40px;
&:before {
content: " ";
.bdb(var(--button-bd_hov));
left: 0;
right: 0;
bottom: 10px;
.poa;
z-index: 1;
}
.tabs-item {
display: inline-block;
padding: 0 10px;
.ff("cn1");
.fc(var(--font-normal));
height: 30px;
line-height: 30px;
cursor: pointer;
.ani;
z-index: 2;
.por;
&:before {
content: " ";
.bgc(var(--button-bd_hov));
.poa;
.fullbox;
opacity: 0;
}
&:hover {
&:before {
opacity: .3;
}
}
&.active {
.bdb(var(--font-strong));
.fc(var(--font-strong));
}
}
}
}</style>
\ No newline at end of file
<script setup>
const state=reactive({
arry:[
{title:"软件销售额",icon:"i carbon:ibm-z-cloud-mod-stack",unit:"万元",total:"1874"},
{title:"硬件销售额",icon:"i carbon:chip",unit:"万元",total:"3276"},
{title:"技术服务",icon:"i carbon:user-speaker",unit:"万元",total:"315"},
{title:"安全服务",icon:"i carbon:rule",unit:"万元",total:"769"},
],
})
const borderConfig=(index)=>{
let rotate
if(index==0){
rotate="x";
}else if(index==1){
rotate="all";
}else if(index==2){
rotate=null;
}else if(index==3){
rotate="y";
}
return {
dur: 3,
opacity: 0.7,
// decoration: false,
rotate
}
}
</script>
<template>
<div class="screenA-counterGrid">
<aYinTechBorderB3 :config="borderConfig(index)" v-for="(item,index) in state.arry" :key="index">
<div class="inner-content">
<div class="block-title">{{item.title}} <span v-if="item.unit">({{item.unit}})</span></div>
<div class="total">
<i :class="[item.icon,'icon']"></i>
<!-- <DigitalTransform class="numbers" :value="123210" :interval="$vuex.state.globalConfig.ani?3000:0"></DigitalTransform> -->
<DigitalTransform class="numbers" :value="item.total" :useGrouping="true" :interval="3000"></DigitalTransform>
<!-- <span class="unit">{{item.unit}}</span> -->
</div>
</div>
</aYinTechBorderB3>
<!-- <div class="block" > <div class="bdTechBottom"></div> </div> -->
</div>
</template>
<style lang="less">
.screenA-counterGrid{display: grid; grid-template-columns: repeat(2,1fr); height: 100%; grid-template-rows: repeat(2,1fr); grid-gap: 12px; position: relative;
.aYinTechBorderB3{ padding:0; position: relative;
//&:nth-child(1){ grid-area: 1 / 1 / 2 / 3; }
.inner-content{
.block-title{position: absolute;.ff("cn1"); left:0; right:0; text-align: center; top:10px;.fc(var(--font-normal)); font-size: 14px; }
.total{margin: 0; text-align: center; line-height: 30px; .poa; left:0; right:0; top:60%; .fixc("y");
i{display:inline-block;font-size:32px; vertical-align: text-top; margin-right: 10px;.fc(var(--font-normal));}
.numbers{display:inline-block; text-align: center; font-size: 32px; .ff("en0"); position: relative; vertical-align: text-top; .fc(var(--font-strong));
.badge{position: absolute; left:100%; top:-10px; font-size: 14px; width: 30px; height:30px; padding:0; line-height: 1; }
}
.unit{font-size: 14px; margin:0 0 0 10px;.fc(var(--font-strong));}
}
}
}
}
</style>
<script setup>
const state=reactive({
chartData:{
legend:['本地视频会议', '异地视频会议'],
xAxis:['十二月', '一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月'],
colors:[$c.bll4,$c.aql4,$c.ipl3,$c.cbl3,],
data:[
[235, 210, 187, 212, 278, 220, 320, 302, 301, 334, 390, 330],
[68, 121, 34, 56, 23, 120, 132, 101, 134, 90, 230, 210]
],
},
chartOption:{}
})
const processData=()=>{
let legend=state.chartData.legend,
colors=state.chartData.colors,
xAxis=state.chartData.xAxis,
data=state.chartData.data,
processedData=[]
legend.forEach((item,i)=>{
processedData.push({
name: legend[i],
type: 'bar',
barWidth:15,
label: {
show: false,
position: 'insideRight'
},
itemStyle:{
color: colors[i],
borderRadius: 5
},
data: data[i]
})
})
state.chartOption.series=processedData;
state.chartOption.xAxis.data=xAxis;
}
const processOption=()=>{
state.chartOption={
update:false,
// title:{ text:"barA", left:200, top:0, textStyle:{ color:$c.gyl3, fontSize:16, fontWeight:"normal" }, },
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
//show:false,
data: [],
top:"5",
right:60,
},
toolbox: {
feature: {
magicType: { type: ['line', 'bar'] }
},
},
grid: {
left: '5%',
right: '5%',
bottom: '5%',
top: "15%",
containLabel: true
},
yAxis: {
type: 'value',
axisLabel: { align: 'right' }
},
xAxis: {
type: 'category',
data: [],
axisLabel: { align: 'center' }
},
series: []
}
processData()
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<script setup>
const state=reactive({
chartData:{
legend:['收入', '支出'],
yAxis:['业务1', '业务2', '业务3', '业务4', '业务5', '业务6'],
colors:[$c.cbl4,$c.bll5,],
data:[
[320, 302, 341, 374, 390, 450],
[-120, -132, -101, -134, -190, -230],
],
},
chartOption:{}
})
const processData=()=>{
let {legend,colors,yAxis,data}=state.chartData,
processedData=[];
legend.forEach((item,i)=>{
processedData.push({
name: legend[i],
type: 'bar',
barWidth:10,
stack: 'Total',
label: {
color:"#fff",
show: true
},
emphasis: {
focus: 'series'
},
itemStyle:{
color: $c.fade(colors[i],.9),
borderRadius: 3
},
data: data[i]
})
})
state.chartOption.legend.data=legend;
state.chartOption.series=processedData;
state.chartOption.yAxis.data=yAxis;
}
const processOption=()=>{
state.chartOption={
update:false,
// title:{ text:"barA", left:200, top:0, textStyle:{ color:$c.gyl3, fontSize:16, fontWeight:"normal" }, },
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
legend: {
right: '10',
top: '10',
},
grid: {
left: '5%',
right: '10%',
bottom: '8%',
top: "15%",
containLabel: true
},
xAxis: {
type: 'value',
axisLabel: {
align: 'center',
interval:0,
}
},
yAxis: {
type: 'category',
axisTick: {
show: false
},
data: [],
axisLabel: {
formatter: '{value}',
align: 'right'
}
}
}
processData();
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<script setup>
const base64Img="image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAA6CAMAAADWZboaAAAAZlBMVEUAAABe3uVe3+Vf3uVf3+Zf3uVg3+Zg3+Zf3+Vi4OZh4OZg3+Z86/Bh3+Zi4Odj4Odi4OZ86/B76/B86/Bj4ed56+9x5+xn4umB7/N87PB36e+A7/N+7fF/7vJ/7vJ+7fGA7/OB7/PReX+lAAAAIXRSTlMABQkVDREmIhk3MR10LEFFPHh7cUprXE35h2XnqMLAp+mHAG9cAAAB5ElEQVRIx83WjU7CMBQFYIoiKMqU/XUboHv/l/Tce7t2XamDNSacETEmX86tlK2rx4py150o+MstMBLwWRfHKo6JCVxLnvmFGBjFQ58oF1//sUZhGy/ClSTWObgnL4O+bkeN4nY2okfNMbkRt9/vtxz8InoTsWplJSCzFxPmO8+GpSIByX3YQAuGDWtRKhKjCnxDXhF6Z4yxnZ20Wgko7BMRDmxtSGVaI4kdTIgb+zTYoJQlIMlDlmUFgrcDWWC201qSayqlTkiCddWWeV62VU0YlnpRi9VOKaSUsiyq/N0krwq2Ugt7lVpZl5BfHNiytjagMi+XYp0kCR45hMlivVQrE/uU5pXSrCB5bM6d1t2lOZItMqmliT3q5uVxqxzyW/ccfYLNKx7ZTeykMvNyac2yt2Fbc61MHLSC0rwoxbiNdlQ3GBm1NLHQsHUrtEXppR/ljNpW6DbSCoqlFiVoN6YdaFlgsSFVPs1BdT8OaB5QyQzVcaqWDows/zepxR8ObLglTrdtCRVuRNj4Rrxh+//0ke2f8KVL+Kon3GCSbmsJN9OUW3j6g0Ns+LgCij2u0h+Sghc8mlMPBMgdx5DFh59VmOVHrvmDnoNxCz3J7MFWsMuaLyR089xz/xhlfijvwutR8gv3zk6BLUUeCgAAAABJRU5ErkJggg=="
const state=reactive({
chartData:{
yAxis:['任务A', '任务B', '任务C', '任务较长名称D', '任务E', '任务F', '任务G', '任务H', '任务I'],
color:[$c.cyl4,$c.orl5,$c.rel5],
data:[69, 96, 35,26, 96, 32 ,52 ,22 ,72]
},
chartOption:{}
})
const fillArr=computed(()=>{
return (new Array(state.chartData.data.length)).fill(100);
})
const getSymbolData=(data)=>{
let arr = [];
for (var i = 0; i < data.length; i++) {
arr.push({
value: data[i],
symbolPosition: 'end'
})
}
return arr;
}
const processData=()=>{
let legend=state.chartData.legend,
colors=state.chartData.colors,
yAxis=state.chartData.yAxis,
data=state.chartData.data,
processedData=[];
state.chartOption.yAxis.data=state.chartData.yAxis;
state.chartOption.series[0].data=state.chartData.data;
state.chartOption.series[1].data=fillArr;
state.chartOption.series[2].data=getSymbolData(state.chartData.data);
dataScroll();
}
const processOption=()=>{
state.chartOption={
update:false,
title: {
show:false,
// text: '实时流速图2',
textStyle:{
color:$c.cbl5,
fontSize:16,
fontWeight:"normal"
},
},
grid: {
top: '15%',
left: '18%',
right: '12%',
bottom: '5%'
},
tooltip: {show: false},
xAxis: {
type: 'value',
min: 0,
max: 100,
axisLine: {show: false},
splitLine: {show: false},
axisLabel: {show: false},
axisTick: {show: false}
},
dataZoom: {
yAxisIndex: 0,
show: false,
type: "slider",
startValue: 0,
endValue: 5,
},
yAxis: {
//show: false,
type: 'category',
inverse: true,
splitLine: {show: false,},
axisLine: {show: false},
axisLabel: {
show: true,
interval: 0,
margin: 10,
fontSize: 12,
width:50,
lineHeight:14,
overflow:"breakAll",
fontWeight: 'normal',
},
axisTick: {show: false},
data:[]
},
series: [
{
type: 'bar',
barWidth: '40%',
animationDuration:2000,
itemStyle: {
borderWidth:0,
borderRadius:10,
color: {
type: 'linear', x: 0, y: 0, x2: 1, y2: 0,
colorStops: [{ offset: 0, color: $c.cyl8, }, { offset: 1, color: $c.cyl4, }]
}
},
label: { show: false, },
data: [],
z: 0
},
{
type: 'bar',
barWidth: '40%',
barGap: '-100%',
animation: false,
itemStyle: {
borderWidth: 0,
borderRadius:5,
color: 'rgba(0,202,255,0.2)'
},
label: {
show: true,
position: ['101%', '20%'],
fontSize: 14,
fontWeight: 'normal',
formatter: (params)=>{
return ' ' + (state.chartData.data[params.dataIndex] ) + '%';
}
},
data: [],
z: 0
},
{
type: 'pictorialBar',
animation: true,
// animationThreshold: 3000 ,
animationDuration: 3000 ,
// animationDurationUpdate:500,
symbol: base64Img,
symbolSize: [50, 50],
symbolOffset: [20, 0],
z: 12,
itemStyle: {
color: '#fff'
},
data: []
},
]
}
processData();
}
const { proxy } = getCtx();
const dataScroll=()=>{
proxy.$timer("dataScrollBarHorizA",()=>{
let {data}=state.chartData
let {dataZoom}=state.chartOption
if (dataZoom.endValue == data.length ) {
dataZoom.endValue = 5;
dataZoom.startValue = 0;
}else{
dataZoom.endValue ++;
dataZoom.startValue ++;
}
state.chartOption.update=true
dataScroll()
},5000)
}
onMounted(() => {
processOption();
})
onBeforeMount(() => {
proxy.$timer("dataScrollBarHorizA")
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<script setup>
const state=reactive({
chartData:{
title:"任务完成情况",
legend:['开发任务1','采购任务2','销售任务3'],
colors:[$c.aql4, $c.cyl4,$c.cbl3],
colorsD:[$c.aql8,$c.cyl8,$c.bll8],
data:[72,14,36],
radius:["60%","75%","60%"],
position:[
['17%', '55%'],
['50%', '55%'],
['83%', '55%'],
],
},
chartOption:{}
})
const processData=()=>{
const {legend,colors,colorsD,data,radius,position}=state.chartData;
let processedData=[],
type="bar",
yAxisIndex=0;
legend.forEach((item,i)=>{
processedData.push({
type: 'gauge',
startAngle: 90,
endAngle: -270,
center: position[i],
radius: radius[i],
pointer: { show: false },
title: { fontSize: 14 },
itemStyle: {
color: colors[i],
shadowColor: colors[i],
},
progress: {
show: true,
overlap: false,
roundCap: true,
clip: false,
itemStyle: {}
},
detail: {
width: 50,
height: 14,
borderColor: 'inherit',
borderRadius: 20,
borderWidth: 0,
formatter: function (value) {
return '{value|' + value.toFixed(0) + '}{unit|%}';
},
rich: {
value: { fontSize: 24, color:colors[i], fontWeight: 'bolder'},// color: '#999',
unit: { fontSize: 12, color:$c.darken(colors[i],1),}
}
},
axisLine: {
lineStyle: {color: [[1, $c.darken(colors[i],4)]], width:10 }
},
splitLine: { show: false, distance: 0, length: 10 },
axisTick: { show: false },
axisLabel: { show: false, distance: 50 },
data:[
{
value: data[i],
name: legend[i],
title: { color:$c.lighten(colors[i],1), offsetCenter: ['0%', '30%'] },
detail: { valueAnimation: true, offsetCenter: ['0', '-30%'] }
}
],
})
})
state.chartOption.series=processedData;
}
const processOption=()=>{
state.chartOption={
update:false,
series: []
}
processData()
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<script setup>
const state=reactive({
chartData:{
legend:['本地', '异地'],
xAxis:['M1', 'M2', 'M3', 'M4', 'M5', 'M6', 'M7', 'M8', 'M9', 'M10', 'M11', 'M12'],
colors:[$c.aql4,$c.bll5,$c.ipl3,$c.cbl3,],
data:[
[ 230, 210,220,179,123, 120, 132, 101,168, 181, 134, 126, 134, 190, ],
[ 301, 334, 390, 330,300,240,235, 210, 187, 212, 278, 220, 320, 302,],
],
},
chartOption:{}
})
const processData=()=>{
let legend=state.chartData.legend,
colors=state.chartData.colors,
xAxis=state.chartData.xAxis,
data=state.chartData.data,
processedData=[]
legend.forEach((item,i)=>{
processedData.push({
name: legend[i],
type: 'line',
barWidth:15,
label: {
show: false,
position: 'insideRight'
},
itemStyle:{
color: colors[i],
borderRadius: 5
},
smooth: true,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: $c.fade(colors[i],.9)
}, {
offset: 0.8,
color: $c.fade(colors[i],.1)
}], false),
shadowcolor: $c.fade(colors[i],.3),
shadowBlur: 10
},
data: data[i]
})
})
state.chartOption.series=processedData;
state.chartOption.xAxis.data=xAxis;
state.chartOption.legend.data=legend;
}
const processOption=()=>{
state.chartOption={
update:false,
// title:{ text:"barA", left:200, top:0, textStyle:{ color:$c.gyl3, fontSize:16, fontWeight:"normal" }, },
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
show:true,
data: [],
top:"5",
right:10,
},
// toolbox: {
// feature: {
// magicType: { type: ['line', 'bar'] }
// },
// },
grid: {
left: '5%',
right: '5%',
bottom: '5%',
top: "15%",
containLabel: true
},
yAxis: {
type: 'value',
axisLabel: {align: 'right' }
},
xAxis: {
type: 'category',
boundaryGap: false,
data: [],
axisLabel: { interval:0, align: 'center' }
},
series: []
}
processData()
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
This diff is collapsed.
<script setup>
const state=reactive({
chartData:{
legend:['直接材料费','内部结算成本','其他直接费用','人工成本','折旧及摊销费','间接费用分摊数'],
colors:[$c.bll5,$c.inl3,$c.aql3,$c.yel3,$c.orl3,$c.rel3],
data:[325,252,323,183,120,43]
},
counter:{title:"费用总量",num:1723},
chartOption:{}
})
const processData=()=>{
let {legend,colors,data}=state.chartData,
processedData=[]
legend.forEach((item,i)=>{
processedData.push({
value:data[i],
name:legend[i],
itemStyle:{
color:colors[i]
}
})
})
state.chartOption.series[0].data=processedData;
state.chartOption.legend.data=legend;
}
const processOption=()=>{
state.chartOption={
update:false,
title:{
show:false,
text:"",
x:'center',
top:'32%',
textStyle:{
fontSize:24,
fontWeight:"bold",
lineHeight:30
},
},
tooltip: {
trigger: 'item',
formatter: "{a} <br/>{b}: {c} ({d}%)"
},
legend: {
orient: 'vertical',//horizontal
show:true,
right: '20',
top:'22%',
data:[],
formatter:(name)=>{
let target;
for(let i=0;i<state.chartData.data.length;i++){
if(state.chartData.legend[i]==name){
target=state.chartData.data[i]
}
}
return "{a|"+name+"}"+" "+"{b|"+target+"}"
},
textStyle:{
rich:{
a:{
fontSize:14,
color:$c.bll5,
padding:10
},
b:{
fontSize:16,
color:$c.cyl5
}
}
}
},
series: [
{
name:'数据类别',
type:'pie',
radius: ['40%', '65%'],
center: ['30%', '50%'],
//roseType: 'radius',
avoidLabelOverlap: false,
label: {
show: false,
position: 'outside',
},
itemStyle: {
borderRadius: 10,
borderColor: $c.bll9,
borderWidth: 5
},
emphasis: {
label:{
show: false,
fontSize: '20',
color:$c.gyd5,
}
},
labelLine: {
show: false
},
data:[]
}
]
}
processData()
}
onMounted(() => {
processOption();
})
</script>
<template>
<div class="echart-wrap">
<div class="total-digital">
<span class="desc">{{state.counter.title}}</span>
<DigitalTransform class="counter" :value="state.counter.num" :interval="1000" :dislocation="false" ></DigitalTransform>
</div>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</div>
</template>
<style lang="less">
.echart-wrap{height: 100%;
.total-digital{.fc(@cyl5); text-align: center; width: 100px; .poa; top:52%; left:20%; .fixc("y");
.desc{display:block; font-size: 18px; margin:0 0 10px 0;}
.counter{display:block; .ff("en0"); font-size: 24px; font-weight: bold;}
}
}
</style>
<script setup>
const { proxy } = getCtx();
const state=reactive({
fontColor:$c.wh,
subFontColor:$c.cbl3,
chartData:{
title:"业务利润占比",
colors:[$c.aql7, $c.cyl5],
data:[
{
name: '软件',
children: [
{
name: '产品',value:123,
children: [
{ name: 'GIS系统', value: 49 },
{ name: '可视化', value: 25},
{ name: '财务系统', value: 11 }
]
},
{
name: '定制',value:90,
children: [
{ name: '业务系统', value: 35 },
{ name: '门户', value:15 }
]
}
]
},
{
name: '硬件', children: [
{
name: '服务器',value:230, children: [
{ name: '入门级', value: 43 },
{ name: '企业级', value: 121 }
]
},
{
name: '网管设备',value:55, children: [
{ name: '安全网关', value: 23 },
{ name: '路由器', value: 12 }
]
}
]
}
],
dataMax:300
},
chartOption:{},
dataOri:[]
})
const {dataOri,fontColor,subFontColor}=toRefs(state)
const mapLinkAction=(data,time)=>{
const {chartData}=state
data.forEach((item,i)=>{
if(time==1&&item.value){
let rmdval=i*proxy.randomNumber(time*10,100)
item.value=rmdval
chartData.dataMax+=rmdval
}else if(item.value){
delete item.value
}
if(item.children&&item.children.length>0){
const num=time-1
mapLinkAction(item.children,num)
}
})
}
const processData=()=>{
const {colors,data}=state.chartData;
let processedData=[],
type="bar",
yAxisIndex=0;
processedData.push({
type: 'sunburst',
data: data,
radius: [20, '80%'],
center:['53%','50%'],
itemStyle: {
borderRadius: 7,
borderWidth: 2,
borderColor:$c.bll9,
},
label: {
show: true,
color:fontColor,
fontSize: 12,
rotate: 'tangential'//文字旋转
// formatter: function (param) {
// return param.name+'\n'+param.value
// }
},
emphasis: {
label:{
show: true,
fontSize: '16',
color:$c.wh,
formatter: function (param) {
return param.name+'\n'+param.value
}
}
},
levels: [{},]
})
state.chartOption.series=processedData;
}
const processOption=()=>{
const {dataMax,colors}=state.chartData
state.chartOption={
update:false,
title:{
text:"数据单位:万元 点击数据可下钻",subtext:"", right:20, bottom:0,
textStyle:{ color:subFontColor, fontSize:12, fontWeight:"normal" },
},
visualMap: {
type: 'continuous',
left:10,
bottom:40,
min: 0,
max: dataMax,
inRange: {
color: colors
},
textStyle:{
color:fontColor,
},
},
series: []
}
processData();
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<script setup>
const state=reactive({
chartData:{
legend:['埋深'],
colors:[$c.bll5,],
data:[235, 210, 187, 212, 278, 220, 320, 302, 301, 334],
},
chartOption:{ }
})
const props=defineProps({
barColor:{
type:String,
default:""
},
})
const processData=()=>{
const {barColor}=props
let {colors,xAxis,data}=state.chartData,
processedData=[],
color=barColor?barColor:colors[0]
processedData.push({
type: "line",
symbolSize: 0,
label: { show: false, },
itemStyle:{
color: $c.fade(color,.1),
borderRadius: 3,
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: $c.fade(color,.9)
}, {
offset: 0.8,
color: $c.fade(color,.5)
}], false),
// shadowcolor: $c.fade(color,.3),
// shadowBlur: 10
},
smooth: true,
data: data
})
state.chartOption.series=processedData;
state.chartOption.xAxis.data=xAxis;
}
const processOption=()=>{
state.chartOption={
update:false,
// title:{ text:"barA", left:200, top:0, textStyle:{ color:$c.gyl3, fontSize:16, fontWeight:"normal" }, },
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
grid: {
left: 0,
right: 0,
bottom: 0,
top: 0,
},
yAxis:{
type: 'value',
axisLine: {show:false},
splitLine: {show:false},
axisLabel: {show:false}
},
xAxis: {
type: 'category',
boundaryGap: false,
data: [],
axisLine: {show:false},
splitLine: {show:false},
axisLabel: {show:false,}
},
series: []
}
processData();
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<template>
<!--本组件后续会封装成标注组件,通过参数来配置不同的风格和外观-->
<div class="map-counter-wrap">
<div class="counter-item" v-for="(item,index) in state.counterList">
<div class="content">
<DigitalTransform class="num" :value="item.num" :useGrouping="false" :interval="2000"></DigitalTransform>
</div>
<div class="name">{{item.name}} <span class="unit">({{item.unit}})</span></div>
<echartLine :barColor="item.barColor"></echartLine>
</div>
</div>
</template>
<script setup>
import echartLine from "./echart-line.vue"
const state=reactive({
counterList:[
{name:"软件年盈利",num:394,unit:"万元",barColor:$c.rel3},
{name:"硬件年盈利",num:42558,unit:"万元",barColor:$c.yel3},
{name:"服务年盈利",num:50262,unit:"万元"},
{name:"安全年盈利",num:50262,unit:"万元"},
]
})
</script>
<style lang="less">
.counter-item-re(){.bgc(fade(@red9,90%));
.name{.fc(@rer4);
.unit{.fc(@rer4);}
}
.content{
.num,
.num .plus{.fc(@rer4);}
}
}
.counter-item-ye(){.bgc(fade(@yed9,90%));
.name{.fc(@yer5);
.unit{.fc(@yer5);}
}
.content{
.num,
.num .plus{.fc(@yer5);}
}
}
.map-counter-wrap{.poa; left:50%; .fixc("x"); top:80px; z-index: 10;
.counter-item{ width: 190px; display:inline-block; .bgc(fade(@bll9,80%)); height: 60px; margin:0 20px 0 0; padding:10px 0 0 10px; position: relative;.bdr(5px);
.name{.fc(var(--font-normal)); font-size: 12px; .ff("cn1"); z-index: 1; .poa; left:5px; top:5px;
.unit{font-size: 12px;}
}
.content{.fc(var(--font-normal));.poa; right:5px; top:5px;
.num{font-size: 18px; .por; .ff(impact);.fc(var(--font-normal));
.plus{.poa; left:101%; top:-5px; font-size: 12px; .fc(var(--font-normal)); font-weight: normal; .ff("arial");}
}
}
.echartsInit-wrap{.poa!important; left:0; right:0; bottom:0; height: 25px!important;min-height: 25px!important;}
&:nth-child(1){.counter-item-re;}
&:nth-child(2){.counter-item-ye;}
&:nth-child(3){}
&:last-child{margin:0;}
}
}
</style>
{
"icon":"path://m569.52,440.01c18.46,31.99-4.71,71.99-41.58,71.99H48.05c-36.94,0-60-40.05-41.58-71.99L246.42,23.99c18.47-32.01,64.72-31.95,83.15,0l239.94,416.03h0Zm-281.52-86.01c-25.4,0-46,20.6-46,46s20.6,46,46,46,46-20.6,46-46-20.6-46-46-46Zm-43.67-165.35l7.42,136c.35,6.36,5.61,11.35,11.98,11.35h48.55c6.37,0,11.64-4.98,11.98-11.35l7.42-136c.38-6.87-5.1-12.65-11.98-12.65h-63.38c-6.88,0-12.36,5.78-11.98,12.65h0Z"
}
\ No newline at end of file
<script setup>
import layout from "./layout.vue"
const state=reactive({
APConfig:{
height:930,
backgroundFillAll:true,
backgroundName:"A2",
chartCount:9
}
})
</script>
<template>
<adaptivePanel :config="state.APConfig"><layout></layout></adaptivePanel>
</template>
<style lang="less">
</style>
\ No newline at end of file
<script setup>
import echartBarHoriz from "./portlet/echart-barHoriz.vue"
import echartBar from "./portlet/echart-bar.vue"
import echartLine from "./portlet/echart-line.vue"
import echartBarLine from "./portlet/echart-barLine.vue"
import echartBarHorizScroll from "./portlet/echart-barHorizScroll.vue"
import echartGaugeTriple from "./portlet/echart-gaugeTriple.vue"
import echartsRadar from "./portlet/echarts-radar.vue"
import echartPie from "./portlet/echart-pie.vue"
import echartsPictorialBar from "./portlet/echarts-PictorialBar.vue"
import counterGrid from "./portlet/counter-grid.vue"
import mainNav from "@/common/mainNav.vue"
import externalLinks from "@/common/externalLinks.vue"
const router = useRouter();
const { proxy } = getCtx();
const comps={
echartBarHoriz,
echartLine,
echartBar,
echartBarHorizScroll,
echartGaugeTriple,
echartsRadar,
counterGrid,
echartPie,
echartsPictorialBar,
echartBarLine
}
const state=reactive({
systemTitleConfig:{
width:500
},
panelTitleConfig:{
width:160,
},
dialogConfig:{
show:false,
width:'60%',
height:'60%',
title:"对话框标题",
titleWidth:350,
},
// panelTitleConfig:{
// width:180,
// theme:true
// },
areas:[
{name:"left",portlets:[
{id:"l2",title:"收支情况",component:"echartsPictorialBar",border:"aYinTechBorderA1",hideTitle:true},
{id:"l3",title:"业务收益情况",component:"echartBar",border:"aYinTechBorderA1",hideTitle:true},
{id:"l1",title:"销售任务",component:"echartsRadar",border:"aYinTechBorderA1",hideTitle:true},
]},
{name:"center",portlets:[
{id:"c1",title:"销售情况",component:"counterGrid",border:"blank",hideTitle:true},
{id:"c2",title:"任务完成情况",component:"echartPie",border:"aYinTechBorderA1",hideTitle:true},
{id:"c3",title:"业务利润占比",component:"echartGaugeTriple",border:"aYinTechBorderA1",hideTitle:true},
{id:"c4",title:"业务利润占比",component:"echartBarLine",border:"aYinTechBorderB4"},
]},
{name:"right",portlets:[
{id:"r1",title:"销售情况",component:"echartLine",border:"aYinTechBorderA1",hideTitle:true},
{id:"r2",title:"任务完成情况",component:"echartBarHoriz",border:"aYinTechBorderA1",hideTitle:true},
{id:"r3",title:"业务利润占比",component:"echartBarHorizScroll",border:"aYinTechBorderA1",hideTitle:true},
]},
]
})
const {systemTitleConfig,panelTitleConfig,dialogConfig,areas}=toRefs(state)
const chartCounter=computed(()=>{
return this.$vuex.state.adaptiveConfig.chartCounter;
})
const getConfig=(item)=>{
const {id}=item
if(id=='c2'){
return {
title:item.title,
opacity: 0.5,
decoration:false,
}
}else if(id=='c3'){
return {
title:item.title,
opacity: 0.5,
rotate:"y",
decoration:false,
}
}else if(id.includes("l")){
return {
title:item.title,
titleWidth:120,
decoration:false,
decorationAlt: true,
rotate: "y",
opacity: 0.5
}
}else{
return {
title:item.title,
titleWidth:120,
decoration:false,
opacity:.5
}
}
}
onMounted(()=>{ })
</script>
<template>
<div class="screen1080B">
<mainNav></mainNav>
<externalLinks></externalLinks>
<div :class="`area-box area-${area.name}`" v-for="area in areas" :key="area.id">
<div class="portlet-wrapper" v-for="item in area.portlets" :key="item.id">
<component v-if="item.border" :is='item.border' :config="getConfig(item)">
<panelTitleA1 v-if="!item.hideTitle" :config="panelTitleConfig" >{{item.title}}</panelTitleA1>
<component :is='comps[item.component]' ></component>
</component>
<template v-else>
<component :is='item.component'></component>
<i>{{item.component}}</i>
</template>
</div>
</div>
<systemTitleA1 :config="systemTitleConfig">TechUI数据可视化成型工具</systemTitleA1>
</div>
</template>
<style lang="less">
.screen1080B{ z-index: 1;padding:60px 30px 30px 30px; height: 100%; //url(../common/images/bg.png)
.techButtonA2 {z-index: 10; .poa; bottom:20px; left:50%; .fixc("x");}
.i(){.poa; bottom:0; right:10px; font-size: 12px; opacity: .1; .fc(@wh); z-index: 10;}
display: grid; grid-template-columns: repeat(24,1fr); grid-template-rows:repeat(24,1fr); grid-gap: 30px;
.area-box{.bdr(5px); pointer-events: visible; position: relative; z-index: 10;
.board-3d-wrap{ .poa; .fullbox;
}
//<row-start> / <column-start> / <row-end> / <column-end>;
.blank,
.portlet-wrapper{.por;
>i{.i;}
}
.border-content{>i{.i;}}
&.area-left{ grid-area: 1 / 1 / 25 / 7; }
&.area-right{ grid-area: 1 / 19 / 25 / 25; }
&.area-center{grid-area: 1 / 7 / 25 / 19; }
&.area-left,
&.area-right,
&.area-center{ display: grid; grid-template-columns: repeat(1,1fr); grid-template-rows:repeat(24,1fr); grid-gap: 20px;
.portlet-wrapper{
&:nth-child(1){grid-area: 1 / 1 / 8 / 3;}
&:nth-child(2){grid-area: 8 / 1 / 15 / 3;}
&:nth-child(3){grid-area: 15 / 1 / 25 / 3;}
}
}
&.area-center{grid-template-columns: repeat(2,1fr);
.portlet-wrapper{
&:nth-child(1){grid-area: 1 / 1 / 8 / 3;}
&:nth-child(2){grid-area: 8 / 1 / 15 / 2;}
&:nth-child(3){grid-area: 8/ 2 / 15 / 3;}
&:nth-child(4){grid-area: 15 / 1 / 25 / 3;}
}
}
}
.content-tabs{.poa; top:-40px; left:80px; right:80px; text-align: center; height: 40px;
&:before{content:" "; .bdb(var(--button-bd_hov));left:0; right:0; bottom:10px;.poa; z-index: 1;}
.tabs-item{display:inline-block; padding:0 10px; .ff("cn1"); .fc(var(--font-normal)); height: 30px;line-height: 30px; cursor: pointer; .ani; z-index: 2; .por;
&:before{content:" "; .bgc(var(--button-bd_hov)); .poa; .fullbox; opacity: 0;}
&:hover{&:before{opacity: .3;}}
&.active{ .bdb(var(--font-strong)); .fc(var(--font-strong));}
}
}
}
</style>
\ No newline at end of file
<script setup>
const state=reactive({
arry:[
{title:"软件销售额",icon:"i carbon:ibm-z-cloud-mod-stack",unit:"万元",total:"1874"},
{title:"硬件销售额",icon:"i carbon:chip",unit:"万元",total:"3276"},
{title:"技术服务",icon:"i carbon:user-speaker",unit:"万元",total:"315"},
{title:"安全服务",icon:"i carbon:rule",unit:"万元",total:"769"},
{title:"总支出费用",icon:"i carbon:airline-digital-gate",unit:"万元",total:"23769"},
],
})
const decoFrameConfig={
directionAlt: true,
scale:.8
}
</script>
<template>
<div class="screenB-counterGrid">
<div class="content-wrap" v-for="(item,index) in state.arry" :key="index">
<decoFrameA2 :config="decoFrameConfig"><i :class="[item.icon,'icon']"></i></decoFrameA2>
<DigitalTransform class="numbers" :value="item.total" :useGrouping="true" :interval="3000"></DigitalTransform>
<div class="block-title">{{item.title}} <span class="unit" v-if="item.unit">({{item.unit}})</span></div>
</div>
</div>
</template>
<style lang="less">
.screenB-counterGrid{ margin-top:30px; display: grid; grid-template-columns: repeat(5,1fr); height: 100%; grid-template-rows: repeat(1,1fr); grid-gap: 12px; position: relative;
.content-wrap{.por; text-align: center;
.decoFrameA2{margin:0 auto;}
.block-title{.ff("cn1"); .fc(@cbl3); font-size: 20px; line-height: 1.5;
.unit{display:block; font-size: 12px;}
}
.numbers{display:inline-block; text-align: center; height:38px; line-height: 1; font-size: 38px; .ff("en0"); position: relative; vertical-align: text-top; .fc(@cbl3); }
}
}
</style>
<script setup>
const state=reactive({
chartData:{
legend:['本地视频会议', '异地视频会议'],
xAxis:['十二月', '一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月'],
colors:[$c.bll4,$c.aql4,$c.ipl3,$c.cbl3,],
data:[
[235, 210, 187, 212, 278, 220, 320, 302],
[68, 121, 34, 56, 23, 120, 132, 101, 134]
],
},
chartOption:{}
})
const processData=()=>{
let legend=state.chartData.legend,
colors=state.chartData.colors,
xAxis=state.chartData.xAxis,
data=state.chartData.data,
processedData=[]
legend.forEach((item,i)=>{
processedData.push({
name: legend[i],
type: 'bar',
// barWidth:10,
label: {
show: false,
position: 'insideRight'
},
itemStyle:{
color: colors[i],
borderRadius: 5
},
data: data[i]
})
})
state.chartOption.series=processedData;
state.chartOption.xAxis.data=xAxis;
}
const processOption=()=>{
state.chartOption={
update:false,
// title:{ text:"barA", left:200, top:0, textStyle:{ color:$c.gyl3, fontSize:16, fontWeight:"normal" }, },
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
//show:false,
data: [],
top:"5",
right:60,
},
// toolbox: { feature: { magicType: { type: ['line', 'bar'] } }, },
grid: {
left: '5%',
right: '5%',
bottom: '5%',
top: "20%",
containLabel: true
},
yAxis: {
type: 'value',
axisLabel: {align: 'right' }
},
xAxis: {
type: 'category',
data: [],
axisLabel: { align: 'center' }
},
series: []
}
processData()
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<script setup>
const state=reactive({
chartData:{
legend:['收入', '支出'],
yAxis:['业务1', '业务2', '业务3', '业务4', '业务5', '业务6'],
colors:[$c.cbl4,$c.bll5,],
data:[
[320, 302, 341, 374, 390, 450],
[-120, -132, -101, -134, -190, -230],
],
},
chartOption:{}
})
const processData=()=>{
let {legend,colors,yAxis,data}=state.chartData,
processedData=[];
legend.forEach((item,i)=>{
processedData.push({
name: legend[i],
type: 'bar',
barWidth:10,
stack: 'Total',
label: {
color:$c.wh,
show: true
},
emphasis: {
focus: 'series'
},
itemStyle:{
color: $c.fade(colors[i],.9),
borderRadius: 3
},
data: data[i]
})
})
state.chartOption.legend.data=legend;
state.chartOption.series=processedData;
state.chartOption.yAxis.data=yAxis;
}
const processOption=()=>{
state.chartOption={
update:false,
// title:{ text:"barA", left:200, top:0, textStyle:{ color:$c.gyl3, fontSize:16, fontWeight:"normal" }, },
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
legend: {
left: '15',
top: '5',
},
grid: {
left: '5%',
right: '10%',
bottom: '8%',
top: "15%",
containLabel: true
},
xAxis: {
type: 'value',
axisLabel: {
align: 'center',
interval:0,
}
},
yAxis: {
type: 'category',
axisTick: {
show: false
},
data: [],
axisLabel: {
formatter: '{value}',
align: 'right'
}
}
}
processData();
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<script setup>
const base64Img="image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAA6CAMAAADWZboaAAAAZlBMVEUAAABe3uVe3+Vf3uVf3+Zf3uVg3+Zg3+Zf3+Vi4OZh4OZg3+Z86/Bh3+Zi4Odj4Odi4OZ86/B76/B86/Bj4ed56+9x5+xn4umB7/N87PB36e+A7/N+7fF/7vJ/7vJ+7fGA7/OB7/PReX+lAAAAIXRSTlMABQkVDREmIhk3MR10LEFFPHh7cUprXE35h2XnqMLAp+mHAG9cAAAB5ElEQVRIx83WjU7CMBQFYIoiKMqU/XUboHv/l/Tce7t2XamDNSacETEmX86tlK2rx4py150o+MstMBLwWRfHKo6JCVxLnvmFGBjFQ58oF1//sUZhGy/ClSTWObgnL4O+bkeN4nY2okfNMbkRt9/vtxz8InoTsWplJSCzFxPmO8+GpSIByX3YQAuGDWtRKhKjCnxDXhF6Z4yxnZ20Wgko7BMRDmxtSGVaI4kdTIgb+zTYoJQlIMlDlmUFgrcDWWC201qSayqlTkiCddWWeV62VU0YlnpRi9VOKaSUsiyq/N0krwq2Ugt7lVpZl5BfHNiytjagMi+XYp0kCR45hMlivVQrE/uU5pXSrCB5bM6d1t2lOZItMqmliT3q5uVxqxzyW/ccfYLNKx7ZTeykMvNyac2yt2Fbc61MHLSC0rwoxbiNdlQ3GBm1NLHQsHUrtEXppR/ljNpW6DbSCoqlFiVoN6YdaFlgsSFVPs1BdT8OaB5QyQzVcaqWDows/zepxR8ObLglTrdtCRVuRNj4Rrxh+//0ke2f8KVL+Kon3GCSbmsJN9OUW3j6g0Ns+LgCij2u0h+Sghc8mlMPBMgdx5DFh59VmOVHrvmDnoNxCz3J7MFWsMuaLyR089xz/xhlfijvwutR8gv3zk6BLUUeCgAAAABJRU5ErkJggg=="
const state=reactive({
chartData:{
yAxis:['任务A', '任务B', '任务C', '任务较长名称D', '任务E', '任务F', '任务G', '任务H', '任务I'],
color:[$c.cyl4,$c.orl5,$c.rel5],
data:[69, 96, 35,26, 96, 32 ,52 ,22 ,72]
},
chartOption:{}
})
const fillArr=computed(()=>{
return (new Array(state.chartData.data.length)).fill(100);
})
const getSymbolData=(data)=>{
let arr = [];
for (var i = 0; i < data.length; i++) {
arr.push({
value: data[i],
symbolPosition: 'end'
})
}
return arr;
}
const processData=()=>{
let legend=state.chartData.legend,
colors=state.chartData.colors,
yAxis=state.chartData.yAxis,
data=state.chartData.data,
processedData=[];
state.chartOption.yAxis.data=state.chartData.yAxis;
state.chartOption.series[0].data=state.chartData.data;
state.chartOption.series[1].data=fillArr;
state.chartOption.series[2].data=getSymbolData(state.chartData.data);
dataScroll();
}
const processOption=()=>{
state.chartOption={
update:false,
title: {
show:false,
// text: '实时流速图2',
textStyle:{
color:$c.cbl5,
fontSize:16,
fontWeight:"normal"
},
},
grid: {
top: '10%',
left: '18%',
right: '12%',
bottom: '5%'
},
tooltip: {show: false},
xAxis: {
type: 'value',
min: 0,
max: 100,
axisLine: {show: false},
splitLine: {show: false},
axisLabel: {show: false},
axisTick: {show: false}
},
dataZoom: {
yAxisIndex: 0,
show: false,
type: "slider",
startValue: 0,
endValue: 5,
},
yAxis: {
//show: false,
type: 'category',
inverse: true,
splitLine: {show: false,},
axisLine: {show: false},
axisLabel: {
show: true,
interval: 0,
margin: 10,
fontSize: 12,
width:50,
lineHeight:14,
overflow:"breakAll",
fontWeight: 'normal',
},
axisTick: {show: false},
data:[]
},
series: [
{
type: 'bar',
barWidth: '40%',
animationDuration:2000,
itemStyle: {
borderWidth:0,
borderRadius:10,
color: {
type: 'linear', x: 0, y: 0, x2: 1, y2: 0,
colorStops: [{ offset: 0, color: $c.cyl8, }, { offset: 1, color: $c.cyl4, }]
}
},
label: { show: false, },
data: [],
z: 0
},
{
type: 'bar',
barWidth: '40%',
barGap: '-100%',
animation: false,
itemStyle: {
borderWidth: 0,
borderRadius:5,
color: 'rgba(0,202,255,0.2)'
},
label: {
show: true,
position: ['101%', '20%'],
fontSize: 14,
fontWeight: 'normal',
formatter: (params)=>{
return ' ' + (state.chartData.data[params.dataIndex] ) + '%';
}
},
data: [],
z: 0
},
{
type: 'pictorialBar',
animation: true,
// animationThreshold: 3000 ,
animationDuration: 3000 ,
// animationDurationUpdate:500,
symbol: base64Img,
symbolSize: [50, 50],
symbolOffset: [20, 0],
z: 12,
itemStyle: {
color: '#fff'
},
data: []
},
]
}
processData();
}
const { proxy } = getCtx();
const dataScroll=()=>{
proxy.$timer("dataScrollBarHorizB",()=>{
let {data}=state.chartData
let {dataZoom}=state.chartOption
if (dataZoom.endValue == data.length ) {
dataZoom.endValue = 5;
dataZoom.startValue = 0;
}else{
dataZoom.endValue ++;
dataZoom.startValue ++;
}
state.chartOption.update=true
dataScroll()
},5000)
}
onMounted(() => {
processOption();
})
onBeforeMount(() => {
proxy.$timer("dataScrollBarHorizB")
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<script setup>
const state=reactive({
chartData:{
legend:['合同成本','毛利润','已回款', '已开票','毛利率%','回款率%'],
xAxis:['数据1', '数据2', '数据3', '数据4', '数据5', '数据6', '数据7', '数据8', '数据9', '数据10', '数据11', '数据12','数据13', '数据14', '数据15', '数据16', '数据17', '数据18', '数据19', '数据20', '数据21', '数据22', '数据23', '数据24'],
colors:[$c.aql2,$c.acl6,$c.bil4,$c.ipl4,$c.rel4,$c.yel3],
data:[
[235, 210, 187, 212, 278, 220, 320, 302, 301, 334, 390, 330,300,240,345,235, 210, 187, 212, 278, 220, 320, 302, 301, 334, 390, 330,300,240,345],
[22, 76, 13, 20,35, 30,20,9,13, 10, 50, 15,88,50, 85,22, 76, 13, 20,35, 60,20,9,13, 10, 80, 15,88,50, 85],
[193, 185, 122, 76, 70, 120, 135, 24,32,9,13, 110, 132, 53,88,193, 185, 122, 76, 32, 120, 135, 14,42,9,13, 110, 132, 12,88 ],
[35, 10,22,9,13, 10, 32, 15,0,93, 85, 22, 76, 13, 20,35, 10,0,9,13, 10, 32, 15,0,93, 85, 22, 76, 13, 20],
[5,20,9,13, 10, 22, 23, 13, 20,35,4, 15,37,0, 54,5,20,9,13, 10, 22, 23, 13, 20,35,4, 15,37,0, 54],
[35,0, 15,58,0,0,20,9,13, 10, 85, 22, 76, 13, 20,35,0, 15,58,0,0,20,9,13, 10, 85, 22, 76, 13, 20],
],
},
chartOption:{}
})
const processData=()=>{
let {legend,colors,xAxis,data}=state.chartData,
processedData=[],
yAxisIndex=0,
xName=[
"徽商银行关于2022年采购项目维保终端技术服务交换机合同",
"长城汽车诺博汽车系统徐采购项目维保终端技术服务交换机合同",
"中信银行济南分行4G采购项目维保终端技术服务交换机合同",
"中国科学院空天信息创采购项目维保终端技术服务交换机合同",
"中国信息创新研究院采购项目维保终端技术服务交换机合同",
"上海黄金交易所采购项目维保终端技术服务交换机合同",
"2022年苏州银行采购项目维保终端技术服务交换机合同",
"齐齐哈尔移动采购项目维保终端技术服务交换机合同",
"博时基金2022红帽采购项目维保终端技术服务交换机合同",
"航信远程监控项目采购项目维保终端技术服务交换机合同",
"全路通信信号设计院采购项目维保终端技术服务交换机合同",
"全路通信信号设计院服务器采购项目维保终端技术服务交换机合同",
"徽商银行关于2022年采购项目维保终端技术服务交换机合同",
"长城汽车诺博汽车系统徐采购项目维保终端技术服务交换机合同",
"中信银行济南分行4G采购项目维保终端技术服务交换机合同",
"中国科学院空天信息创采购项目维保终端技术服务交换机合同",
"中国信息创新研究院采购项目维保终端技术服务交换机合同",
"上海黄金交易所采购项目维保终端技术服务交换机合同",
"2022年苏州银行采购项目维保终端技术服务交换机合同",
"齐齐哈尔移动采购项目维保终端技术服务交换机合同",
"博时基金2022红帽采购项目维保终端技术服务交换机合同",
"航信远程监控项目采购项目维保终端技术服务交换机合同",
"全路通信信号设计院采购项目维保终端技术服务交换机合同",
"全路通信信号设计院服务器采购项目维保终端技术服务交换机合同"
];
xAxis.forEach((item,i)=>{
xAxis[i]=xName[i]//+"1"
})
legend.forEach((item,i)=>{
if(i>3){yAxisIndex=1}
processedData.push({
name: legend[i],
type: i>=legend.length-2?'line':'bar',
stack: i<2?'01':null,
barWidth:i==0?20:15,
label: {
show: false,
position: 'insideRight'
},
itemStyle:{
color: $c.fade(colors[i],.9),
borderRadius: 3,
},
z:10-i,
smooth: true,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: $c.fade(colors[i],.9) },
{ offset: 0.8, color: $c.fade(colors[i],.1) }
], false),
shadowcolor: $c.fade(colors[i],.3),
shadowBlur: 10
},
yAxisIndex:yAxisIndex,
data: data[i]
})
})
state.chartOption.legend.data=legend;
state.chartOption.series=processedData;
state.chartOption.xAxis.data=xAxis;
state.chartOption.xAxis.axisLabel.formatter=(str,index)=>{
// if (index % 2 != 0) { return '\n\n\n' + value; }
// else{ return value; }
let newstr= str, strLT=0,theNum=0;
for(let i=0;i<str.length;i++){
if(strLT<20){
if(str.charCodeAt(i)>255){
strLT++
}else{
strLT+=0.5
}
}else{
theNum=i;
break;
}
}
if(theNum>0){ newstr=newstr.substring(0,theNum)+"..."; }
return newstr;
}
}
const processOption=()=>{
state.chartOption={
update:false,
// title:{ text:"barA", left:200, top:0, textStyle:{ color:$c.gyl3, fontSize:16, fontWeight:"normal" }, },
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
legend: {
itemGap: 15,
left: 'center',
top: '50',
},
dataZoom:[
{
type: 'slider',
xAxisIndex: [0],
height: 30,
filterMode: 'filter',
bottom: 40,
start:0,
end:20,
show: true,
minSpan:5,
maxSpan:30,
moveHandleSize: 15 ,
showDetail:false
},
{
type: 'inside',// 内置于坐标系中
start: 0,
end: 20,
xAxisIndex: [0],
minSpan:5,
maxSpan:30
},
],
grid: {
left: '2%',
right: '2%',
bottom: '20%',
top: "25%",
containLabel: true
},
yAxis:[
{
type: 'value',
name: '单位:万元',
// min: 0,
// max: 300,
splitNumber: 3,
position: 'left',
axisLabel: {
formatter: '{value}',
align: 'right'
}
},
{
type: 'value',
name: '单位:%',
min: 0,
max: 100,
position: 'right',
offset: 0,
splitLine:{
show:false,
},
axisLabel: {
formatter: '{value}',
}
},
],
xAxis: {
type: 'category',
data: [],
axisLabel: {
align: 'center',
interval:0,
width:90,
lineHeight:14,
overflow:"breakAll",
margin:20,
},
},
series: []
}
processData()
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<script setup>
const state=reactive({
chartData:{
title:"任务完成情况",
legend:['开发任务1','采购任务2','销售任务3'],
colors:[$c.aql4, $c.cyl4,$c.cbl3],
colorsD:[$c.aql8,$c.cyl8,$c.bll8],
data:[72,14,36],
radius:["50%","65%","50%"],
position:[
['17%', '55%'],
['50%', '55%'],
['83%', '55%'],
],
},
chartOption:{}
})
const processData=()=>{
const {legend,colors,colorsD,data,radius,position}=state.chartData;
let processedData=[],
type="bar",
yAxisIndex=0;
legend.forEach((item,i)=>{
processedData.push({
type: 'gauge',
startAngle: 90,
endAngle: -270,
center: position[i],
radius: radius[i],
pointer: { show: false },
title: { fontSize: 14 },
itemStyle: {
color: colors[i],
shadowColor: colors[i],
},
progress: {
show: true,
overlap: false,
roundCap: true,
clip: false,
itemStyle: {}
},
detail: {
width: 50,
height: 14,
borderColor: 'inherit',
borderRadius: 20,
borderWidth: 0,
formatter: function (value) {
return '{value|' + value.toFixed(0) + '}{unit|%}';
},
rich: {
value: { fontSize: 24, color:colors[i], fontWeight: 'bolder'},// color: '#999',
unit: { fontSize: 12, color:$c.darken(colors[i],1),}
}
},
axisLine: {
lineStyle: {color: [[1, $c.darken(colors[i],4)]], width:10 }
},
splitLine: { show: false, distance: 0, length: 10 },
axisTick: { show: false },
axisLabel: { show: false, distance: 50 },
data:[
{
value: data[i],
name: legend[i],
title: { color:$c.lighten(colors[i],1), offsetCenter: ['0%', '30%'] },
detail: { valueAnimation: true, offsetCenter: ['0', '-30%'] }
}
],
})
})
state.chartOption.series=processedData;
}
const processOption=()=>{
state.chartOption={
update:false,
series: []
}
processData()
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<script setup>
const state=reactive({
chartData:{
legend:['本地', '异地'],
xAxis:['M1', 'M2', 'M3', 'M4', 'M5', 'M6', 'M7', 'M8', 'M9', 'M10', 'M11', 'M12'],
colors:[$c.aql4,$c.bll5,$c.ipl3,$c.cbl3,],
data:[
[ 230, 210,220,179,123, 120, 132, 101,168, 181, 134, 126, 134, 190, ],
[ 301, 334, 390, 330,300,240,235, 210, 187, 212, 278, 220, 320, 302,],
],
},
chartOption:{}
})
const processData=()=>{
let legend=state.chartData.legend,
colors=state.chartData.colors,
xAxis=state.chartData.xAxis,
data=state.chartData.data,
processedData=[]
legend.forEach((item,i)=>{
processedData.push({
name: legend[i],
type: 'line',
barWidth:15,
label: {
show: false,
position: 'insideRight'
},
itemStyle:{
color: colors[i],
borderRadius: 5
},
smooth: true,
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: $c.fade(colors[i],.9)
}, {
offset: 0.8,
color: $c.fade(colors[i],.1)
}], false),
shadowcolor: $c.fade(colors[i],.3),
shadowBlur: 10
},
data: data[i]
})
})
state.chartOption.series=processedData;
state.chartOption.xAxis.data=xAxis;
state.chartOption.legend.data=legend;
}
const processOption=()=>{
state.chartOption={
update:false,
// title:{ text:"barA", left:200, top:0, textStyle:{ color:$c.gyl3, fontSize:16, fontWeight:"normal" }, },
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
show:true,
data: [],
top:5,
left:15,
},
grid: {
left: '5%',
right: '5%',
bottom: '5%',
top: "20%",
containLabel: true
},
yAxis: {
type: 'value',
axisLabel: {align: 'right' }
},
xAxis: {
type: 'category',
boundaryGap: false,
data: [],
axisLabel: { interval:0, align: 'center' }
},
series: []
}
processData()
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
This diff is collapsed.
<script setup>
const state=reactive({
chartData:{
legend:['软件','硬件','服务','安全','广告'],
colors:[$c.bll5,$c.inl3,$c.aql3,$c.yel3,$c.orl3,$c.rel3],
data:[325,252,323,183,120,43]
},
counter:{title:"费用总量",num:1723},
chartOption:{}
})
const processData=()=>{
let {legend,colors,data}=state.chartData,
processedData=[]
legend.forEach((item,i)=>{
processedData.push({
value:data[i],
name:legend[i],
itemStyle:{
color:colors[i]
}
})
})
state.chartOption.series[0].data=processedData;
state.chartOption.legend.data=legend;
}
const processOption=()=>{
state.chartOption={
update:false,
title:{
show:false,
text:"",
x:'center',
top:'32%',
textStyle:{
color:$c.bll5,
fontSize:24,
fontWeight:"bold",
lineHeight:30
},
},
tooltip: {
trigger: 'item',
formatter: "{a} <br/>{b}: {c} ({d}%)"
},
legend: {
orient: 'vertical',//horizontal
show:true,
right: '40',
top:'22%',
data:[],
formatter:(name)=>{
let target;
for(let i=0;i<state.chartData.data.length;i++){
if(state.chartData.legend[i]==name){
target=state.chartData.data[i]
}
}
return "{a|"+name+"}"+" "+"{b|"+target+"}"
},
textStyle:{
rich:{
a:{
fontSize:14,
color:$c.bll5,
padding:10
},
b:{
fontSize:16,
color:$c.cyl5
}
}
}
},
series: [
{
name:'数据类别',
type:'pie',
radius: ['55%', '80%'],
center: ['30%', '50%'],
//roseType: 'radius',
avoidLabelOverlap: false,
label: {
show: false,
position: 'outside',
},
itemStyle: {
borderRadius: 10,
borderColor: $c.bll9,
borderWidth: 5
},
emphasis: {
label:{
show: false,
fontSize: '20',
color:$c.gyd5,
}
},
labelLine: {
show: false
},
data:[]
}
]
}
processData()
}
onMounted(() => {
processOption();
})
</script>
<template>
<div class="echart-wrap-dashB">
<div class="total-digital">
<span class="desc">{{state.counter.title}}</span>
<DigitalTransform class="counter" :value="state.counter.num" :interval="1000" :dislocation="false" ></DigitalTransform>
</div>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</div>
</template>
<style lang="less">
.echart-wrap-dashB{height: 100%;
.total-digital{.fc(@cyl5); text-align: center; width: 100px; .poa; top:52%; left:19%; .fixc("y");
.desc{display:block; font-size: 18px; margin:0 0 10px 0;}
.counter{display:block; .ff("en0"); font-size: 24px; font-weight: bold;}
}
}
</style>
<script setup>
const symbol = {
0:'path://M288,358.3c13.98-8.09,17.53-30.04,28.88-41.39s33.3-14.88,41.39-28.87c7.98-13.79,.17-34.54,4.37-50.29,4.06-15.25,20.46-29.25,20.46-45.75s-17.27-30.52-21.34-45.73c-4.21-15.75,3.61-36.5-4.36-50.29-8.09-13.98-30.03-17.52-41.38-28.87-11.35-11.35-14.89-33.3-28.87-41.39-13.79-7.98-34.54-.16-50.29-4.38-14.36-4.08-28.36-21.35-44.86-21.35s-30.5,17.27-45.7,21.34c-15.8,4.2-36.5-3.61-50.32,4.36-13.98,8.09-17.52,30.04-28.87,41.38-11.34,11.35-33.3,14.89-41.39,28.87-7.98,13.75-.16,34.55-4.37,50.25-4.08,15.3-21.35,29.3-21.35,45.8s17.27,30.52,21.34,45.73c4.21,15.75-3.61,36.5,4.36,50.29,8.1,13.98,30.04,17.48,41.38,28.88,11.35,11.35,14.89,33.3,28.88,41.4,13.79,7.98,34.53,.16,50.28,4.37,15.26,4.03,29.26,21.33,45.76,21.33s30.52-17.27,45.74-21.34c15.76-4.16,36.46,3.64,50.26-4.36ZM112,192c0-44.27,35.81-80,80-80s80,35.73,80,80-35.81,80-80,80-80-35.8-80-80ZM1.72,433.2c-3.25,8.19-1.78,17.48,3.87,24.25,5.66,6.75,14.53,9.9,23.12,8.15l45.19-9.04,21.43,42.27c4.13,8.17,12.27,13.17,21.37,13.17,.34,0,.66-.01,1.01-.03,9.5-.38,17.65-6.08,21.24-14.88l33.58-82.08c-53.71-4.64-102-28.12-138.2-63.95L1.72,433.2Zm347.88-82.1c-36.15,35.83-84.45,59.31-138.2,63.95l33.58,82.08c3.59,8.8,11.74,14.5,21.24,14.88,.38-.91-.12-.01,1.08-.01,9.09,0,17.23-4.97,21.35-13.14l21.43-42.28,45.19,9.04c8.59,1.75,17.47-1.4,23.12-8.15,5.66-6.77,7.12-16.06,3.88-24.25l-32.66-82.12Z',
};
const state=reactive({
chartData:{
legend:['预算成本'],
yAxis:["队伍A", "队伍B", "队伍C", "队伍D", "队伍E"],
colors:["#19e680","#00e8b8","#00e6df","#00c7f3","#009af3"],
colorsD:["#052e1a","#003328","#003331","#002a33","002033"],
data: [93, 85, 22, 76, 13],
},
chartOption:{ }
})
const processData=()=>{
let {legend,colors,colorsD,yAxis,data}=state.chartData,
processedData1={
tooltip: { show: false },
z: 4,
type: "pictorialBar",
symbolSize: ['20', '25'],
symbolRepeat: "fixed",
symbolMargin:12,
itemStyle:{
color: (item)=>{
return $c.fade(colorsD[item.dataIndex],.8)
},
},
data: []
},
processedData2={
z: 6,
type: "pictorialBar",
symbolSize: ['20', '25'],
animation: true,
symbolRepeat: "fixed",
symbolMargin:12,
symbolClip: true,
symbolPosition: "start",
symbolOffset: [0, 0],
itemStyle:{
color: (item)=>{
return $c.fade(colors[item.dataIndex],.8)
},
},
data: [],
label: { show: true, color: '#18fcff', fontSize: 14, position: "right", offset: [20, 0] },
};
data.forEach((item,i)=>{
processedData1.data.push(
{ value: 100, symbol: symbol[0], },
)
processedData2.data.push(
{ value: item, symbol: symbol[0], },
)
})
// state.chartOption.legend.data=legend;
state.chartOption.series[0]=processedData1;
state.chartOption.series[1]=processedData2;
state.chartOption.yAxis.data=yAxis;
}
const processOption=()=>{
state.chartOption={
update:false,
grid: {
left: "5%",
top: "20%",
bottom: "5%",
right: "20%",
containLabel: true
},
tooltip: {
trigger: "item",
},
xAxis: {
splitLine: { show: false },
axisLine: { show: false },
axisLabel: { show: false },
axisTick: { show: false }
},
yAxis:{
type: "category",
inverse: true,
data: [],
axisLine: { show: false },
axisTick: { show: false },
splitLine: { show: false, lineStyle: { type: "dashed" } },
axisLabel: { margin: 20, fontSize: 14, }
},
series: [ ]
}
processData()
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<script setup>
const state=reactive({
chartData:{
legend:['预算分配','实际开销'],
colors:[$c.bll5,$c.cyl5,],
data:[
[5000, 3400, 2800,4100, 4200, 2100],
[4300, 3000, 3700, 1500, 5000, 4900],
],
indicator: [
{ name: '销售', max: 5000,},
{ name: '管理', max: 5000, },
{ name: '技术', max: 5000, },
{ name: '客服', max: 5000, },
{ name: '研发', max: 5000, },
{ name: '市场', max: 5000, }
],
},
chartOption:{ }
})
const processData=()=>{
let {legend,colors,data,indicator}=state.chartData,
processedData=[]
legend.forEach((item,i)=>{
processedData.push({
name: legend[i],
type: "radar",
symbol: "circle",
color:colors[i],
symbolSize: 10,
areaStyle: {
color: $c.fade(colors[i],.4)
},
// itemStyle: {
// color: $c.fade(colors[i],.9),
// bordercolor: $c.fade(colors[i],.3),
// borderWidth: 10,
// },
lineStyle: {
color: $c.fade(colors[i],.9),
width: 2
},
data: [data[i]]
})
})
state.chartOption.legend.data=legend;
state.chartOption.series=processedData;
state.chartOption.radar.indicator=indicator;
}
const processOption=()=>{
state.chartOption={
update:false,
// title:{ text:"barA", left:200, top:0, textStyle:{ color:$c.gyl3, fontSize:16, fontWeight:"normal" }, },
title:{
text:"异常特征分布1",
show:false,
left:0,
top:0,
textStyle:{
color:$c.cbl5, fontSize:16, fontWeight:"normal"
},
},
tooltip: {
show: true,
trigger: "item"
},
legend: {
show:true,
right:15,
top:15,
width:50,
data: []
},
radar: {
center: ["50%", "53%"],
radius: "78%",
startAngle: 90,
splitNumber: 4,
shape: "circle",
splitArea: {
areaStyle: {
color: ["transparent"]
}
},
axisLabel: {
show: false,
fontSize: 12,
},
axisLine: {
show: true,
lineStyle: {
type: "dashed",
}
},
splitLine: {
show: true,
lineStyle: {
type: "dashed",
}
},
// shape: 'circle',
axisName: {
// formatter: '{a|{value}}{abg|}\n{hr|}\n{b|1234}',
// backgroundColor: '#eee',
// borderColor: '#aaa',
fontSize:14,
borderWidth: 1,
borderRadius: 0,
// rich: {
// a: { color: '#00b7ee', lineHeight: 25, padding: [0, 0, 0, 8], height: 25, backgroundColor: '#fff', borderRadius: 0 },
// hr: { borderColor: '#aaa', width: '100%', borderWidth: 0.1, align: 'left', height: 1 },
// b: { color: '#333', lineHeight: 25, padding: [0, 0, 0, 8], height: 25, backgroundColor: '#fff', width: '100%', align: 'left', borderRadius: 0 },
// per: { color: '#eee', backgroundColor: '#ffffff', borderWidth: 0.5, borderRadius: 0, borderColor: '#fff', }
// }
},
indicator: []
},
series: []
}
processData();
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
This diff is collapsed.
This diff is collapsed.
<script setup>
const state=reactive({
chartData:{
legend:['埋深'],
colors:[$c.bll5,],
data:[235, 210, 187, 212, 278, 220, 320, 302, 301, 334],
},
chartOption:{ }
})
const props=defineProps({
barColor:{
type:String,
default:""
},
})
const processData=()=>{
const {barColor}=props
let {colors,xAxis,data}=state.chartData,
processedData=[],
color=barColor?barColor:colors[0]
processedData.push({
type: "line",
symbolSize: 0,
label: { show: false, },
itemStyle:{
color: $c.fade(color,.1),
borderRadius: 3,
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: $c.fade(color,.9)
}, {
offset: 0.8,
color: $c.fade(color,.5)
}], false),
// shadowcolor: $c.fade(color,.3),
// shadowBlur: 10
},
smooth: true,
data: data
})
state.chartOption.series=processedData;
state.chartOption.xAxis.data=xAxis;
}
const processOption=()=>{
state.chartOption={
update:false,
// title:{ text:"barA", left:200, top:0, textStyle:{ color:$c.gyl3, fontSize:16, fontWeight:"normal" }, },
tooltip: {
trigger: 'axis',
axisPointer: { // 坐标轴指示器,坐标轴触发有效
type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
}
},
grid: {
left: 0,
right: 0,
bottom: 0,
top: 0,
},
yAxis:{
type: 'value',
axisLine: {show:false},
splitLine: {show:false},
axisLabel: {show:false}
},
xAxis: {
type: 'category',
boundaryGap: false,
data: [],
axisLine: {show:false},
splitLine: {show:false},
axisLabel: {show:false,}
},
series: []
}
processData();
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<template>
<!--本组件后续会封装成标注组件,通过参数来配置不同的风格和外观-->
<div class="map-counter-wrap">
<div class="counter-item" v-for="(item,index) in state.counterList">
<div class="content">
<DigitalTransform class="num" :value="item.num" :useGrouping="false" :interval="2000"></DigitalTransform>
</div>
<div class="name">{{item.name}} <span class="unit">({{item.unit}})</span></div>
<echartLine :barColor="item.barColor"></echartLine>
</div>
</div>
</template>
<script setup>
import echartLine from "./echart-line.vue"
const state=reactive({
counterList:[
{name:"软件年盈利",num:394,unit:"万元",barColor:$c.rel3},
{name:"硬件年盈利",num:42558,unit:"万元",barColor:$c.yel3},
{name:"服务年盈利",num:50262,unit:"万元"},
{name:"安全年盈利",num:50262,unit:"万元"},
]
})
</script>
<style lang="less">
.counter-item-re(){.bgc(fade(@red9,90%));
.name{.fc(@rer4);
.unit{.fc(@rer4);}
}
.content{
.num,
.num .plus{.fc(@rer4);}
}
}
.counter-item-ye(){.bgc(fade(@yed9,90%));
.name{.fc(@yer5);
.unit{.fc(@yer5);}
}
.content{
.num,
.num .plus{.fc(@yer5);}
}
}
.map-counter-wrap{.poa; left:50%; .fixc("x"); top:80px; z-index: 10;
.counter-item{ width: 190px; display:inline-block; .bgc(fade(@bll9,80%)); height: 60px; margin:0 20px 0 0; padding:10px 0 0 10px; position: relative;.bdr(5px);
.name{.fc(var(--font-normal)); font-size: 12px; .ff("cn1"); z-index: 1; .poa; left:5px; top:5px;
.unit{font-size: 12px;}
}
.content{.fc(var(--font-normal));.poa; right:5px; top:5px;
.num{font-size: 18px; .por; .ff(impact);.fc(var(--font-normal));
.plus{.poa; left:101%; top:-5px; font-size: 12px; .fc(var(--font-normal)); font-weight: normal; .ff("arial");}
}
}
.echartsInit-wrap{.poa!important; left:0; right:0; bottom:0; height: 25px!important;min-height: 25px!important;}
&:nth-child(1){.counter-item-re;}
&:nth-child(2){.counter-item-ye;}
&:nth-child(3){}
&:last-child{margin:0;}
}
}
</style>
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"icon":"path://m569.52,440.01c18.46,31.99-4.71,71.99-41.58,71.99H48.05c-36.94,0-60-40.05-41.58-71.99L246.42,23.99c18.47-32.01,64.72-31.95,83.15,0l239.94,416.03h0Zm-281.52-86.01c-25.4,0-46,20.6-46,46s20.6,46,46,46,46-20.6,46-46-20.6-46-46-46Zm-43.67-165.35l7.42,136c.35,6.36,5.61,11.35,11.98,11.35h48.55c6.37,0,11.64-4.98,11.98-11.35l7.42-136c.38-6.87-5.1-12.65-11.98-12.65h-63.38c-6.88,0-12.36,5.78-11.98,12.65h0Z"
}
\ No newline at end of file
This diff is collapsed.
<script setup>
import echartBarHorizScroll from "./portlet/echart-barHorizScroll.vue"
import echartPie from "./portlet/echart-pie.vue"
import echartGaugeTriple from "./portlet/echart-gaugeTriple.vue"
import echartMap from "./portlet/echart-map.vue"
import echartSunburst from "./portlet/echart-sunburst.vue"
import echartHill from "./portlet/echarts-hill-group/echart-hill.vue"
import echartBar from "./portlet/echart-bar.vue"
import echartBarHorizScroll from "./portlet/echart-barHorizScroll.vue";
import echartPie from "./portlet/echart-pie.vue";
import echartGaugeTriple from "./portlet/echart-gaugeTriple.vue";
import echartMap from "./portlet/echart-map.vue";
import echartSunburst from "./portlet/echart-sunburst.vue";
import echartHill from "./portlet/echarts-hill-group/echart-hill.vue";
import echartBar from "./portlet/echart-bar.vue";
import echartLine from "./portlet/echart-line.vue"
import counterGrid from "./portlet/counter-grid.vue"
import echartBarHoriz from "./portlet/echart-barHoriz.vue"
import echartLine from "./portlet/echart-line.vue";
import counterGrid from "./portlet/counter-grid.vue";
import echartBarHoriz from "./portlet/echart-barHoriz.vue";
import { fetchLocl } from "@/api/request";
import mainNav from "@/common/mainNav.vue"
import externalLinks from "@/common/externalLinks.vue"
console.log(fetchLocl);
const { proxy } = getCtx();
const comps={
const comps = {
echartMap,
echartGaugeTriple,
echartPie,
......@@ -28,119 +27,216 @@ const comps={
echartBarHoriz,
echartLine,
counterGrid,
}
const state=reactive({
systemTitleConfig:{
width:1000
};
const state = reactive({
systemTitleConfig: {
width: 1000,
},
panelTitleConfig:{
scale:1.1
panelTitleConfig: {
scale: 1.1,
},
tabActive:0,
configBLeft:{
tabActive: 0,
configBLeft: {
rotate: {
y:8,
y: 8,
},
transformOrigin:"right",
view3d:true,
showShadow:false,
hoverDelay:0
transformOrigin: "right",
view3d: true,
showShadow: false,
hoverDelay: 0,
},
configBCenter:{
configBCenter: {
rotate: {
x:30,
x: 30,
},
transformOrigin:"bottom",
view3d:true,
showShadow:false,
hoverDelay:0
transformOrigin: "bottom",
view3d: true,
showShadow: false,
hoverDelay: 0,
},
configBRight:{
rotate:{
y:-8,
configBRight: {
rotate: {
y: -8,
},
transformOrigin:"left",
view3d:true,
showShadow:false,
hoverDelay:0
transformOrigin: "left",
view3d: true,
showShadow: false,
hoverDelay: 0,
},
areas:[
{name:"left",portlets:[
{id:"r1",title:"销售情况",component:"echartBar",border:"blank"},
{id:"r2",title:"任务完成情况",component:"echartGaugeTriple",border:"blank"},
{id:"r3",title:"开支占比",component:"echartSunburst",border:"blank"},
]},
{name:"right",portlets:[
{id:"l2",title:"收支情况",component:"echartPie",border:"blank"},
{id:"l3",title:"业务收益情况",component:"echartBarHorizScroll",border:"blank"},
{id:"l1",title:"行业收入占比",component:"echartHill",border:"blank"},
]},
]
})
const {systemTitleConfig,panelTitleConfig,areas}=toRefs(state)
areas: [
{
name: "left",
portlets: [
{
id: "r1",
title: "销售情况",
component: "echartBar",
border: "blank",
},
{
id: "r2",
title: "任务完成情况",
component: "echartGaugeTriple",
border: "blank",
},
{
id: "r3",
title: "开支占比",
component: "echartSunburst",
border: "blank",
},
],
},
{
name: "right",
portlets: [
{
id: "l2",
title: "收支情况",
component: "echartPie",
border: "blank",
},
{
id: "l3",
title: "业务收益情况",
component: "echartBarHorizScroll",
border: "blank",
},
{
id: "l1",
title: "行业收入占比",
component: "echartHill",
border: "blank",
},
],
},
],
});
onMounted(()=>{
})
const { systemTitleConfig, panelTitleConfig, areas } = toRefs(state);
onMounted(() => {});
</script>
<template>
<div class="screen1080C">
<mainNav></mainNav>
<externalLinks></externalLinks>
<div :class="`area-box area-${area.name}`" v-for="area in areas" :key="area.id">
<div
:class="`area-box area-${area.name}`"
v-for="area in areas"
:key="area.id"
>
<div class="portlet-wrapper" v-for="item in area.portlets" :key="item.id">
<component v-if="item.border" :is='item.border'>
<panelTitleB1 v-if="!item.hideTitle" :config="panelTitleConfig">{{item.title}}</panelTitleB1>
<component :is='comps[item.component]' ></component>
<i>{{item.component}}</i>
<component v-if="item.border" :is="item.border">
<panelTitleB1 v-if="!item.hideTitle" :config="panelTitleConfig">{{
item.title
}}</panelTitleB1>
<component :is="comps[item.component]"></component>
<i>{{ item.component }}</i>
</component>
<template v-else>
<component :is='item.component'></component>
<i>{{item.component}}</i>
<component :is="item.component"></component>
<i>{{ item.component }}</i>
</template>
</div>
</div>
<systemTitleA3 :config="systemTitleConfig">TechUI数据可视化成型工具</systemTitleA3>
<systemTitleA3 :config="systemTitleConfig"
>教学资源库运行监测云图</systemTitleA3
>
<echartMap></echartMap>
</div>
</template>
<style lang="less">
.screen1080C{ z-index: 1; padding:60px 30px 30px 30px; height: 100%;
.i(){.poa; bottom:0; right:10px; font-size: 12px; opacity: .1; .fc(@wh); z-index: 10;}
display: grid; grid-template-columns: repeat(24,1fr); grid-template-rows:repeat(24,1fr); grid-gap: 30px;
.area-box{.bdr(5px); pointer-events: visible; position: relative; z-index: 10; padding:15px; .bdFilter(5px,120%); .bdr(10px);
&:before{ content:" "; .poa; .fullbox; .bdFilter(10px,300%); .bdr(10px); opacity: .8; .bgc(fade(@bll8,30%)); .bd(fade(@bll8,80%));}//
.screen1080C {
z-index: 1;
padding: 60px 30px 30px 30px;
height: 100%;
.i() {
.poa;
bottom: 0;
right: 10px;
font-size: 12px;
opacity: 0.1;
.fc(@wh);
z-index: 10;
}
display: grid;
grid-template-columns: repeat(24, 1fr);
grid-template-rows: repeat(24, 1fr);
grid-gap: 30px;
.area-box {
.bdr(5px);
pointer-events: visible;
position: relative;
z-index: 10;
padding: 15px;
.bdFilter(5px,120%);
.bdr(10px);
&:before {
content: " ";
.poa;
.fullbox;
.bdFilter(10px,300%);
.bdr(10px);
opacity: 0.8;
.bgc(fade(@bll8,30%));
.bd(fade(@bll8,80%));
} //
//<row-start> / <column-start> / <row-end> / <column-end>;
.blank,
.portlet-wrapper{.por;
>i{.i;}
.portlet-wrapper {
.por;
> i {
.i;
}
}
.border-content{>i{.i;}}
&.area-left{ grid-area: 1 / 1 / 25 / 7;
.portlet-wrapper{
&:nth-child(3){grid-area:3 / 1 /5/ 2}
.border-content {
> i {
.i;
}
}
&.area-right{ grid-area: 1 / 19 / 25 / 25; }
&.area-center{ grid-area: 19 / 7 / 25 / 19; }
&.area-right{display: grid; grid-template-columns: repeat(1,1fr); grid-template-rows:repeat(3,1fr); grid-gap: 20px;}
&.area-left{display: grid; grid-template-columns: repeat(1,1fr); grid-template-rows:repeat(4,1fr); grid-gap: 20px;}
&.area-center{display: grid; grid-template-columns: repeat(2,1fr); grid-template-rows:repeat(1,1fr); grid-gap: 20px;
.portlet-wrapper{ margin-top:-8px;}
&.area-left {
grid-area: 1 / 1 / 25 / 7;
.portlet-wrapper {
&:nth-child(3) {
grid-area: 3 / 1 /5/ 2;
}
}
}
&.area-right {
grid-area: 1 / 19 / 25 / 25;
}
&.area-center {
grid-area: 19 / 7 / 25 / 19;
}
&.area-right {
display: grid;
grid-template-columns: repeat(1, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-gap: 20px;
}
&.area-left {
display: grid;
grid-template-columns: repeat(1, 1fr);
grid-template-rows: repeat(4, 1fr);
grid-gap: 20px;
}
&.area-center {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(1, 1fr);
grid-gap: 20px;
.portlet-wrapper {
margin-top: -8px;
}
}
}
.panelTitleB1 {
left: 0;
top: 0;
}
.panelTitleB1{left:0; top:0;}
// .systemTitle-01{left:40px; transform: none;}
}
</style>
\ No newline at end of file
</style>
<script setup>
import layout from "./layout.vue"
const { proxy } = getCtx();
const store=useStore()
const state=reactive({
APConfig:{
height:930,
backgroundFillAll:true,
backgroundName:"A2",
chartCount:5,
backgroundConfig:{
vectorBGA:$c.wh,
vectorBGB:$c.wh,
vectorBGC:$c.wh,
vectorBGX:$c.bk.replace("#","%23"),
vectorBGXOpa:0.03,
}
}
})
</script>
<template>
<adaptivePanel :config="state.APConfig"><layout></layout></adaptivePanel>
</template>
<style lang="less">
</style>
\ No newline at end of file
<script setup>
import echartBarHoriz from "./portlet/echart-barHoriz.vue"
import echartLine from "./portlet/echart-line.vue"
import echartBarHorizScroll from "./portlet/echart-barHorizScroll.vue"
import echartGaugeTriple from "./portlet/echart-gaugeTriple.vue"
import echartSunburst from "./portlet/echart-sunburst.vue"
import counterGrid from "./portlet/counter-grid.vue"
import echartMap from "./portlet/echart-map.vue"
import mainNav from "@/common/mainNav.vue"
import externalLinks from "@/common/externalLinks.vue"
const comps={
echartBarHoriz,
echartLine,
echartBarHorizScroll,
echartGaugeTriple,
echartSunburst,
echartMap,
counterGrid,
}
const state=reactive({
systemTitleConfig:{
width:1000,
decoration:false,
backgroundColor:$c.cbA01,
decorationColor:[$c.cbA02,$c.bll5],
fontColor:[$c.bll7,$c.bll5]
},
panelTitleConfig:{
width:160,
color:$c.bk,
},
dialogConfig:{
show:false,
width:'60%',
height:'60%',
title:"对话框标题",
titleWidth:350,
},
// panelTitleConfig:{
// width:180,
// theme:true
// },
areas:[
{name:"left",portlets:[
{id:"l2",title:"收支情况",component:"echartBarHoriz",border:"aYinTechBorderA1",hideTitle:true},
{id:"l3",title:"业务收益情况",component:"echartLine",border:"aYinTechBorderA1",hideTitle:true},
{id:"l1",title:"销售任务",component:"echartBarHorizScroll",border:"aYinTechBorderA1",hideTitle:true},
]},
{name:"right",portlets:[
{id:"r1",title:"销售情况",component:"counterGrid",border:"blank",hideTitle:true},
{id:"r2",title:"任务完成情况",component:"echartGaugeTriple",border:"aYinTechBorderA1",hideTitle:true},
{id:"r3",title:"业务利润占比",component:"echartSunburst",border:"aYinTechBorderA1"},
]},
]
})
const {systemTitleConfig,panelTitleConfig,dialogConfig,areas}=toRefs(state)
const getConfig=(item)=>{
const {id}=item
if(id=='r3'){
return {
directionAlt: true,
rotate: "z",
opacity: 0.8,
backgroundColor:$c.gyl1,
decorationColor:[$c.cyl3,$c.bll4],
borderColor:$c.gyl5,
titleColor:$c.bk
}
}else if(id.includes("l")){
return {
title:item.title,
titleWidth:120,
decoration:false,
decorationAlt: true,
rotate: "y",
opacity: 0.8,
backgroundColor:$c.gyl1,
decorationColor:[$c.cyl3,$c.bll4],
borderColor:$c.gyl5,
titleColor:$c.bk,
fontWeight:"bold"
}
}else{
return {
title:item.title,
titleWidth:120,
decoration:false,
opacity:.8,
backgroundColor:$c.gyl1,
decorationColor:[$c.cyl3,$c.bll4],
borderColor:$c.gyl5,
titleColor:$c.bk,
fontWeight:"bold"
}
}
}
onMounted(()=>{
})
</script>
<template>
<div class="screen1080D">
<mainNav></mainNav>
<externalLinks></externalLinks>
<div :class="`area-box area-${area.name}`" v-for="area in areas" :key="area.id">
<div class="portlet-wrapper" v-for="item in area.portlets" :key="item.id">
<component v-if="item.border" :is='item.border' :config="getConfig(item)">
<panelTitleA1 v-if="!item.hideTitle" :config="panelTitleConfig" >{{item.title}}</panelTitleA1>
<component :is='comps[item.component]' ></component>
</component>
<template v-else>
<component :is='item.component'></component>
<i>{{item.component}}</i>
</template>
</div>
</div>
<systemTitleA2 :config="systemTitleConfig">TechUI数据可视化成型工具</systemTitleA2>
<echartMap></echartMap>
</div>
</template>
<style lang="less">
.screen1080D{ z-index: 1;padding:60px 30px 30px 30px; height: 100%; //url(../common/images/bg.png)
.techButtonA2 {z-index: 10; .poa; bottom:20px; left:50%; .fixc("x");}
.i(){.poa; bottom:0; right:10px; font-size: 12px; opacity: .1; .fc(@wh); z-index: 10;}
display: grid; grid-template-columns: repeat(24,1fr); grid-template-rows:repeat(24,1fr); grid-gap: 30px;
.area-box{.bdr(5px); pointer-events: visible; position: relative; z-index: 10;
.board-3d-wrap{ .poa; .fullbox;
}
//<row-start> / <column-start> / <row-end> / <column-end>;
.blank,
.portlet-wrapper{.por;
>i{.i;}
}
.border-content{>i{.i;}}
&.area-left{ grid-area: 1 / 1 / 25 / 7; }
&.area-right{ grid-area: 1 / 19 / 25 / 25;
.portlet-wrapper{
&:nth-child(3){grid-area:3 / 1 /5/ 2}
}
}
&.area-left{ display: grid; grid-template-columns: repeat(1,1fr); grid-template-rows:repeat(3,1fr); grid-gap: 20px;}
&.area-right{ display: grid; grid-template-columns: repeat(1,1fr); grid-template-rows:repeat(4,1fr); grid-gap: 20px;}
}
.content-tabs{.poa; top:-40px; left:80px; right:80px; text-align: center; height: 40px;
&:before{content:" "; .bdb(var(--button-bd_hov));left:0; right:0; bottom:10px;.poa; z-index: 1;}
.tabs-item{display:inline-block; padding:0 10px; .ff("cn1"); .fc(var(--font-normal)); height: 30px;line-height: 30px; cursor: pointer; .ani; z-index: 2; .por;
&:before{content:" "; .bgc(var(--button-bd_hov)); .poa; .fullbox; opacity: 0;}
&:hover{&:before{opacity: .3;}}
&.active{ .bdb(var(--font-strong)); .fc(var(--font-strong));}
}
}
.nav-wrap{
.item{.fc(@gym5);
&:before{ .bgc(@cbl3);}
&:hover{.fc(@cbl5);}
&.active{.fc(@bk); }
}
}
}
</style>
\ No newline at end of file
<script setup>
const state=reactive({
arry:[
{title:"软件销售额",icon:"i carbon:ibm-z-cloud-mod-stack",unit:"万元",total:"1874"},
{title:"硬件销售额",icon:"i carbon:chip",unit:"万元",total:"3276"},
{title:"技术服务",icon:"i carbon:user-speaker",unit:"万元",total:"315"},
{title:"安全服务",icon:"i carbon:rule",unit:"万元",total:"769"},
],
})
const borderConfig=(index)=>{
let rotate
if(index==0){
rotate="x";
}else if(index==1){
rotate="all";
}else if(index==2){
rotate=null;
}else if(index==3){
rotate="y";
}
return {
dur: 3,
opacity: 0.7,
backgroundColor:$c.gyl1,
decorationColor:[$c.cyl3,$c.bll3],
borderColor:$c.gyl5,
titleColor:$c.bk,
rotate
}
}
</script>
<template>
<div class="screenD-counterGrid">
<aYinTechBorderB3 :config="borderConfig(index)" v-for="(item,index) in state.arry" :key="index">
<div class="inner-content">
<div class="block-title">{{item.title}} <span v-if="item.unit">({{item.unit}})</span></div>
<div class="total">
<i :class="[item.icon,'icon']"></i>
<!-- <DigitalTransform class="numbers" :value="123210" :interval="$vuex.state.globalConfig.ani?3000:0"></DigitalTransform> -->
<DigitalTransform class="numbers" :value="item.total" :useGrouping="true" :interval="3000"></DigitalTransform>
<!-- <span class="unit">{{item.unit}}</span> -->
</div>
</div>
</aYinTechBorderB3>
<!-- <div class="block" > <div class="bdTechBottom"></div> </div> -->
</div>
</template>
<style lang="less">
.screenD-counterGrid{display: grid; grid-template-columns: repeat(2,1fr); height: 100%; grid-template-rows: repeat(2,1fr); grid-gap: 12px; position: relative;
.aYinTechBorderB3{ padding:0; position: relative;
//&:nth-child(1){ grid-area: 1 / 1 / 2 / 3; }
.inner-content{
.block-title{position: absolute;.ff("cn1"); left:0; right:0; text-align: center; top:10px;.fc(@bk); font-size: 14px; }
.total{margin: 0; text-align: center; line-height: 30px; .poa; left:0; right:0; top:60%; .fixc("y");
i{display:inline-block;font-size:32px; vertical-align: text-top; margin-right: 10px;.fc(@bk);}
.numbers{display:inline-block; text-align: center; font-size: 32px; .ff("en0"); position: relative; vertical-align: text-top; .fc(@bk);
.badge{position: absolute; left:100%; top:-10px; font-size: 14px; width: 30px; height:30px; padding:0; line-height: 1; }
}
.unit{font-size: 14px; margin:0 0 0 10px;.fc(@gyd5);}
}
}
}
}
</style>
<script setup>
const state=reactive({
lineColor:$c.bll7,
fontColor:$c.gyl3,
chartData:{
legend:['本地视频会议', '异地视频会议'],
xAxis:['十二月', '一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月'],
colors:[$c.bll4,$c.aql4,$c.ipl3,$c.cbl3,],
data:[
[235, 210, 187, 212, 278, 220, 320, 302, 301, 334, 390, 330],
[68, 121, 34, 56, 23, 120, 132, 101, 134, 90, 230, 210]
],
},
chartOption:{}
})
const {lineColor,fontColor}=toRefs(state)
const processData=()=>{
let legend=state.chartData.legend,
colors=state.chartData.colors,
xAxis=state.chartData.xAxis,
data=state.chartData.data,
processedData=[]
legend.forEach((item,i)=>{
processedData.push({
name: legend[i],
type: 'bar',
barWidth:15,
label: {
show: false,
position: 'insideRight'
},
itemStyle:{
color: colors[i],
borderRadius: 5
},
data: data[i]
})
})
state.chartOption.series=processedData;
state.chartOption.xAxis.data=xAxis;
}
const processOption=()=>{
state.chartOption={
update:false,
// title:{ text:"barA", left:200, top:0, textStyle:{ color:$c.gyl3, fontSize:16, fontWeight:"normal" }, },
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
//show:false,
data: [],
top:"5",
right:60,
label: { color:fontColor }
},
toolbox: {
feature: {
magicType: { type: ['line', 'bar'] }
},
},
grid: {
left: '5%',
right: '5%',
bottom: '5%',
top: "15%",
containLabel: true
},
yAxis: {
type: 'value',
axisLine: {
lineStyle: { color:lineColor },
},
splitLine: {
lineStyle: { color:lineColor },
},
axisLabel: { color:fontColor, align: 'right' }
},
xAxis: {
type: 'category',
data: [],
axisLine: {
lineStyle: { color:lineColor },
},
splitLine: {
lineStyle: { color:lineColor },
},
axisLabel: { color:fontColor, align: 'center' }
},
series: []
}
processData()
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<script setup>
const state=reactive({
lineSPColor:$c.gyl3,
lineAXColor:$c.gyl3,
fontColor:$c.bk,
chartData:{
legend:['收入', '支出'],
yAxis:['业务1', '业务2', '业务3', '业务4', '业务5', '业务6'],
colors:[$c.cbl4,$c.bll5,],
data:[
[320, 302, 341, 374, 390, 450],
[-120, -132, -101, -134, -190, -230],
],
},
chartOption:{}
})
const {lineSPColor,lineAXColor,fontColor}=toRefs(state)
const processData=()=>{
let {legend,colors,yAxis,data}=state.chartData,
processedData=[];
legend.forEach((item,i)=>{
processedData.push({
name: legend[i],
type: 'bar',
barWidth:10,
stack: 'Total',
label: {
color:$c.wh,
show: true
},
emphasis: {
focus: 'series'
},
itemStyle:{
color: $c.fade(colors[i],.9),
borderRadius: 3
},
data: data[i]
})
})
state.chartOption.legend.data=legend;
state.chartOption.series=processedData;
state.chartOption.yAxis.data=yAxis;
}
const processOption=()=>{
state.chartOption={
update:false,
// title:{ text:"barA", left:200, top:0, textStyle:{ color:$c.gyl3, fontSize:16, fontWeight:"normal" }, },
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
legend: {
right: '10',
top: '10',
textStyle: {
color: fontColor,
}
},
grid: {
left: '5%',
right: '10%',
bottom: '8%',
top: "15%",
containLabel: true
},
xAxis: {
type: 'value',
axisLine: {
lineStyle: {
color: lineAXColor,
},
},
splitLine: {
lineStyle: {
color: lineSPColor
},
},
axisLabel: {
color: fontColor,
align: 'center',
interval:0,
}
},
yAxis: {
type: 'category',
axisTick: {
show: false
},
data: [],
axisLine: {
show:true,
lineStyle: {
color: lineSPColor,
},
},
splitLine: {
show:false,
lineStyle: {
color: lineSPColor
},
},
axisLabel: {
formatter: '{value}',
color: fontColor,
align: 'right'
}
}
}
processData();
}
onMounted(() => {
processOption();
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
<script setup>
const base64Img="image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADoAAAA6CAMAAADWZboaAAAAZlBMVEUAAABe3uVe3+Vf3uVf3+Zf3uVg3+Zg3+Zf3+Vi4OZh4OZg3+Z86/Bh3+Zi4Odj4Odi4OZ86/B76/B86/Bj4ed56+9x5+xn4umB7/N87PB36e+A7/N+7fF/7vJ/7vJ+7fGA7/OB7/PReX+lAAAAIXRSTlMABQkVDREmIhk3MR10LEFFPHh7cUprXE35h2XnqMLAp+mHAG9cAAAB5ElEQVRIx83WjU7CMBQFYIoiKMqU/XUboHv/l/Tce7t2XamDNSacETEmX86tlK2rx4py150o+MstMBLwWRfHKo6JCVxLnvmFGBjFQ58oF1//sUZhGy/ClSTWObgnL4O+bkeN4nY2okfNMbkRt9/vtxz8InoTsWplJSCzFxPmO8+GpSIByX3YQAuGDWtRKhKjCnxDXhF6Z4yxnZ20Wgko7BMRDmxtSGVaI4kdTIgb+zTYoJQlIMlDlmUFgrcDWWC201qSayqlTkiCddWWeV62VU0YlnpRi9VOKaSUsiyq/N0krwq2Ugt7lVpZl5BfHNiytjagMi+XYp0kCR45hMlivVQrE/uU5pXSrCB5bM6d1t2lOZItMqmliT3q5uVxqxzyW/ccfYLNKx7ZTeykMvNyac2yt2Fbc61MHLSC0rwoxbiNdlQ3GBm1NLHQsHUrtEXppR/ljNpW6DbSCoqlFiVoN6YdaFlgsSFVPs1BdT8OaB5QyQzVcaqWDows/zepxR8ObLglTrdtCRVuRNj4Rrxh+//0ke2f8KVL+Kon3GCSbmsJN9OUW3j6g0Ns+LgCij2u0h+Sghc8mlMPBMgdx5DFh59VmOVHrvmDnoNxCz3J7MFWsMuaLyR089xz/xhlfijvwutR8gv3zk6BLUUeCgAAAABJRU5ErkJggg=="
const state=reactive({
lineColor:$c.gyl3,
fontColor:$c.bk,
chartData:{
yAxis:['任务A', '任务B', '任务C', '任务较长名称D', '任务E', '任务F', '任务G', '任务H', '任务I'],
color:[$c.aql4,$c.orl5,$c.rel5],
data:[69, 96, 35,26, 96, 32 ,52 ,22 ,72]
},
chartOption:{}
})
const {lineColor,fontColor}=toRefs(state)
const fillArr=computed(()=>{
return (new Array(state.chartData.data.length)).fill(100);
})
const getSymbolData=(data)=>{
let arr = [];
for (var i = 0; i < data.length; i++) {
arr.push({
value: data[i],
symbolPosition: 'end'
})
}
return arr;
}
const processData=()=>{
let legend=state.chartData.legend,
colors=state.chartData.colors,
yAxis=state.chartData.yAxis,
data=state.chartData.data,
processedData=[];
state.chartOption.yAxis.data=state.chartData.yAxis;
state.chartOption.series[0].data=state.chartData.data;
state.chartOption.series[1].data=fillArr;
state.chartOption.series[2].data=getSymbolData(state.chartData.data);
dataScroll();
}
const processOption=()=>{
state.chartOption={
update:false,
title: {
show:false,
// text: '实时流速图2',
textStyle:{
color:$c.cbl5,
fontSize:16,
fontWeight:"normal"
},
},
grid: {
top: '15%',
left: '18%',
right: '12%',
bottom: '5%'
},
tooltip: {show: false},
xAxis: {
type: 'value',
min: 0,
max: 100,
axisLine: {show: false},
splitLine: {show: false},
axisLabel: {show: false},
axisTick: {show: false}
},
dataZoom: {
yAxisIndex: 0,
show: false,
type: "slider",
startValue: 0,
endValue: 5,
},
yAxis: {
//show: false,
type: 'category',
inverse: true,
splitLine: {show: false,},
axisLine: {show: false},
axisLabel: {
show: true,
interval: 0,
margin: 10,
color:fontColor,
fontSize: 12,
width:50,
lineHeight:14,
overflow:"breakAll",
fontWeight: 'normal',
},
axisTick: {show: false},
data:[]
},
series: [
{
type: 'bar',
barWidth: '40%',
animationDuration:2000,
itemStyle: {
borderWidth:0,
borderRadius:10,
color: {
type: 'linear', x: 0, y: 0, x2: 1, y2: 0,
colorStops: [{ offset: 0, color: $c.cyl4, }, { offset: 1, color: $c.cyl6, }]
}
},
label: { show: false, },
data: [],
z: 0
},
{
type: 'bar',
barWidth: '40%',
barGap: '-100%',
animation: false,
itemStyle: {
borderWidth: 0,
borderRadius:5,
color: 'rgba(0,202,255,0.2)'
},
label: {
color:fontColor,
show: true,
position: ['101%', '20%'],
fontSize: 14,
fontWeight: 'normal',
formatter: (params)=>{
return ' ' + (state.chartData.data[params.dataIndex] ) + '%';
}
},
data: [],
z: 0
},
{
type: 'pictorialBar',
animation: true,
// animationThreshold: 3000 ,
animationDuration: 3000 ,
// animationDurationUpdate:500,
symbol: base64Img,
symbolSize: [50, 50],
symbolOffset: [20, 0],
z: 12,
itemStyle: {
color: '#fff'
},
data: []
},
]
}
processData();
}
const { proxy } = getCtx();
const dataScroll=()=>{
proxy.$timer("dataScrollBarHorizD",()=>{
let {data}=state.chartData
let {dataZoom}=state.chartOption
if (dataZoom.endValue == data.length ) {
dataZoom.endValue = 5;
dataZoom.startValue = 0;
}else{
dataZoom.endValue ++;
dataZoom.startValue ++;
}
state.chartOption.update=true
dataScroll()
},5000)
}
onMounted(() => {
processOption();
})
onBeforeMount(() => {
proxy.$timer("dataScrollBarHorizD")
})
</script>
<template>
<echartsInit :chartOption="state.chartOption"></echartsInit>
</template>
<style lang="less">
</style>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<template>
<div class="map-counter-alt-wrap">
<div class="counter-item" v-for="(item,index) in state.counterList">
<i :class="'icon '+item.icon"></i>
<div class="name">{{item.name}} <span class="unit">({{item.unit}})</span></div>
<div class="content">
<span class="num">
<DigitalTransform class="num" :value="item.num" :useGrouping="true" :interval="2000"></DigitalTransform>
<span class="plus" v-if="item.plus">+{{item.plus}}</span>
</span>
</div>
</div>
</div>
</template>
<script setup>
const state=reactive({
counterList:[
{name:"软件销售额",icon:"i carbon:ibm-z-cloud-mod-stack",num:13694,unit:"元",plus:218},
{name:"硬件销售额",icon:"i carbon:chip",num:14558,unit:"元"},
{name:"技术服务",icon:"i carbon:user-speaker",num:3962,unit:"元",plus:462},
{name:"安全服务",icon:"i carbon:rule",num:5302,unit:"元",plus:775},
]
})
</script>
<style lang="less">
.mapD-wrap{
.map-counter-alt-wrap{.poa; left:50%; .fixc("x"); bottom:70px; z-index: 10;
.counter-item{.bdl(@cbl3,3px); .bdFilter; .bgc(fade(@cbd1,70%)); width: 210px; display:inline-block; height: 80px; margin:0 20px 0 0; padding:10px 0 0 60px; position: relative;
.icon{.fc(@bll5); font-size: 32px;z-index: 1; .poa;left:5px; top:50%; .fixc("y"); width: 50px; height: 58px; line-height: 60px; text-align: center;}
.name{.fc(@bll5); font-size: 16px; .ff("cn1"); z-index: 1; .por;
.unit{font-size: 12px;}
}
.content{.fc(@bll5); margin:10px 0;
.num{font-size: 24px; .por; font-weight: bold;.ff("en0"); .fc(@bll5);
.dt-scroll-digital{text-align: center;}
.plus{.poa; left:101%; top:-5px; font-size: 12px; .fc(@bll5); font-weight: normal; .ff("arial");}
}
}
// &:nth-child(1){.counter-item-re;}
// &:nth-child(2){.counter-item-ye;}
// &:nth-child(3){}
&:last-child{margin:0;}
}
}
}
</style>
{
"icon":"path://m569.52,440.01c18.46,31.99-4.71,71.99-41.58,71.99H48.05c-36.94,0-60-40.05-41.58-71.99L246.42,23.99c18.47-32.01,64.72-31.95,83.15,0l239.94,416.03h0Zm-281.52-86.01c-25.4,0-46,20.6-46,46s20.6,46,46,46,46-20.6,46-46-20.6-46-46-46Zm-43.67-165.35l7.42,136c.35,6.36,5.61,11.35,11.98,11.35h48.55c6.37,0,11.64-4.98,11.98-11.35l7.42-136c.38-6.87-5.1-12.65-11.98-12.65h-63.38c-6.88,0-12.36,5.78-11.98,12.65h0Z"
}
\ No newline at end of file
<script setup>
import layout from "./layout.vue"
const state=reactive({
APConfig:{
// backgroundFillAll:true,
// backgroundName:"A1",
height:930,
userSelect:true,
chartCount:9
}
})
</script>
<template>
<adaptivePanel :config="state.APConfig"><layout></layout></adaptivePanel>
</template>
<style lang="less">
</style>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
{
"icon":"path://m569.52,440.01c18.46,31.99-4.71,71.99-41.58,71.99H48.05c-36.94,0-60-40.05-41.58-71.99L246.42,23.99c18.47-32.01,64.72-31.95,83.15,0l239.94,416.03h0Zm-281.52-86.01c-25.4,0-46,20.6-46,46s20.6,46,46,46,46-20.6,46-46-20.6-46-46-46Zm-43.67-165.35l7.42,136c.35,6.36,5.61,11.35,11.98,11.35h48.55c6.37,0,11.64-4.98,11.98-11.35l7.42-136c.38-6.87-5.1-12.65-11.98-12.65h-63.38c-6.88,0-12.36,5.78-11.98,12.65h0Z"
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment