首頁>技術>

前面寫了一篇vue3.0的基本上手的文章,今天來個偏向實戰的,寫兩個大屏demo,沒有設計稿參考了一個別人寫的HTML版的,一些邊框裝飾我用了DataV這個庫,這兒也放上這兩個的地址。

1rem = 100px

佈局方面同過vw,vh flex 彈性盒子進行佈局

封裝元件

main.js 中註冊echarts 配置到全域性呼叫,vue2.x中就是掛載到原型鏈上,我把全域性元件自動註冊了,統一把components下的元件都作為全域性元件使用,使用require.context 遍歷註冊

app.config.globalProperties.echarts = echartsconst vueFiles = require.context("@/components", true, /component\\.vue$/)vueFiles.keys().forEach((key) => { const component = vueFiles(key).default app.component(component.name, component)})const jsFiles = require.context("@/components", true, /component\\.js$/)jsFiles.keys().forEach((key) => { const component = jsFiles(key).default app.component(component.name, component)})

components 新增tao-charts元件

<template> <div ref="myChart" class="echarts"></div></template><script>import { onMounted, getCurrentInstance } from "vue"export default { name: "tao-charts", props: { data: { type: Object, default: null } }, setup(props) { const { ctx } = getCurrentInstance() const drawLine = (dom, option) => { const myChart = ctx.echarts.init(dom) myChart.setOption(option) // 當瀏覽器視窗發生變化的時候呼叫div的resize方法 window.onresize = () => { myChart.resize() } } const setChart = (option) => { const dom = ctx.$refs.myChart drawLine(dom, option) } onMounted(() => { setChart(props.data) }) }}</script><style lang="scss" scoped>.echarts { height: 100%; width: 100%; position: relative;}</style>
呼叫元件圖表配置項
const lineChart = (echarts, datasource) => { const options = { grid: { left: "2%", top: "30%", bottom: "5%", right: "8%", containLabel: true }, tooltip: {}, xAxis: { type: "category", axisTick: { alignWithLabel: true }, nameTextStyle: { color: "#82b0ec" }, axisLine: { show: false, lineStyle: { color: "#82b0ec" } }, axisLabel: { textStyle: { color: "#fff" }, margin: 30 } }, yAxis: { show: false, gridIndex: 0, axisLine: { lineStyle: { color: "#4ADEFE" } }, splitLine: { lineStyle: { color: "#4ADEFE" } } }, dataset: { source: datasource }, series: [{ name: "", type: "pictorialBar", symbolSize: [20, 10], symbolOffset: [0, -6], symbolPosition: "end", z: 12, // "barWidth": "0", label: { normal: { show: true, position: "top", // "formatter": "{c}%" fontSize: 18, fontWeight: "bold", color: "#34DCFF" } }, color: "#2DB1EF" }, { type: "pictorialBar", symbolSize: [20, 10], symbolOffset: [0, 7], // "barWidth": "20", z: 12, color: "#2DB1EF" }, { type: "pictorialBar", symbolSize: [30, 15], symbolOffset: [0, 12], z: 10, itemStyle: { normal: { color: "transparent", borderColor: "#2EA9E5", borderType: "solid", borderWidth: 1 } } }, { type: "pictorialBar", symbolSize: [40, 20], symbolOffset: [0, 18], z: 10, itemStyle: { normal: { color: "transparent", borderColor: "#19465D", borderType: "solid", borderWidth: 2 } } }, { type: "bar", barWidth: "20", barGap: "10%", // Make series be overlap barCateGoryGap: "10%", itemStyle: { normal: { color: new echarts.graphic.LinearGradient(0, 0, 0, 0.7, [{ offset: 0, color: "#38B2E6" }, { offset: 1, color: "#0B3147" } ]), opacity: 0.8 } } } ] } return options}const mapChart = (echarts, datas) => { echarts.registerMap("china", datas) const data = [ { name: "北京", transAmt: 199, serviceRate: 99 }, { name: "蘇州", transAmt: 42, serviceRate: 99 }, { name: "南京", transAmt: 102, serviceRate: 99 }, { name: "上海", transAmt: 81, serviceRate: 99 }, { name: "杭州", transAmt: 47, serviceRate: 99 }, { name: "天津", transAmt: 67, serviceRate: 99 }, { name: "成都", transAmt: 82, serviceRate: 99 }, { name: "寧波", transAmt: 123, serviceRate: 99 }, { name: "上海", transAmt: 24, serviceRate: 99 }, { name: "深圳", transAmt: 92, serviceRate: 99 } ] const option = { tooltip: { trigger: "item", formatter(params) { if (typeof params.value[2] === "undefined") { return `${params.name} : ${params.value}` } return `${params.name} : ${params.value[2]}` } }, legend: { orient: "vertical", y: "bottom", x: "right", data: ["pm2.5"], textStyle: { color: "#fff" } }, visualMap: { show: false, min: 0, max: 500, left: "left", top: "bottom", text: ["高", "低"], // 文字,預設為數值文字 calculable: true, seriesIndex: [1], inRange: {} }, geo: { map: "china", show: true, roam: true, label: { normal: { show: false }, emphasis: { show: false } }, itemStyle: { normal: { areaColor: "#3a7fd5", borderColor: "#0a53e9", // 線 shadowColor: "#092f8f", // 外發光 shadowBlur: 20 }, emphasis: { areaColor: "#0a2dae" // 懸浮區背景 } } }, series: [ { symbolSize: 5, label: { normal: { formatter: "{b}", position: "right", show: true }, emphasis: { show true } }, itemStyle: { normal: { color: "#fff" } }, name: "light", type: "scatter", coordinateSystem: "geo", data: [...data] }, { type: "map", map: "china", geoIndex: 0, aspectScale: 0.75, // 長寬比 showLegendSymbol: false, // 存在legend時顯示 label: { normal: { show: false }, emphasis: { show: false, textStyle: {  color: "#fff" } } }, roam: true, itemStyle: { normal: { areaColor: "#031525", borderColor: "#FFFFFF" }, emphasis: { areaColor: "#2B91B7" } }, animation: false, data }, { name: "Top 5", type: "scatter", coordinateSystem: "geo", symbol: "pin", symbolSize: [50, 50], label: { normal: { show: true, textStyle: {  color: "#fff",  fontSize: 9 }, formatter(value) {  return value.data.value[2] } } }, itemStyle: { normal: { color: "#D8BC37" // 標誌顏色 } }, data: [...data], showEffectOn: "render", rippleEffect: { brushType: "stroke" }, hoverAnimation: true, zlevel: 1 } ] } return option}const pieChart = (echarts, datasource) => { const option = { color: ["#cd4692", "#9658c3", "#6c6be2", "#01aebf", "#18b794"], tooltip: { trigger: "item", axisPointer: { type: "shadow" }, formatter: "{a} <br/>{c}({d}%)", textStyle: { fontSize: 16 } }, dataset: { source: datasource }, series: [{ type: "pie", clockwise: false, startAngle: 90, radius: "45%", center: ["50%", "50%"], roseType: "radius", // area itemStyle: { normal: { borderColor: "#273454", borderWidth: "3" } }, label: { show: true, position: "outside", formatter: "{a|{b}:{d}%}\\n{hr|}", rich: { hr: { backgroundColor: "t", borderRadius: 100, width: 0, height: 5, padding: [3, 3, 0, -16], shadowColor: "#1c1b3a", shadowBlur: 1, shadowOffsetX: "0", shadowOffsetY: "2" }, a: { padding: [-35, 15, -20, 5] } } }, labelLine: { normal: { length: 10, length2: 20, lineStyle: { width: 1 } } } }] } return option}const pieChartVie = () => { const scaleData = [{ name: "紅燈 14", value: 14, radius1: [58, 60], radius2: "25%" }, { name: "黃燈 32", value: 32, radius1: [80, 82], radius2: "30%" }, { name: "綠燈 288", value: 288, radius1: [102, 104], radius2: "35%" }, { name: "掛起 463", value: 463, radius1: [124, 126], radius2: "40%" } ] const placeHolderStyle = { normal: { label: { show: false }, labelLine: { show: false }, color: "rgba(0, 0, 0, 0)", borderColor: "rgba(0, 0, 0, 0)", borderWidth: 0 } } const seriesObj = [] const color = ["#FF647C", "#FFBE75", "#3EE2A5", "#6C77FD"] // eslint-disable-next-line no-plusplus for (let i = 0; i < scaleData.length; i++) { console.log(scaleData[i].name) seriesObj.push({ name: "", type: "pie", radius: scaleData[i].radius1, hoverAnimation: false, itemStyle: { normal: { label: { show: false, color: "#ddd" } } }, data: [{ value: scaleData[i].value, name: scaleData[i].name, itemStyle: { normal: { borderWidth: 5, borderColor: color[i] } } }, { value: 200, name: "", itemStyle: placeHolderStyle }] }, { name: "", type: "gauge", detail: false, splitNumber: 10, // 刻度數量 radius: scaleData[i].radius2, // 圖表尺寸 center: ["50%", "50%"], startAngle: 0, // 開始刻度的角度 endAngle: -356, // 結束刻度的角度 axisLine: { show: false, lineStyle: { width: 0, shadowBlur: 0 } }, axisTick: { show: true, lineStyle: { color: "rgba(220,220,220,0.5)", width: 5 }, length: 5, splitNumber: 5 }, splitLine: { show: false, length: 5, lineStyle: { color: "rgba(220,220,220,0.1)" } }, axisLabel: { show: false } }) } const option = { color, tooltip: { show: false }, legend: { orient: "vertical", x: "200", y: "center", itemGap: 35, data: ["掛起 463", "紅燈 14", "黃燈 32", "綠燈 288"], show: true, textStyle: { color: "#fff" } }, toolbox: { show: false }, series: seriesObj } return option}const hillChart = (echarts, datasource) => { const option = { tooltip: { trigger: "axis", axisPointer: { type: "shadow" } }, grid: { left: "12%", top: "25%", bottom: "12%", right: "8%" }, xAxis: { type: "category", axisTick: { show: false }, axisLine: { lineStyle: { color: "rgba(255, 129, 109, 0.1)", width: 1 // 這裡是為了突出顯示加上的 } }, axisLabel: { textStyle: { color: "#999", fontSize: 12 } } }, yAxis: [{ splitNumber: 2, axisTick: { show: false }, axisLine: { lineStyle: { color: "rgba(255, 129, 109, 0.1)", width: 1 // 這裡是為了突出顯示加上的 } }, axisLabel: { textStyle: { color: "#999" } }, splitArea: { areaStyle: { color: "rgba(255,255,255,.5)" } }, splitLine: { show: true, lineStyle: { color: "rgba(255, 129, 109, 0.1)", width: 0.5, type: "dashed" } } }], dataset: { source: datasource }, series: [{ type: "pictorialBar", barCategoryGap: "0%", symbol: "path://M0,10 L10,10 C5.5,10 5.5,5 5,0 C4.5,5 4.5,10 0,10 z", label: { show: true, position: "top", distance: 10, color: "#b73a35", fontWeight: "bolder", fontSize: 14 }, itemStyle: { normal: { color: { type: "linear", x: 0, y: 0, x2: 0, y2: 1, colorStops: [{  offset: 0,  color: "#5433f7" // 0% 處的顏色 }, {  offset: 1,  color: "#f24c44" // 100% 處的顏色 } ], global: false // 預設為 false } }, emphasis: { opacity: 1 } }, z: 10 }] } return option}const barChart = (echarts, datasource) => { const option = { color: ["#FADB71"], tooltip: { trigger: "axis", axisPointer: { // 座標軸指示器,座標軸觸發有效 type: "shadow" // 預設為直線,可選為:'line' | 'shadow' } }, grid: { left: "12%", top: "25%", bottom: "12%", right: "8%" }, xAxis: [ { type: "category", axisTick: { alignWithLabel: true }, axisLabel: { color: "#FADB71" // 刻度線標籤顏色 } } ], yAxis: [ { type: "value", axisLabel: { color: "#FADB71" // 刻度線標籤顏色 } } ], dataset: { source: datasource }, series: [ { type: "bar", barWidth: "60%" } ] } return option}export default { lineChart, mapChart, pieChart, pieChartVie, hillChart, barChart}
呼叫配置項,填充資料
<template> <div class="wrapper"> <section class="item span1"> <article class="item-span item-span1"> <dv-border-box-13> <div class="flex-center-align"> <h1 class="title">// 當前比對資料 // </h1> <span class="num">3,456,789</span> </div> </dv-border-box-13> </article> <article class="item-span item-span2"> <dv-border-box-11 title="違法犯罪人員分析"> <tao-charts :data="option.pieChart" /> </dv-border-box-11> </article> <article class="item-span item-span3"> <dv-border-box-11 title="人口出入記錄"> <tao-charts :data="option.lineChart" /> </dv-border-box-11> </article> </section> <section class="item span2"> <div class="header flex-center"> <img src="/img/jinghui.png" style="width:0.8rem;height:0.8rem"> <span>智慧社群內網比對平臺</span> </div> <div class="flex-center"> <p class="title">NO.1北京:2543289人</p> <p class="title">NO.1天津: 5690人</p> <p class="title">NO.1河北: 456人</p> </div> <p>犯罪人口來源分析</p> <dv-decoration-12 class="animate-rate" /> <tao-charts :data="option.mapChart" /> </section> <section class="item span3"> <article class="item-span item-span1"> <dv-border-box-11 title="違法犯罪人員年齡分佈"> <tao-charts :data="option.hillChart" /> </dv-border-box-11> </article> <article class="item-span item-span2"> <dv-border-box-11 title="違法犯罪人員地區分佈"> <tao-charts :data="option.barChart" /> </dv-border-box-11> </article> <article class="item-span item-span3"> <dv-border-box-11 title="人口出入時間段統計"> <tao-charts :data="option.hillChart" /> </dv-border-box-11> </article> </section> </div></template><script>// import axios from "axios"import { reactive, onMounted, getCurrentInstance } from "vue"import chartConfig from "./echarts"import cityJson from "./city.json"export default { setup() { const { ctx } = getCurrentInstance() // 指定圖表的配置項和資料 const dataset = [ ["product", "值"], ["襯衫", 43.3], ["羊毛衫", 83.1], ["雪紡衫", 86.4], ["褲子", 72.4], ["高跟鞋", 72.4], ["襪子", 72.4] ] const dataset2 = [ ["違法犯罪人員分析", "數值"], ["賣淫嫖娼", 335], ["經偵嫌疑", 310], ["重點人口", 234], ["刑貞重點", 135], ["吸毒人口", 148] ] const dataset3 = [ ["人口出入時間段統計", "數值"], ["馴鹿", 123], ["火箭", 60], ["飛機", 234], ["高鐵", 45], ["輪船", 148], ["汽車", 148], ["跑步", 148], ["步行", 148] ] const dataset4 = [ ["地區分佈", "數值"], ["河北", 123], ["天津", 60], ["北京", 234], ["新疆", 45], ["內蒙", 148], ["寧夏", 148], ["海南", 148] ] const option = reactive( { lineChart: chartConfig.lineChart(ctx.echarts, dataset), pieChart: chartConfig.pieChart(ctx.echarts, dataset2), hillChart: chartConfig.hillChart(ctx.echarts, dataset3), barChart: chartConfig.barChart(ctx.echarts, dataset4), pieChartVie: chartConfig.pieChartVie(ctx.echarts), mapChart: { ...chartConfig.mapChart(ctx.echarts, cityJson) } } ) onMounted(() => { // 介面呼叫 // axios.get("https://geo.datav.aliyun.com/areas_v2/bound/100000_full.json").then((res) => { // console.log(res, "ress") // 資料賦值 // option.mapChart = chartConfig.mapChart(ctx.echarts, res.data) // }) }) return { option } }}</script><style lang="scss" scoped>$num-text-size: 0.44rem;.wrapper { width: 100vw; height: 100vh; position: absolute; margin: 0; overflow: hidden; background: url("/img/index_bg.png") no-repeat 0 0 / 100% 100%; background-size: cover; display: flex; color: #ffffff; .item { flex-direction: column; display: flex; margin: 0.2rem 0; .item-span { .title { color: #0e94ea; } .num { color: #ffffff; font-size: $num-text-size; } } } .span1 { width: 25vw; .item-span1 { height: 20vh; } .item-span2 { flex: 1; } .item-span3 { height: 30vh; } } .span2 { flex: 1; } .span3 { width: 25vw; .item-span { flex: 1; } }}.flex-center-align { display: flex; justify-content: center; align-items: center; flex-flow: column;}.flex-center { display: flex; justify-content: center; align-items: center; .title { color: #7fff00; font-weight: bold; margin-left: 0.4rem; }}.header { display: flex; justify-content: center; align-items: center; font-size: 0.44rem; color: #cdddf7; font-weight: 900; letter-spacing: 5px;}.animate-rate { width: 6rem; height: 6rem; position: fixed; margin: 0 auto; top: 25vh; left: 35%;}</style>
效果預覽總結

上面的程式碼只是部分,完整程式碼我也上傳到碼雲上面了,需要說明下,所有的資料都是隨便造的,具體細節也沒有調,只是作為個demo,如果想要完整的程式碼碼雲上搜索upholdjx/vue-datav-chart就可以找到了

下面展示幾張上面提到的別人寫的HTML版本的一些樣例,感覺挺不錯有需要的可以去看看,地址在開頭也說了。

最新評論
  • 1 #

    一個web應用,冒充大屏。了解視覺化大屏嗎?

  • 2 #

    我覺得大屏的核心在於產品原型的設計和美工

  • 3 #

    一般般,智慧社群專案都快黃了

  • 4 #

    螞蟻的antv很容易做出來

  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • App應用開發,新人小白應該看的10本資料書