北斗卫星数据监测展示互动系统
This commit is contained in:
54
index.html
54
index.html
@@ -1,13 +1,59 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="w-h-full">
|
||||
<head>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
/* 当屏幕宽度大于或等于3840px时 */
|
||||
@media (min-width: 3840px) {
|
||||
html {
|
||||
font-size: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 当屏幕宽度在2560px到3839px之间时 */
|
||||
@media (min-width: 2560px) and (max-width: 3839px) {
|
||||
html {
|
||||
font-size: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 当屏幕宽度在1920px到2559px之间时 */
|
||||
@media (min-width: 1920px) and (max-width: 2559px) {
|
||||
html {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 当屏幕宽度在750px到1919px之间时 */
|
||||
@media (min-width: 750px) and (max-width: 1919px) {
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 当屏幕宽度在600px到749px之间时 */
|
||||
@media (min-width: 600px) and (max-width: 749px) {
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 当屏幕宽度小于600px时 */
|
||||
@media (max-width: 599px) {
|
||||
html {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<title>北斗卫星数据监测展示软件</title>
|
||||
</head>
|
||||
<body class="w-h-full">
|
||||
</head>
|
||||
|
||||
<body class="w-h-full">
|
||||
<div id="app" class="w-h-full"></div>
|
||||
<script type="module" src="/src/render/main.ts"></script>
|
||||
</body>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -19,6 +19,8 @@
|
||||
"echarts": "^5.1.0",
|
||||
"electron-store": "^8.0.0",
|
||||
"nmea": "http://git.hwasmart.com/bd_group/node-nmea.git",
|
||||
"node-gyp": "^10.0.1",
|
||||
"node-pre-gyp": "^0.17.0",
|
||||
"serialport": "^12.0.0",
|
||||
"through": "^2.3.8",
|
||||
"vue": "^3.2.26",
|
||||
@@ -31,9 +33,9 @@
|
||||
"@vue/compiler-sfc": "^3.2.26",
|
||||
"autoprefixer": "^10.2.5",
|
||||
"cross-env": "^7.0.3",
|
||||
"electron": "^19.0.3",
|
||||
"electron": "^22.0.0",
|
||||
"electron-builder": "^25.0.5",
|
||||
"electron-rebuild": "2.3.5",
|
||||
"electron-rebuild": "^2.3.5",
|
||||
"postcss": "^8.2.10",
|
||||
"rimraf": "^3.0.2",
|
||||
"rollup-plugin-copy": "^3.4.0",
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// 加密关键字
|
||||
const keyword = 'BD'
|
||||
export { keyword }
|
||||
const keyword = 'BD';
|
||||
export { keyword };
|
||||
@@ -1,89 +1,89 @@
|
||||
import { parse, Helpers } from 'nmea'
|
||||
import { parse, Helpers } from 'nmea';
|
||||
|
||||
let events = {}
|
||||
let events = {};
|
||||
const on = (eventName, callback) => {
|
||||
if (!(eventName in events)) {
|
||||
events[eventName] = []
|
||||
events[eventName] = [];
|
||||
}
|
||||
|
||||
events[eventName].push(callback)
|
||||
}
|
||||
events[eventName].push(callback);
|
||||
};
|
||||
|
||||
const emit = (eventName, ...args) => {
|
||||
if (!(eventName in events)) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
const cbs = events[eventName]
|
||||
const cbs = events[eventName];
|
||||
|
||||
cbs.forEach(cb => {
|
||||
cb.call(this, ...args)
|
||||
cb.call(this, ...args);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handle = (value) => {
|
||||
if (value.length <= 0) return
|
||||
if (value.length <= 0) return;
|
||||
|
||||
emit('received', value)
|
||||
nmeaObj = resetNMEAObj()
|
||||
emit('received', value);
|
||||
nmeaObj = resetNMEAObj();
|
||||
|
||||
const strArr = value.split('\r\n')
|
||||
const strArr = value.split('\r\n');
|
||||
for (let i = 0; i < strArr.length; i++) {
|
||||
const element = strArr[i];
|
||||
doHandle(element)
|
||||
doHandle(element);
|
||||
}
|
||||
|
||||
emit('handled', nmeaObj)
|
||||
}
|
||||
emit('handled', nmeaObj);
|
||||
};
|
||||
|
||||
const doHandle = (value) => {
|
||||
if (!verify(value)) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
const result = parse(value)
|
||||
const result = parse(value);
|
||||
switch (result.sentence) {
|
||||
case 'GGA':
|
||||
nmeaObj.GGA = result
|
||||
nmeaObj.GGA = result;
|
||||
break;
|
||||
case 'GLL':
|
||||
nmeaObj.GLL = result
|
||||
nmeaObj.GLL = result;
|
||||
break;
|
||||
case 'RMC':
|
||||
nmeaObj.RMC = result
|
||||
nmeaObj.RMC = result;
|
||||
break;
|
||||
case 'VTG':
|
||||
nmeaObj.VTG = result
|
||||
nmeaObj.VTG = result;
|
||||
break;
|
||||
case 'ZDA':
|
||||
nmeaObj.ZDA = result
|
||||
nmeaObj.ZDA = result;
|
||||
break;
|
||||
case 'TXT':
|
||||
nmeaObj.TXT = result
|
||||
nmeaObj.TXT = result;
|
||||
break;
|
||||
case 'GSA':
|
||||
nmeaObj.GSA.push(result)
|
||||
nmeaObj.GSA.push(result);
|
||||
break;
|
||||
case 'GSV':
|
||||
nmeaObj.GSV.push(result)
|
||||
nmeaObj.GSV.push(result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const verify = (value) => {
|
||||
if (!value) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
|
||||
const dollar_index = value.indexOf('$')
|
||||
const star_index = value.indexOf('*')
|
||||
const dollar_index = value.indexOf('$');
|
||||
const star_index = value.indexOf('*');
|
||||
if (value.indexOf('$') !== 0 || star_index <= dollar_index) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
|
||||
const [sentence, checksum, ] = value.split('*')
|
||||
return Helpers.verifyChecksum(sentence, checksum)
|
||||
}
|
||||
const [sentence, checksum, ] = value.split('*');
|
||||
return Helpers.verifyChecksum(sentence, checksum);
|
||||
};
|
||||
|
||||
const resetNMEAObj = () => {
|
||||
return {
|
||||
@@ -95,9 +95,9 @@ const resetNMEAObj = () => {
|
||||
TXT: null,
|
||||
GSA: [],
|
||||
GSV: []
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
let nmeaObj = resetNMEAObj()
|
||||
let nmeaObj = resetNMEAObj();
|
||||
|
||||
export default { on, handle }
|
||||
export default { on, handle };
|
||||
|
||||
172
src/main/app.ts
172
src/main/app.ts
@@ -1,80 +1,80 @@
|
||||
import { app, screen, globalShortcut, BrowserWindow, ipcMain, dialog } from 'electron'
|
||||
import { join } from "path"
|
||||
import config from './config.js'
|
||||
import './load-serialport'
|
||||
import { keyword } from './KeyWord'
|
||||
import { app, screen, globalShortcut, BrowserWindow, ipcMain, dialog } from 'electron';
|
||||
import { join } from "path";
|
||||
import config from './config.js';
|
||||
import './load-serialport';
|
||||
import { keyword } from './KeyWord';
|
||||
|
||||
import child_process from 'child_process'
|
||||
import crypto from 'crypto'
|
||||
import child_process from 'child_process';
|
||||
import crypto from 'crypto';
|
||||
|
||||
function queryPass(passPath: string, passValue: string) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
try {
|
||||
child_process.exec(`reg query ${passPath} /v ${passValue}`, (error: Error | null, stdout: string, stderr: string) => {
|
||||
if (error) {
|
||||
reject(error)
|
||||
return
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve({stdout, stderr})
|
||||
resolve({stdout, stderr});
|
||||
})
|
||||
} catch (error) {
|
||||
reject(error)
|
||||
reject(error);
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
function queryKey(keyPath: string, keyValue: string) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
try {
|
||||
child_process.exec(`reg query ${keyPath} /v ${keyValue}`, (error: Error | null, stdout: string, stderr: string) => {
|
||||
if (error) {
|
||||
reject(error)
|
||||
return
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve({stdout, stderr})
|
||||
resolve({stdout, stderr});
|
||||
})
|
||||
} catch (error) {
|
||||
reject(error)
|
||||
reject(error);
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
function cryptMD5(GUID: string) {
|
||||
let md5 = crypto.createHash('md5')
|
||||
let ciphertext = md5.update(GUID).digest('hex')
|
||||
return ciphertext.slice(0,8)+'-'+ciphertext.slice(8,12)+'-'+ciphertext.slice(12,16)+'-'+ciphertext.slice(16,20)+'-'+ciphertext.slice(20,32)
|
||||
}
|
||||
let md5 = crypto.createHash('md5');
|
||||
let ciphertext = md5.update(GUID).digest('hex');
|
||||
return ciphertext.slice(0,8)+'-'+ciphertext.slice(8,12)+'-'+ciphertext.slice(12,16)+'-'+ciphertext.slice(16,20)+'-'+ciphertext.slice(20,32);
|
||||
};
|
||||
|
||||
const passPath = 'HKEY_CURRENT_USER\\SOFTWARE\\HwaSmart'
|
||||
const passValue = 'BDAuthorization'
|
||||
const keyPath = 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography'
|
||||
const keyValue = 'MachineGuid'
|
||||
const passPath = 'HKEY_CURRENT_USER\\SOFTWARE\\HwaSmart';
|
||||
const passValue = 'BDAuthorization';
|
||||
const keyPath = 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography';
|
||||
const keyValue = 'MachineGuid';
|
||||
|
||||
async function checkLaunchEnv() {
|
||||
try {
|
||||
const passResult: any = await queryPass(passPath, passValue)
|
||||
const keyResult: any = await queryKey(keyPath, keyValue)
|
||||
const passResult: any = await queryPass(passPath, passValue);
|
||||
const keyResult: any = await queryKey(keyPath, keyValue);
|
||||
if(cryptMD5(keyResult.stdout.slice(83,119) + keyword) == passResult.stdout.slice(72,108)){
|
||||
return true
|
||||
return true;
|
||||
}else{
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
// 成功
|
||||
// 查询到 有这个app启动项
|
||||
} catch (error) {
|
||||
// 没有查询到该app启动项目
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async function main() {
|
||||
// 异步代码
|
||||
const checkReault: any = await checkLaunchEnv()
|
||||
console.log('env right:', checkReault)
|
||||
const checkReault: any = await checkLaunchEnv();
|
||||
console.log('env right:', checkReault);
|
||||
|
||||
// 异步代码执行完毕后执行的代码
|
||||
if (checkReault) {
|
||||
const URl_REGEX = /[a-zA-z]+:\/\/[^\s]*/
|
||||
const URl_REGEX = /[a-zA-z]+:\/\/[^\s]*/;
|
||||
const DEFAULT_OPTION = {
|
||||
fullscreen: true,
|
||||
frame: false,
|
||||
@@ -82,57 +82,75 @@ const DEFAULT_OPTION = {
|
||||
nodeIntegration: true,
|
||||
preload: join(__dirname, 'preload.js')
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const launch = () => {
|
||||
const extend_tdt_window = config.get('extend_tdt_window')
|
||||
const displays = screen.getAllDisplays()
|
||||
const showMode = config.get('showMode');
|
||||
const extend_tdt_window = config.get('extend_tdt_window');
|
||||
const displays = screen.getAllDisplays();
|
||||
|
||||
const { option, url } = getMonitorWindowArguments(displays[0])
|
||||
createWindow(option, url)
|
||||
if (showMode == "showPositive") {
|
||||
const { option, url } = getMonitorWindowArguments(displays[0]);
|
||||
createWindow(option, url);
|
||||
|
||||
if (extend_tdt_window) {
|
||||
const { option, url } = getTDTWindowArguments(displays[displays.length - 1])
|
||||
createWindow(option, url)
|
||||
const { option, url } = getTDTWindowArguments(displays[displays.length - 1]);
|
||||
createWindow(option, url);
|
||||
}
|
||||
}
|
||||
} else if (showMode == "showReverse") {
|
||||
const { option, url } = getTDTWindowArguments(displays[0]);
|
||||
createWindow(option, url);
|
||||
|
||||
if (extend_tdt_window) {
|
||||
const { option, url } = getMonitorWindowArguments(displays[displays.length - 1]);
|
||||
createWindow(option, url);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getMonitorWindowArguments = (display: any) => {
|
||||
const option = getOption(display)
|
||||
const url = process.env.NODE_ENV === 'development' ? 'http://localhost:3000/' : 'dist/render/index.html'
|
||||
const option = getOption(display);
|
||||
const url = process.env.NODE_ENV === 'development' ? 'http://localhost:3000/' : 'dist/render/index.html';
|
||||
|
||||
return { option, url };
|
||||
};
|
||||
|
||||
return { option, url }
|
||||
}
|
||||
const getTDTWindowArguments = (display: any) => {
|
||||
const option = getOption(display)
|
||||
const url = 'http://gd.map.hwasmart.com/'
|
||||
const option = getOption(display);
|
||||
const url = 'http://gd.map.hwasmart.com/';
|
||||
|
||||
return { option, url }
|
||||
}
|
||||
return { option, url };
|
||||
};
|
||||
|
||||
const getOption = (display: any) => {
|
||||
const origin = getDisplayOrigin(display)
|
||||
const option = Object.assign({}, DEFAULT_OPTION, origin)
|
||||
return option
|
||||
}
|
||||
const origin = getDisplayOrigin(display);
|
||||
const option = Object.assign({}, DEFAULT_OPTION, origin);
|
||||
return option;
|
||||
};
|
||||
|
||||
const getDisplayOrigin = (display: any) => {
|
||||
const origin = !display ? {x: 0, y: 0} : {x: display.bounds.x, y: display.bounds.y}
|
||||
return origin
|
||||
}
|
||||
const origin = !display ? {x: 0, y: 0} : {x: display.bounds.x, y: display.bounds.y};
|
||||
return origin;
|
||||
};
|
||||
|
||||
var windows:Array<BrowserWindow> = [];
|
||||
|
||||
function createWindow(option: any, url: any) {
|
||||
const win = new BrowserWindow(option)
|
||||
const win = new BrowserWindow(option);
|
||||
if (URl_REGEX.test(url)) {
|
||||
win.loadURL(url)
|
||||
win.loadURL(url);
|
||||
} else {
|
||||
win.loadFile(url)
|
||||
win.loadFile(url);
|
||||
}
|
||||
if(process.env.NODE_ENV === 'development') win.webContents.openDevTools()
|
||||
if(process.env.NODE_ENV === 'development') win.webContents.openDevTools();
|
||||
windows.push(win);
|
||||
}
|
||||
};
|
||||
|
||||
ipcMain.on("APP_MOUNTED", (event) => {
|
||||
const { sender } = event;
|
||||
let softwareName = config.get('softwareName');
|
||||
sender.send('softwareName', softwareName);
|
||||
});
|
||||
|
||||
ipcMain.on('CLOSE', (event) => {
|
||||
const res = dialog.showMessageBox({
|
||||
@@ -143,7 +161,7 @@ ipcMain.on('CLOSE', (event) => {
|
||||
cancelId: 1, // 按esc默认点击索引按钮
|
||||
defaultId: 0, // 默认高亮的按钮下标
|
||||
buttons: ['确认', '取消'], // 按钮按索引从右往左排序
|
||||
})
|
||||
});
|
||||
|
||||
res.then((data)=>{
|
||||
if(data.response == 0){
|
||||
@@ -152,33 +170,33 @@ ipcMain.on('CLOSE', (event) => {
|
||||
});
|
||||
windows = [];
|
||||
}else{
|
||||
console.log('not close software')
|
||||
console.log('not close software');
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
app.whenReady().then(() => {
|
||||
launch()
|
||||
launch();
|
||||
|
||||
// 屏蔽 F11 进入/退出全屏功能
|
||||
globalShortcut.register('F11', () => {return})
|
||||
})
|
||||
globalShortcut.register('F11', () => {return});
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
app.quit();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
app.on('activate', () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
launch()
|
||||
launch();
|
||||
}
|
||||
})
|
||||
});
|
||||
} else {
|
||||
dialog.showErrorBox('系统提示', '软件启动出错,请联系售后技术支持人员')
|
||||
process.exit(1)
|
||||
}
|
||||
dialog.showErrorBox('系统提示', '软件启动出错,请联系售后技术支持人员');
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
main()
|
||||
main();
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// import Store from 'electron-store'
|
||||
const Store = require('electron-store')
|
||||
const Store = require('electron-store');
|
||||
|
||||
const store = new Store()
|
||||
const set = (key, val) => store.set(key, val)
|
||||
const store = new Store();
|
||||
const set = (key, val) => store.set(key, val);
|
||||
|
||||
const get = (key) => store.get(key)
|
||||
const get = (key) => store.get(key);
|
||||
|
||||
// export default {set, get}
|
||||
module.exports = { set, get }
|
||||
module.exports = { set, get };
|
||||
@@ -1,26 +1,26 @@
|
||||
import { ipcMain } from 'electron'
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
const senders = []
|
||||
const senders = [];
|
||||
ipcMain.on("APP_MOUNTED", (event) => {
|
||||
const { sender } = event
|
||||
senders.push(sender)
|
||||
const { sender } = event;
|
||||
senders.push(sender);
|
||||
|
||||
sender.once('destroyed', () => {
|
||||
const index = senders.indexOf(sender)
|
||||
if (index >= 0) senders.splice(index, 1)
|
||||
const index = senders.indexOf(sender);
|
||||
if (index >= 0) senders.splice(index, 1);
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
const sendMsg = (channel, msg) => {
|
||||
if (senders.length <= 0) return
|
||||
if (senders.length <= 0) return;
|
||||
|
||||
try {
|
||||
senders.forEach((sender) => {
|
||||
sender.send(channel, msg)
|
||||
sender.send(channel, msg);
|
||||
})
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default sendMsg
|
||||
export default sendMsg;
|
||||
|
||||
@@ -1,49 +1,49 @@
|
||||
import { SerialPort } from 'serialport'
|
||||
import { InterByteTimeoutParser } from '@serialport/parser-inter-byte-timeout'
|
||||
import config from './config.js'
|
||||
import sendMsg from './ipcRendererManager'
|
||||
import NMEAHandler from './api/NMEAHandler'
|
||||
import { SerialPort } from 'serialport';
|
||||
import { InterByteTimeoutParser } from '@serialport/parser-inter-byte-timeout';
|
||||
import config from './config.js';
|
||||
import sendMsg from './ipcRendererManager';
|
||||
import NMEAHandler from './api/NMEAHandler';
|
||||
|
||||
const DEFAULT_BAUDRATE = 115200
|
||||
const DEFAULT_BAUDRATE = 115200;
|
||||
const getSerialPortConstructorArguments = (ports) => {
|
||||
// 很多电脑自带COM1接口,过滤掉COM1口
|
||||
ports = ports.filter((port) => port.path != 'COM1')
|
||||
if (ports.length == 0) return
|
||||
ports = ports.filter((port) => port.path != 'COM1');
|
||||
if (ports.length == 0) return;
|
||||
|
||||
const serialport = config.get('serialport')
|
||||
const path = ( serialport && serialport.path ) ? serialport.path : ports[0].path
|
||||
const baudRate = ( serialport && serialport.baudRate ) ? serialport.baudRate : DEFAULT_BAUDRATE
|
||||
return { path, baudRate }
|
||||
}
|
||||
const serialport = config.get('serialport');
|
||||
const path = ( serialport && serialport.path ) ? serialport.path : ports[0].path;
|
||||
const baudRate = ( serialport && serialport.baudRate ) ? serialport.baudRate : DEFAULT_BAUDRATE;
|
||||
return { path, baudRate };
|
||||
};
|
||||
|
||||
const openSerialport = (ports) => {
|
||||
try {
|
||||
const constructorArguments = getSerialPortConstructorArguments(ports)
|
||||
const constructorArguments = getSerialPortConstructorArguments(ports);
|
||||
if (!constructorArguments) {
|
||||
console.error('设备未连接')
|
||||
return
|
||||
console.error('设备未连接');
|
||||
return;
|
||||
}
|
||||
|
||||
const { path, baudRate } = constructorArguments
|
||||
const { path, baudRate } = constructorArguments;
|
||||
|
||||
const serialPort = new SerialPort({ path, baudRate })
|
||||
const parser = serialPort.pipe(new InterByteTimeoutParser({interval: 300}))
|
||||
const serialPort = new SerialPort({ path, baudRate });
|
||||
const parser = serialPort.pipe(new InterByteTimeoutParser({interval: 300}));
|
||||
|
||||
NMEAHandler.on('received' , (nmeaStr) => {
|
||||
sendMsg('NMEA_RECEIVED', nmeaStr)
|
||||
})
|
||||
sendMsg('NMEA_RECEIVED', nmeaStr);
|
||||
});
|
||||
|
||||
NMEAHandler.on('handled' , (nmeaObj) => {
|
||||
sendMsg('NMEA_HANDLED', JSON.stringify(nmeaObj))
|
||||
})
|
||||
sendMsg('NMEA_HANDLED', JSON.stringify(nmeaObj));
|
||||
});
|
||||
|
||||
parser.on('data', (data) => NMEAHandler.handle(data.toString()))
|
||||
parser.on('data', (data) => NMEAHandler.handle(data.toString()));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SerialPort.list().then(
|
||||
ports => openSerialport(ports),
|
||||
err => console.error(err)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
const { ipcRenderer, contextBridge } = require('electron')
|
||||
const { ipcRenderer, contextBridge } = require('electron');
|
||||
|
||||
contextBridge.exposeInMainWorld('ipcRenderer', {
|
||||
send: (channel, data) => {
|
||||
// whitelist channels
|
||||
let validChannels = ['toMain']
|
||||
let validChannels = ['toMain'];
|
||||
if (validChannels.includes(channel)) {
|
||||
ipcRenderer.send(channel, data)
|
||||
ipcRenderer.send(channel, data);
|
||||
}
|
||||
ipcRenderer.send(channel, data)
|
||||
ipcRenderer.send(channel, data);
|
||||
},
|
||||
receive: (channel, func) => {
|
||||
let validChannels = ['fromMain']
|
||||
let validChannels = ['fromMain'];
|
||||
if (validChannels.includes(channel)) {
|
||||
// Deliberately strip event as it includes `sender`
|
||||
ipcRenderer.on(channel, (event, ...args) => func(...args))
|
||||
ipcRenderer.on(channel, (event, ...args) => func(...args));
|
||||
}
|
||||
ipcRenderer.on(channel, (event, ...args) => func(...args))
|
||||
ipcRenderer.on(channel, (event, ...args) => func(...args));
|
||||
}
|
||||
})
|
||||
});
|
||||
@@ -16,43 +16,46 @@
|
||||
<BaseInfoView ref="baseInfoViewInstance" />
|
||||
</div>
|
||||
<div class="text-white fixed bottom-0 right-0">
|
||||
北斗卫星数据监测展示互动系统V1.0
|
||||
{{ softwareName }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import SNRView from './components/SNRView.vue'
|
||||
import NMEAView from './components/NMEAView.vue'
|
||||
import EarthView from './components/EarthView.vue'
|
||||
import BaseInfoView from './components/BaseInfoView.vue'
|
||||
import PlanisphereView from './components/PlanisphereView.vue'
|
||||
import { ref, onMounted } from 'vue';
|
||||
import SNRView from './components/SNRView.vue';
|
||||
import NMEAView from './components/NMEAView.vue';
|
||||
import EarthView from './components/EarthView.vue';
|
||||
import BaseInfoView from './components/BaseInfoView.vue';
|
||||
import PlanisphereView from './components/PlanisphereView.vue';
|
||||
|
||||
const nmeaViewInstance = ref(null);
|
||||
const snrViewInstance = ref(null);
|
||||
const earthViewInstance = ref(null);
|
||||
const baseInfoViewInstance = ref(null);
|
||||
const planisphereViewInstance = ref(null);
|
||||
const softwareName = ref("北斗卫星数据监测展示互动系统V1.0");
|
||||
|
||||
const nmeaViewInstance = ref(null)
|
||||
const snrViewInstance = ref(null)
|
||||
const earthViewInstance = ref(null)
|
||||
const baseInfoViewInstance = ref(null)
|
||||
const planisphereViewInstance = ref(null)
|
||||
|
||||
const changeName = (newName) => {
|
||||
if (newName !== undefined) {
|
||||
softwareName.value = newName;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if ('ipcRenderer' in window) {
|
||||
ipcRenderer.receive('NMEA_RECEIVED', nmeaViewInstance.value.update)
|
||||
|
||||
ipcRenderer.receive('NMEA_RECEIVED', nmeaViewInstance.value.update);
|
||||
ipcRenderer.receive('NMEA_HANDLED' , (nmeaStr: string) => {
|
||||
const nmea = JSON.parse(nmeaStr)
|
||||
|
||||
snrViewInstance.value.update(nmea)
|
||||
earthViewInstance.value.update(nmea)
|
||||
baseInfoViewInstance.value.update(nmea)
|
||||
planisphereViewInstance.value.update(nmea)
|
||||
})
|
||||
|
||||
ipcRenderer.send('APP_MOUNTED')
|
||||
const nmea = JSON.parse(nmeaStr);
|
||||
snrViewInstance.value.update(nmea);
|
||||
earthViewInstance.value.update(nmea);
|
||||
baseInfoViewInstance.value.update(nmea);
|
||||
planisphereViewInstance.value.update(nmea);
|
||||
});
|
||||
ipcRenderer.receive("softwareName", changeName);
|
||||
ipcRenderer.send('APP_MOUNTED');
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -1,58 +1,67 @@
|
||||
import { Helpers } from 'nmea'
|
||||
import { Helpers } from 'nmea';
|
||||
|
||||
const getPosition = (nmea) => {
|
||||
if (!nmea) return
|
||||
if (!nmea) return;
|
||||
|
||||
const { RMC } = nmea
|
||||
const position = { lng: Helpers.parseLongitude(RMC.lon, RMC.lonPole), lat: Helpers.parseLatitude(RMC.lat, RMC.latPole) }
|
||||
const { RMC } = nmea;
|
||||
const position = { lng: Helpers.parseLongitude(RMC.lon, RMC.lonPole), lat: Helpers.parseLatitude(RMC.lat, RMC.latPole) };
|
||||
|
||||
return position
|
||||
}
|
||||
return position;
|
||||
};
|
||||
|
||||
const getBaseInfo = (nmea) => {
|
||||
if (!nmea) return
|
||||
if (!nmea) return;
|
||||
|
||||
const { RMC, GGA } = nmea
|
||||
const { RMC, GGA } = nmea;
|
||||
try {
|
||||
const longitude = (!RMC.lon || !RMC.lonPole) ? '' : Helpers.parseLongitude(RMC.lon, RMC.lonPole)
|
||||
const latitude = (!RMC.lat || !RMC.latPole) ? '' : Helpers.parseLatitude(RMC.lat, RMC.latPole)
|
||||
const altitude = GGA.alt + GGA.altUnit
|
||||
const date = (!RMC.date) ? '' : '20' + RMC.date.slice(4, 6) + '-' + RMC.date.slice(2, 4) + '-' + RMC.date.slice(0, 2)
|
||||
let UTCTime = '', BJTime = ''
|
||||
const longitude = (!RMC.lon || !RMC.lonPole) ? '' : Helpers.parseLongitude(RMC.lon, RMC.lonPole);
|
||||
const latitude = (!RMC.lat || !RMC.latPole) ? '' : Helpers.parseLatitude(RMC.lat, RMC.latPole);
|
||||
const altitude = GGA.alt + GGA.altUnit;
|
||||
const date = (!RMC.date) ? '' : '20' + RMC.date.slice(4, 6) + '-' + RMC.date.slice(2, 4) + '-' + RMC.date.slice(0, 2);
|
||||
let UTCTime = '', BJTime = '';
|
||||
if (RMC.timestamp) {
|
||||
const hour = parseInt(RMC.timestamp.slice(0, 2))
|
||||
const bjHour = (hour + 8) % 24
|
||||
UTCTime = hour.toString().padStart(2, '0') + ':' + RMC.timestamp.slice(2, 4) + ':' + RMC.timestamp.slice(4, 6)
|
||||
BJTime = bjHour.toString().padStart(2, '0') + ':' + RMC.timestamp.slice(2, 4) + ':' + RMC.timestamp.slice(4, 6)
|
||||
const hour = parseInt(RMC.timestamp.slice(0, 2));
|
||||
const bjHour = (hour + 8) % 24;
|
||||
UTCTime = hour.toString().padStart(2, '0') + ':' + RMC.timestamp.slice(2, 4) + ':' + RMC.timestamp.slice(4, 6);
|
||||
BJTime = bjHour.toString().padStart(2, '0') + ':' + RMC.timestamp.slice(2, 4) + ':' + RMC.timestamp.slice(4, 6);
|
||||
}
|
||||
|
||||
const baseInfo = { longitude, latitude, altitude, date, UTCTime, BJTime }
|
||||
return baseInfo
|
||||
const baseInfo = { longitude, latitude, altitude, date, UTCTime, BJTime };
|
||||
return baseInfo;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getSNROption = (nmea) => {
|
||||
if (!nmea) return
|
||||
if (!nmea) return;
|
||||
|
||||
const { GSV, GSA } = nmea
|
||||
const GSVArr = GSV.filter((gsv) => gsv.talker_id === 'BD')
|
||||
const GSAArr = GSA.filter((gsa) => gsa.talker_id === 'BD')
|
||||
const { GSV, GSA } = nmea;
|
||||
const GSVArr = GSV.filter((gsv) => gsv.talker_id === 'BD' || gsv.talker_id === 'GB');
|
||||
const GSAArr = GSA.filter((gsa) => gsa.talker_id === 'BD' || gsa.talker_id === 'GB');
|
||||
|
||||
try {
|
||||
let yAxis_data = [], series_data = []
|
||||
const in_positioning_id = get_in_positioning_id(GSAArr)
|
||||
|
||||
let yAxis_data = [], series_data = [];
|
||||
const in_positioning_id = get_in_positioning_id(GSAArr);
|
||||
GSVArr.forEach(({ satellites }) => {
|
||||
let compatibleVersion = false;
|
||||
if (satellites[satellites.length-1].elevationDeg == null && satellites[satellites.length-1].azimuthTrue == null && satellites[satellites.length-1].SNRdB == null) {
|
||||
compatibleVersion = true;
|
||||
let type = satellites.pop();
|
||||
if (type.id == 0 || type.id == 1) {
|
||||
compatibleVersion = false;
|
||||
}
|
||||
}
|
||||
if (!compatibleVersion) {
|
||||
satellites.forEach(({ id, SNRdB }) => {
|
||||
yAxis_data.push(id)
|
||||
yAxis_data.push(id);
|
||||
if (in_positioning_id.indexOf(parseInt(id)) < 0) {
|
||||
series_data.push([SNRdB, id, false])
|
||||
series_data.push([SNRdB, id, false]);
|
||||
} else {
|
||||
series_data.push([SNRdB, id, true])
|
||||
series_data.push([SNRdB, id, true]);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const SNROption = {
|
||||
@@ -62,52 +71,52 @@ const getSNROption = (nmea) => {
|
||||
series: [{
|
||||
data: series_data
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
return SNROption
|
||||
return SNROption;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const getPlanisphereOption = (nmea) => {
|
||||
if (!nmea) return
|
||||
if (!nmea) return;
|
||||
|
||||
const { GSV, GSA } = nmea
|
||||
const GSVArr = GSV.filter((gsv) => gsv.talker_id === 'BD')
|
||||
const GSAArr = GSA.filter((gsa) => gsa.talker_id === 'BD')
|
||||
const { GSV, GSA } = nmea;
|
||||
const GSVArr = GSV.filter((gsv) => gsv.talker_id === 'BD' || gsv.talker_id === 'GB');
|
||||
const GSAArr = GSA.filter((gsa) => gsa.talker_id === 'BD' || gsa.talker_id === 'GB');
|
||||
|
||||
try {
|
||||
let data = []
|
||||
const in_positioning_id = get_in_positioning_id(GSAArr)
|
||||
let data = [];
|
||||
const in_positioning_id = get_in_positioning_id(GSAArr);
|
||||
|
||||
GSVArr.forEach(({ satellites }) => {
|
||||
satellites.forEach(({ id, elevationDeg, azimuthTrue }) => {
|
||||
if (in_positioning_id.indexOf(parseInt(id)) < 0) {
|
||||
data.push([parseInt(elevationDeg), azimuthTrue, id, false])
|
||||
data.push([parseInt(elevationDeg), azimuthTrue, id, false]);
|
||||
} else {
|
||||
data.push([parseInt(elevationDeg), azimuthTrue, id, true])
|
||||
data.push([parseInt(elevationDeg), azimuthTrue, id, true]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const planisphereOption = {
|
||||
series: [{ data }]
|
||||
}
|
||||
};
|
||||
|
||||
return planisphereOption
|
||||
return planisphereOption;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const get_in_positioning_id = (GSAArr) => {
|
||||
let in_positioning_id = []
|
||||
let in_positioning_id = [];
|
||||
GSAArr.forEach(({ satellites }) => {
|
||||
in_positioning_id.push(...satellites)
|
||||
in_positioning_id.push(...satellites);
|
||||
});
|
||||
|
||||
return in_positioning_id
|
||||
}
|
||||
return in_positioning_id;
|
||||
};
|
||||
|
||||
export { getPosition, getBaseInfo, getSNROption, getPlanisphereOption }
|
||||
export { getPosition, getBaseInfo, getSNROption, getPlanisphereOption };
|
||||
@@ -1,28 +1,28 @@
|
||||
<template>
|
||||
<div>
|
||||
<SubTitleView :title="'基础信息'" />
|
||||
<div class="text-center text-2xl leading-loose text-blue-100">
|
||||
<div>
|
||||
<div class="text-center text-2xl leading-8 text-blue-100">
|
||||
<div class="box">
|
||||
<div class="label">经 度:</div>
|
||||
<div class="content">{{ baseInfo.longitude ? baseInfo.longitude : '' }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="box">
|
||||
<div class="label">纬 度:</div>
|
||||
<div class="content">{{ baseInfo.latitude ? baseInfo.latitude : '' }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="box">
|
||||
<div class="label">海 拔:</div>
|
||||
<div class="content">{{ baseInfo.altitude }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="box">
|
||||
<div class="label">日 期:</div>
|
||||
<div class="content">{{ baseInfo.date }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="box">
|
||||
<div class="label">UTC时间:</div>
|
||||
<div class="content">{{ baseInfo.UTCTime }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="box">
|
||||
<div class="label">北京时间:</div>
|
||||
<div class="content">{{ baseInfo.BJTime }}</div>
|
||||
</div>
|
||||
@@ -31,9 +31,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue'
|
||||
import SubTitleView from './SubTitleView.vue'
|
||||
import { getBaseInfo } from '../api/util'
|
||||
import { reactive, ref } from 'vue';
|
||||
import SubTitleView from './SubTitleView.vue';
|
||||
import { getBaseInfo } from '../api/util';
|
||||
|
||||
|
||||
let baseInfo = reactive({
|
||||
@@ -43,49 +43,55 @@ let baseInfo = reactive({
|
||||
date : '',
|
||||
UTCTime : '',
|
||||
BJTime : '',
|
||||
})
|
||||
});
|
||||
|
||||
let longitudeD = ref()
|
||||
let longitudeM = ref()
|
||||
let longitudeS = ref()
|
||||
let longitudeD = ref();
|
||||
let longitudeM = ref();
|
||||
let longitudeS = ref();
|
||||
|
||||
let latitudeD = ref()
|
||||
let latitudeM = ref()
|
||||
let latitudeS = ref()
|
||||
let latitudeD = ref();
|
||||
let latitudeM = ref();
|
||||
let latitudeS = ref();
|
||||
|
||||
const update = (nmea) => {
|
||||
const newBaseInfo = getBaseInfo(nmea)
|
||||
if (!newBaseInfo) return
|
||||
const newBaseInfo = getBaseInfo(nmea);
|
||||
|
||||
Object.assign(baseInfo, newBaseInfo)
|
||||
if (!newBaseInfo) return;
|
||||
|
||||
longitudeD.value = baseInfo.longitude.substring(0,baseInfo.longitude.indexOf("."))+'°'
|
||||
longitudeM.value = String((Number('0.'+baseInfo.longitude.substring(baseInfo.longitude.indexOf(".")+1,baseInfo.longitude.length))*60).toFixed(10)).substring(0,String((Number('0.'+baseInfo.longitude.substring(baseInfo.longitude.indexOf(".")+1,baseInfo.longitude.length))*60).toFixed(10)).indexOf("."))+'′'
|
||||
longitudeS.value = (Number('0.'+(Number('0.'+baseInfo.longitude.substring(baseInfo.longitude.indexOf(".")+1,baseInfo.longitude.length))*60).toFixed(10).substring(String((Number('0.'+baseInfo.longitude.substring(baseInfo.longitude.indexOf(".")+1,baseInfo.longitude.length))*60).toFixed(10)).indexOf(".")+1,((Number('0.'+baseInfo.longitude.substring(baseInfo.longitude.indexOf(".")+1,baseInfo.longitude.length))*60).toFixed(10)).length))*60).toFixed(6)+'″'
|
||||
Object.assign(baseInfo, newBaseInfo);
|
||||
|
||||
latitudeD.value = baseInfo.latitude.substring(0,baseInfo.latitude.indexOf("."))+'°'
|
||||
latitudeM.value = String((Number('0.'+baseInfo.latitude.substring(baseInfo.latitude.indexOf(".")+1,baseInfo.latitude.length))*60).toFixed(10)).substring(0,String((Number('0.'+baseInfo.latitude.substring(baseInfo.latitude.indexOf(".")+1,baseInfo.latitude.length))*60).toFixed(10)).indexOf("."))+'′'
|
||||
latitudeS.value = (Number('0.'+(Number('0.'+baseInfo.latitude.substring(baseInfo.latitude.indexOf(".")+1,baseInfo.latitude.length))*60).toFixed(10).substring(String((Number('0.'+baseInfo.latitude.substring(baseInfo.latitude.indexOf(".")+1,baseInfo.latitude.length))*60).toFixed(10)).indexOf(".")+1,((Number('0.'+baseInfo.latitude.substring(baseInfo.latitude.indexOf(".")+1,baseInfo.latitude.length))*60).toFixed(10)).length))*60).toFixed(6)+'″'
|
||||
}
|
||||
longitudeD.value = baseInfo.longitude.substring(0,baseInfo.longitude.indexOf("."))+'°';
|
||||
longitudeM.value = String((Number('0.'+baseInfo.longitude.substring(baseInfo.longitude.indexOf(".")+1,baseInfo.longitude.length))*60).toFixed(10)).substring(0,String((Number('0.'+baseInfo.longitude.substring(baseInfo.longitude.indexOf(".")+1,baseInfo.longitude.length))*60).toFixed(10)).indexOf("."))+'′';
|
||||
longitudeS.value = (Number('0.'+(Number('0.'+baseInfo.longitude.substring(baseInfo.longitude.indexOf(".")+1,baseInfo.longitude.length))*60).toFixed(10).substring(String((Number('0.'+baseInfo.longitude.substring(baseInfo.longitude.indexOf(".")+1,baseInfo.longitude.length))*60).toFixed(10)).indexOf(".")+1,((Number('0.'+baseInfo.longitude.substring(baseInfo.longitude.indexOf(".")+1,baseInfo.longitude.length))*60).toFixed(10)).length))*60).toFixed(6)+'″';
|
||||
|
||||
defineExpose({ update })
|
||||
latitudeD.value = baseInfo.latitude.substring(0,baseInfo.latitude.indexOf("."))+'°';
|
||||
latitudeM.value = String((Number('0.'+baseInfo.latitude.substring(baseInfo.latitude.indexOf(".")+1,baseInfo.latitude.length))*60).toFixed(10)).substring(0,String((Number('0.'+baseInfo.latitude.substring(baseInfo.latitude.indexOf(".")+1,baseInfo.latitude.length))*60).toFixed(10)).indexOf("."))+'′';
|
||||
latitudeS.value = (Number('0.'+(Number('0.'+baseInfo.latitude.substring(baseInfo.latitude.indexOf(".")+1,baseInfo.latitude.length))*60).toFixed(10).substring(String((Number('0.'+baseInfo.latitude.substring(baseInfo.latitude.indexOf(".")+1,baseInfo.latitude.length))*60).toFixed(10)).indexOf(".")+1,((Number('0.'+baseInfo.latitude.substring(baseInfo.latitude.indexOf(".")+1,baseInfo.latitude.length))*60).toFixed(10)).length))*60).toFixed(6)+'″';
|
||||
};
|
||||
|
||||
defineExpose({ update });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@layer components {
|
||||
.box {
|
||||
height: 2rem;
|
||||
margin-bottom: 0.6rem;
|
||||
}
|
||||
|
||||
.label {
|
||||
@apply float-left text-right w-2/5;
|
||||
min-width: 120px;
|
||||
height: 36px;
|
||||
min-width: 6rem;
|
||||
height: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.content {
|
||||
@apply float-left text-left w-3/5;
|
||||
min-width: 165px;
|
||||
height: 36px;
|
||||
/* min-height: 48px; */
|
||||
min-width: 6rem;
|
||||
height: 2rem;
|
||||
/* min-height: 2.4rem; */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import SubTitleView from './SubTitleView.vue'
|
||||
import { ref } from 'vue';
|
||||
import SubTitleView from './SubTitleView.vue';
|
||||
|
||||
const nmeaStr = ref('')
|
||||
const update = (value) => nmeaStr.value = value
|
||||
const nmeaStr = ref('');
|
||||
const update = (value) => nmeaStr.value = value;
|
||||
|
||||
defineExpose({ update })
|
||||
defineExpose({ update });
|
||||
</script>
|
||||
@@ -6,12 +6,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, onMounted } from "vue";
|
||||
import { use } from "echarts/core";
|
||||
import { CanvasRenderer } from "echarts/renderers";
|
||||
import { ScatterChart } from "echarts/charts";
|
||||
import { PolarComponent } from "echarts/components";
|
||||
import VChart from "vue-echarts";
|
||||
import { reactive } from "vue";
|
||||
import SubTitleView from './SubTitleView.vue'
|
||||
import { getPlanisphereOption } from '../api/util'
|
||||
|
||||
@@ -21,8 +21,8 @@ use([
|
||||
PolarComponent
|
||||
]);
|
||||
|
||||
const LOCATED_COLOR = '#e5323e'
|
||||
const UNLOCATED_COLOR = '#9ca3af'
|
||||
const LOCATED_COLOR = '#e5323e';
|
||||
const UNLOCATED_COLOR = '#9ca3af';
|
||||
|
||||
|
||||
const option = reactive({
|
||||
@@ -61,7 +61,8 @@ const option = reactive({
|
||||
symbolSize: 32,
|
||||
label: {
|
||||
show: true,
|
||||
formatter: '{@[2]}'
|
||||
formatter: '{@[2]}',
|
||||
fontSize: '14'
|
||||
},
|
||||
itemStyle: {
|
||||
color: ({ value }) => {
|
||||
@@ -69,18 +70,25 @@ const option = reactive({
|
||||
}
|
||||
}
|
||||
}]
|
||||
})
|
||||
});
|
||||
|
||||
const update = (nmea) => {
|
||||
const newOption = getPlanisphereOption(nmea)
|
||||
if (!newOption) return
|
||||
const newOption = getPlanisphereOption(nmea);
|
||||
|
||||
Object.assign(option, newOption)
|
||||
}
|
||||
if (!newOption) return;
|
||||
|
||||
Object.assign(option, newOption);
|
||||
};
|
||||
|
||||
const close = () => {
|
||||
window.ipcRenderer.send('CLOSE')
|
||||
}
|
||||
window.ipcRenderer.send('CLOSE');
|
||||
};
|
||||
|
||||
defineExpose({ update })
|
||||
defineExpose({ update });
|
||||
|
||||
onMounted(() => {
|
||||
// 获取屏幕高度
|
||||
const screenHeight = window.screen.height;
|
||||
option.series[0].label.fontSize = `${screenHeight / 100}`;
|
||||
});
|
||||
</script>
|
||||
@@ -6,11 +6,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, onMounted } from "vue";
|
||||
import { use, graphic } from "echarts/core";
|
||||
import { CanvasRenderer } from "echarts/renderers";
|
||||
import { BarChart } from "echarts/charts";
|
||||
import VChart from "vue-echarts";
|
||||
import { reactive } from "vue";
|
||||
import SubTitleView from './SubTitleView.vue'
|
||||
import { getSNROption } from '../api/util'
|
||||
|
||||
@@ -25,8 +25,8 @@ const LOCATED_COLOR = new graphic.LinearGradient(
|
||||
{offset: 0.3, color: '#83bff6'},
|
||||
{offset: 1, color: '#188df0'}
|
||||
]
|
||||
)
|
||||
const UNLOCATED_COLOR = '#9ca3af'
|
||||
);
|
||||
const UNLOCATED_COLOR = '#9ca3af';
|
||||
|
||||
const option = reactive({
|
||||
grid: {
|
||||
@@ -47,7 +47,7 @@ const option = reactive({
|
||||
inverse: true,
|
||||
axisLine: {show: false},
|
||||
axisTick: {show: false},
|
||||
axisLabel: {color: 'white', fontSize: '12'},
|
||||
axisLabel: {color: 'white', fontSize: '14'},
|
||||
},
|
||||
series: [{
|
||||
type: 'bar',
|
||||
@@ -65,14 +65,21 @@ const option = reactive({
|
||||
},
|
||||
barMaxWidth: 24
|
||||
}]
|
||||
})
|
||||
});
|
||||
|
||||
const update = (nmea) => {
|
||||
const newOption = getSNROption(nmea)
|
||||
if (!newOption) return
|
||||
const newOption = getSNROption(nmea);
|
||||
|
||||
Object.assign(option, newOption)
|
||||
}
|
||||
if (!newOption) return;
|
||||
|
||||
defineExpose({ update })
|
||||
Object.assign(option, newOption);
|
||||
};
|
||||
|
||||
defineExpose({ update });
|
||||
|
||||
onMounted(() => {
|
||||
// 获取屏幕高度
|
||||
const screenHeight = window.screen.height;
|
||||
option.yAxis.axisLabel.fontSize = `${screenHeight / 100}`;
|
||||
});
|
||||
</script>
|
||||
@@ -5,5 +5,5 @@
|
||||
<script lang="ts" setup>
|
||||
defineProps({
|
||||
title: String
|
||||
})
|
||||
});
|
||||
</script>
|
||||
@@ -1,11 +1,11 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import { createApp } from 'vue';
|
||||
import App from './App.vue';
|
||||
|
||||
import 'vue-cesium/dist/index.css'
|
||||
import { VcConfigProvider, VcViewer, VcEntity, VcLayerImagery, VcImageryProviderSingletile, VcGraphicsBillboard } from 'vue-cesium'
|
||||
import 'vue-cesium/dist/index.css';
|
||||
import { VcConfigProvider, VcViewer, VcEntity, VcLayerImagery, VcImageryProviderSingletile, VcGraphicsBillboard } from 'vue-cesium';
|
||||
|
||||
import './main.css'
|
||||
import './main.css';
|
||||
|
||||
const app = createApp(App)
|
||||
app.use(VcConfigProvider).use(VcViewer).use(VcEntity).use(VcLayerImagery).use(VcImageryProviderSingletile).use(VcGraphicsBillboard)
|
||||
app.mount('#app')
|
||||
const app = createApp(App);
|
||||
app.use(VcConfigProvider).use(VcViewer).use(VcEntity).use(VcLayerImagery).use(VcImageryProviderSingletile).use(VcGraphicsBillboard);
|
||||
app.mount('#app');
|
||||
Reference in New Issue
Block a user