123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658 |
- <script setup name="rateAnalysis">
- import searchCop from './components/search.vue'
- import excelCop from '@/components/excel.vue'
- import treeCop from '@/components/tree.vue'
- import chartCop from './components/chart.vue'
- import lineChartCop from './components/lineChart.vue'
- import scatterSingleChartCop from './components/scatterSingleChart.vue'
- import { ElMessage } from 'element-plus';
- import { onMounted, ref, onActivated, shallowRef, reactive } from 'vue'
- import request from '@/api/axios.js'
- // import flowerRes from '@/data/flower.json'
- import lineChartRes from '@/data/lineNew.json'
- /**配置参数 */
- const treeHeight = ref(window.innerHeight - 140 + 'px') //tree高度
- const excelHeight = ref(window.innerHeight - 140 + 'px') //excel高度
- const tableHeight = ref(window.innerHeight - 140 + 'px')
- /**excel 开始 */
- const excelCheckIds = ref([])
- const excelList = ref([])
- //点击excel项时
- const funExcelChange = async (obj) => {
- excelCheckIds.value = [obj.id] //当为单选展示风机图表时
- chartExcelList.value = excelList.value.map(o=> {
- return {
- ...o,
- name: o.windturbine
- }
- }) // 选中excel当前项时, excel列表赋值给dialog 下拉框
- queryForm.checkIds = excelList.value.map(o => o.id)
- funSubmit()
- }
- const funExcelCheckChange = ({ checkArr, data }) => {
- excelCheckIds.value = checkArr
- }
- /**tree 开始 */
- const treeData = ref([])
- const actTreeNode = ref(null)
- const funRepeatMap = (arr) => {
- return arr.map(o => {
- if (o.children) {
- const findIndex = o.children.findIndex(p => !!p.type)
- if (findIndex !== -1) {
- o.childs = o.children
- o.children = []
- if(!actTreeNode.value){
- actTreeNode.value = o
- }
- }
- }
- return {
- ...o,
- children: o.children?.length ? funRepeatMap(o.children) : []
- }
- })
- }
- const funGetTree = async () => {
- const res = await request.get("/power/process/tree")
- actTreeNode.value = null
- excelList.value = []
- treeData.value = funRepeatMap(res.data)
- if(actTreeNode.value){
- funCurrentChange({current: actTreeNode.value, currentNode: null})
- funExcelChange({id: actTreeNode.value.childs[0].id})
- }
- }
- const funTreeCheckChange = ({ current, checkedNodes, checkedKeys, halfCheckedNodes, halfCheckedKeys }) => { //tree change -> excel change
- funCurrentChange({ current, currentNode: '' })
- const checkIds = []
- if (checkedNodes.length) {
- for (const node of checkedNodes) {
- if (node.childs && node.childs.length) {
- for (const child of node.childs) {
- checkIds.push(child.id)
- }
- }
- }
- }
- excelCheckIds.value = checkIds
- }
- const funCurrentChange = ({ current, currentNode }) => {
- if (current.childs) {
- excelList.value = current.childs.map(o => {
- return {
- id: o.id,
- interval: o.interval,
- path: o.path,
- prepareid: o.prepareid,
- station: o.station,
- time: o.time,
- type: o.type,
- windturbine: o.windturbine,
- name: o.path.substring(o.path.indexOf(o.station + '_') + (o.station + '_').length)
- }
- })
- } else {
- excelList.value = []
- }
- }
- /**chart */
- const funText = (index) => {
- let str = ''
- switch (index) {
- case 0:
- str = '0-2.5'
- break
- case 1:
- str = '2.5-5'
- break
- case 2:
- str = '5-7.5'
- break
- case 3:
- str = '7.5-10'
- break
- case 4:
- str = '10-12.5'
- break
- case 5:
- str = '12.5-15'
- break
- case 6:
- str = '15-17.5'
- break
- case 7:
- str = '17.5-20'
- break
- case 8:
- str = '20-22.5'
- break
- case 9:
- str = '22.5-25'
- break
- case 10:
- str = '25-inf'
- break
- }
- return str
- }
- const chartData = ref([]) //roses的chartList
- let chartId = 1
- /**submit */
- const funSubmit = async () => {
- const rosesRes = await request.get('/wind/roses', {
- params: {
- ids: excelCheckIds.value.join(','),
- mode: 0
- }
- })
- const lineRes = await request.get('/wind/deviation/ratio', {
- params: {
- ids: excelCheckIds.value.join(','),
- mode: 0
- }
- })
- // const rosesRes = flowerRes
- // const lineRes = lineChartRes
- if (rosesRes.code === 200) {
- if (rosesRes.data?.length) {
- console.log(rosesRes.data)
- chartData.value = []
- for (const chart of rosesRes.data) {
- chartData.value.push({
- id: chartId,
- title: '',
- subtext: '风速风向分布图',
- xAxis: {
- type: 'category',
- boundaryGap: false,
- data: ['N','', 'N-E','', 'E','', 'S-E','', 'S','', 'S-W','', 'W','', 'W-N',''],
- splitLine: {
- show: true
- },
- },
- isRadar: false,
- series: chart.roses?.length ?chart.roses.map((o, index) => {
- return {
- type: 'bar',
- data: o,
- coordinateSystem: 'polar',
- name: funText(index),
- stack: 'a',
- emphasis: {
- focus: 'series'
- }
- }
- }): []
- })
- chartId++
- chartData.value.push({
- id: chartId,
- title: '',
- subtext: '风速风向频次图',
- xAxis: {
- type: 'category',
- boundaryGap: false,
- data: ['N','', 'N-E','', 'E','', 'S-E','', 'S','', 'S-W','', 'W','', 'W-N',''],
- splitLine: {
- show: true
- }
- },
- isRadar: true, //显示雷达图
- series: chart.count?.length? [...chart.count.map((o,index) => {
- return {
- type: 'bar',
- data: o,
- coordinateSystem: 'polar',
- name: funText(index),
- stack: 'a',
- emphasis: {
- focus: 'series'
- }
- }
- }), {
- type: 'radar',
- tooltip: {
- trigger: 'item'
- },
- // areaStyle: {},
- data: [
- {
- // value: [1,2,3,4,5,6,7,8],
- value: chart.radar,
- name: '对风风向'
- }
- ]
- }]: []
- })
- chartId++
- }
- }
- }
- if(lineRes.code === 200){
- console.log(lineRes.data)
- if(lineRes.data?.length){
- lineDataSet.value[0].source = lineRes.data[0].scatter.map(o => {
- return [o.x+'', o.y]
- })
- lineSeries.value = [{
- name: "偏差率",
- type: "line",
- symbol: "line", //设定为实心点
- symbolSize: 0, //设定实心点的大小
- smooth: true, //这个是把线变成曲线
- data: lineRes.data[0].count,
- xAxisIndex: 0,
- yAxisIndex: 1,
- },
- {
- type: 'effectScatter',
- showEffectOn: "emphasis",
-
- rippleEffect: {
- scale: 1
- },
- legendHoverLink: false,
- name: '数据散点',
- symbolSize: 5,
- datasetIndex: 0,
- encode: {
- x: 'x',
- y: 'y'
- },
- xAxisIndex: 0,
- yAxisIndex: 0,
- }]
- }
- }
- }
- /**lineChart */
- const linexAxis = ref({
- type: 'category',
- data: new Array(101).fill(-50).map((o,index) => Number((o + index).toFixed(1))),
- splitLine: {
- show: false
- },
- axisTick: {
- show: true
- }
- })
- const lineyAxis = ref([
- {
- type: 'value',
- name: 'm/s',
- splitLine: {
- show: false
- },
- axisTick: {
- show: true
- }
- },{
- type: 'value',
- splitLine: {
- show: false
- },
- axisTick: {
- show: true
- }
- }
- ])
- const lineSeries = ref([])
- const lineDataSet = ref([
- {
- source: []
- }
- ])
- /**scatter chart */
- const scatterxData = ref([
- {
- type: 'category',
- data: [
- '12a', '1a', '2a', '3a', '4a', '5a', '6a',
- '7a', '8a', '9a', '10a', '11a',
- '12p', '1p', '2p', '3p', '4p', '5p',
- '6p', '7p', '8p', '9p', '10p', '11p'
- ],
- boundaryGap: false,
- splitLine: {
- show: true
- },
- axisLine: {
- show: true
- }
- }
- ])
- const scatteryData = ref([
- {
- type: 'category',
- data: [
- 'Saturday', 'Friday', 'Thursday',
- 'Wednesday', 'Tuesday', 'Monday', 'Sunday'
- ],
- axisLine: {
- show: false
- },
- splitLine: {
- show: false
- },
- },
- ])
- const scatterSeries = ref(
- [
- {
- name: 'Punch Card',
- type: 'scatter',
- symbolSize: function (val) {
- return val[2] * 2;
- },
- data: [[0, 0, 5], [0, 1, 1], [0, 2, 0], [0, 3, 0], [0, 4, 0], [0, 5, 0], [0, 6, 0], [0, 7, 0], [0, 8, 0], [0, 9, 0], [0, 10, 0], [0, 11, 2], [0, 12, 4], [0, 13, 1], [0, 14, 1], [0, 15, 3], [0, 16, 4], [0, 17, 6], [0, 18, 4], [0, 19, 4], [0, 20, 3], [0, 21, 3], [0, 22, 2], [0, 23, 5], [1, 0, 7], [1, 1, 0], [1, 2, 0], [1, 3, 0], [1, 4, 0], [1, 5, 0], [1, 6, 0], [1, 7, 0], [1, 8, 0], [1, 9, 0], [1, 10, 5], [1, 11, 2], [1, 12, 2], [1, 13, 6], [1, 14, 9], [1, 15, 11], [1, 16, 6], [1, 17, 7], [1, 18, 8], [1, 19, 12], [1, 20, 5], [1, 21, 5], [1, 22, 7], [1, 23, 2], [2, 0, 1], [2, 1, 1], [2, 2, 0], [2, 3, 0], [2, 4, 0], [2, 5, 0], [2, 6, 0], [2, 7, 0], [2, 8, 0], [2, 9, 0], [2, 10, 3], [2, 11, 2], [2, 12, 1], [2, 13, 9], [2, 14, 8], [2, 15, 10], [2, 16, 6], [2, 17, 5], [2, 18, 5], [2, 19, 5], [2, 20, 7], [2, 21, 4], [2, 22, 2], [2, 23, 4], [3, 0, 7], [3, 1, 3], [3, 2, 0], [3, 3, 0], [3, 4, 0], [3, 5, 0], [3, 6, 0], [3, 7, 0], [3, 8, 1], [3, 9, 0], [3, 10, 5], [3, 11, 4], [3, 12, 7], [3, 13, 14], [3, 14, 13], [3, 15, 12], [3, 16, 9], [3, 17, 5], [3, 18, 5], [3, 19, 10], [3, 20, 6], [3, 21, 4], [3, 22, 4], [3, 23, 1], [4, 0, 1], [4, 1, 3], [4, 2, 0], [4, 3, 0], [4, 4, 0], [4, 5, 1], [4, 6, 0], [4, 7, 0], [4, 8, 0], [4, 9, 2], [4, 10, 4], [4, 11, 4], [4, 12, 2], [4, 13, 4], [4, 14, 4], [4, 15, 14], [4, 16, 12], [4, 17, 1], [4, 18, 8], [4, 19, 5], [4, 20, 3], [4, 21, 7], [4, 22, 3], [4, 23, 0], [5, 0, 2], [5, 1, 1], [5, 2, 0], [5, 3, 3], [5, 4, 0], [5, 5, 0], [5, 6, 0], [5, 7, 0], [5, 8, 2], [5, 9, 0], [5, 10, 4], [5, 11, 1], [5, 12, 5], [5, 13, 10], [5, 14, 5], [5, 15, 7], [5, 16, 11], [5, 17, 6], [5, 18, 0], [5, 19, 5], [5, 20, 3], [5, 21, 4], [5, 22, 2], [5, 23, 0], [6, 0, 1], [6, 1, 0], [6, 2, 0], [6, 3, 0], [6, 4, 0], [6, 5, 0], [6, 6, 0], [6, 7, 0], [6, 8, 0], [6, 9, 0], [6, 10, 1], [6, 11, 0], [6, 12, 2], [6, 13, 1], [6, 14, 3], [6, 15, 4], [6, 16, 0], [6, 17, 0], [6, 18, 0], [6, 19, 0], [6, 20, 1], [6, 21, 2], [6, 22, 2], [6, 23, 6]]
- .map(function (item) {
- return [item[1], item[0], item[2]];
- }),
- animationDelay: function (idx) {
- return idx * 5;
- }
- }
- ]
- )
- /**dialog */
- const dialog = ref(false)
- const actChartName = ref('')
- const actCop = shallowRef(chartCop)
- const actCopList = ref([
- // {
- // xAxis: [],
- // subtext: '',
- // title: '',
- // isRadar: false,
- // series: [],
- // yAxis: [],
- // dataset: []
- // }
- ])
- const queryForm = reactive({
- checkIds: []
- })
- const chartExcelList = ref([]) //dialog 下拉项
- const funActCop = (obj, type) => {
- switch(type){
- case 'chartCop1':
- actChartName.value = 'chartCop1'
- actCop.value = chartCop
- break
- case 'chartCop2':
- actChartName.value = 'chartCop2'
- actCop.value = chartCop
- break
- case 'lineChartCop':
- actChartName.value = 'lineChartCop'
- actCop.value = lineChartCop
- break
- case 'scatterSingleChartCop':
- actChartName.value = 'scatterSingleChartCop'
- actCop.value = scatterSingleChartCop
- break
- }
- dialog.value = true
- actCopList.value = [{...obj, id: 0}]
- }
- const funDiaSubmit = async () => {
- let url = ''
- switch(actChartName.value){
- case 'chartCop1':
- url = '/wind/roses'
- break
- case 'chartCop2':
- url = '/wind/roses'
- break
- case 'lineChartCop':
- url = '/wind/deviation/ratio'
- break
- case 'scatterSingleChartCop':
- url = '' //暂无接口
- break
- }
- if(url){
- let chartId = 1
- const res = await request.get(url, {
- params: {
- ids: queryForm.checkIds.join(','),
- mode: 0
- }
- })
- console.log(res)
- if(res.code===200){
- actCopList.value = []
- if(res.data?.length){
- for(const chart of res.data){
- if(actChartName.value==='chartCop1'){
- actCopList.value.push({
- id: chartId,
- title: chart.wt,
- subtext: '风速风向分布图',
- xAxis: {
- type: 'category',
- boundaryGap: false,
- data: ['N','', 'N-E','', 'E','', 'S-E','', 'S','', 'S-W','', 'W','', 'W-N',''],
- splitLine: {
- show: true
- },
- },
- isRadar: false,
- series: chart.roses?.length ?chart.roses.map((o, index) => {
- return {
- type: 'bar',
- data: o,
- coordinateSystem: 'polar',
- name: funText(index),
- stack: 'a',
- emphasis: {
- focus: 'series'
- }
- }
- }): []
- })
- chartId++
- }
- if(actChartName.value === 'chartCop2'){
- actCopList.value.push({
- id: chartId,
- title: chart.wt,
- subtext: '风速风向频次图',
- xAxis: {
- type: 'category',
- boundaryGap: false,
- data: ['N','', 'N-E','', 'E','', 'S-E','', 'S','', 'S-W','', 'W','', 'W-N',''],
- splitLine: {
- show: true
- }
- },
- isRadar: true, //显示雷达图
- series: chart.count?.length? [...chart.count.map((o,index) => {
- return {
- type: 'bar',
- data: o,
- coordinateSystem: 'polar',
- name: funText(index),
- stack: 'a',
- emphasis: {
- focus: 'series'
- }
- }
- }), {
- type: 'radar',
- tooltip: {
- trigger: 'item'
- },
- // areaStyle: {},
- data: [
- {
- // value: [1,2,3,4,5,6,7,8],
- value: chart.radar,
- name: '对风风向'
- }
- ]
- }]: []
- })
- chartId++
- }
- if(actChartName.value === 'lineChartCop'){
- actCopList.value.push({
- id: chartId,
- title: chart.wtId,
- xAxis: {
- type: 'category',
- data: new Array(101).fill(-50).map((o,index) => Number((o + index).toFixed(1))),
- splitLine: {
- show: false
- },
- axisTick: {
- show: true
- }
- },
- yAxis: [
- {
- type: 'value',
- name: 'm/s',
- splitLine: {
- show: false
- },
- axisTick: {
- show: true
- }
- },{
- type: 'value',
- splitLine: {
- show: false
- },
- axisTick: {
- show: true
- }
- }
- ],
- dataset: [{
- source: chart.scatter.map(o => {
- return [o.x+'', o.y]
- })
- }],
- series: [{
- name: "偏差率",
- type: "line",
- symbol: "line", //设定为实心点
- symbolSize: 0, //设定实心点的大小
- smooth: true, //这个是把线变成曲线
- data: chart.count,
- xAxisIndex: 0,
- yAxisIndex: 1,
- },
- {
- type: 'effectScatter',
- showEffectOn: "emphasis",
-
- rippleEffect: {
- scale: 1
- },
- legendHoverLink: false,
- name: '数据散点',
- symbolSize: 5,
- datasetIndex: 0,
- encode: {
- x: 'x',
- y: 'y'
- },
- xAxisIndex: 0,
- yAxisIndex: 0,
- }]
- })
- chartId++
- }
- }
- }
- }
- }
- }
- /**created */
- // funGetTree()
- /**activated */
- onMounted(() => {
- //test
- // funSubmit()
- //
- tableHeight.value = window.innerHeight - 140 + 'px'
- excelHeight.value =(window.innerHeight - 140) + 'px'
- treeHeight.value = (window.innerHeight - 140) + 'px'
- window.addEventListener('resize', () => {
- tableHeight.value = window.innerHeight - 140 + 'px'
- excelHeight.value = (window.innerHeight - 140) + 'px'
- treeHeight.value = (window.innerHeight - 140) + 'px'
- })
- })
- onActivated(() => {
- funGetTree()
- })
- </script>
- <template>
- <div class="bg-white py-[10px] px-[10px] relative">
- <!-- <search-cop class="mb-[20px] shadow rounded-[6px] shadow-blue-500" @submit="funSubmit">
- </search-cop> -->
- <el-dialog width="1000px" v-model="dialog" title="图表">
- <el-form class="whitespace-nowrap" :inline="true" :model="queryForm">
- <el-form-item label="" class="!mb-0">
- <el-select v-model="queryForm.checkIds" clearable collapse-tags multiple>
- <el-option v-for="item in chartExcelList" :key="item.id" :value="item.id" :label="item.name"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item class="!mb-0">
- <submit-btn desc="多台展示" @click="funDiaSubmit"></submit-btn>
- </el-form-item>
- </el-form>
- <div class="flex flex-wrap justify-center items-center h-[600px] w-[950px] overflow-y-auto overflow-x-hidden">
- <component :is="actCop" :width="actCopList.length>1?'470px':'700px'" height="400px" v-for="item in actCopList" :key="item.id" :xAxis="item.xAxis" :subtext="item.subtext" :title="item.title"
- :isRadar="item.isRadar" :series="item.series" :yAxis="item.yAxis" :dataset="item.dataset"></component>
- </div>
- </el-dialog>
- <div class="relative shadow rounded-[6px] shadow-blue-500 px-[10px] pt-[10px] pb-[10px]">
- <div class="text-[14px] absolute top-[-7px] text-[#B3B3B3] left-[20px]">数据展示</div>
- <el-row :gutter="10">
- <el-col :span="5">
- <tree-cop :data="treeData" @checkChange="funTreeCheckChange" :show-checkbox="false" :height="treeHeight"
- @currentChange="funCurrentChange" @refresh="funGetTree">
- </tree-cop>
- </el-col>
- <el-col :span="3">
- <excel-cop :checkIds="excelCheckIds" :showCheckbox="false" :data="excelList" :height="excelHeight"
- @excelChange="funExcelChange" @checkChange="funExcelCheckChange"></excel-cop>
- </el-col>
- <el-col :span="16">
- <div :style="{ height: tableHeight }"
- class="flex flex-wrap justify-center items-center overflow-x-hidden overflow-y-auto ">
- <div class="mb-[10px] w-[49%] h-[49%] flex flex-col items-end shadow rounded-[6px] shadow-blue-500" v-for="(item, index) in chartData" :key="item.id" :class="{ 'mr-[10px]': index % 2 === 0 }">
- <el-icon class="mr-[10px] mt-[10px] cursor-pointer" size="18" @click="funActCop(item, 'chartCop'+ (index+1))">
- <ZoomIn />
- </el-icon>
- <chart-cop class="" height="100%" width="100%"
- :xAxis="item.xAxis" :subtext="item.subtext" :title="item.title" :isRadar="item.isRadar"
- :series="item.series">
- </chart-cop>
- </div>
- <div class="mr-[10px] w-[49%] h-[49%] flex flex-col items-end shadow rounded-[6px] shadow-blue-500">
- <el-icon class="mr-[10px] mt-[10px] cursor-pointer" size="18" @click="funActCop({xAxis: linexAxis, yAxis: lineyAxis, series: lineSeries, dataset: lineDataSet}, 'lineChartCop')">
- <ZoomIn />
- </el-icon>
- <line-chart-cop class="" height="100%" width="100%" :xAxis="linexAxis"
- :yAxis="lineyAxis" :series="lineSeries" :dataset="lineDataSet"></line-chart-cop>
- </div>
- <div class="w-[49%] h-[49%] flex flex-col items-end shadow rounded-[6px] shadow-blue-500">
- <el-icon class="mr-[10px] mt-[10px] cursor-pointer" size="18" @click="funActCop({xAxis: scatterxData, yAxis: scatteryData, series: scatterSeries}, 'scatterSingleChartCop')">
- <ZoomIn />
- </el-icon>
- <scatter-single-chart-cop class="" height="100%" width="100%"
- :xAxis="scatterxData" :yAxis="scatteryData" :series="scatterSeries"></scatter-single-chart-cop>
- </div>
- </div>
- </el-col>
- </el-row>
- </div>
- </div>
- </template>
|