diff --git a/src/assets/images/map/noLocation.png b/src/assets/images/map/noLocation.png new file mode 100644 index 0000000..d81494c Binary files /dev/null and b/src/assets/images/map/noLocation.png differ diff --git a/src/assets/images/threeLeftNew/item-bg.png b/src/assets/images/threeLeftNew/item-bg.png new file mode 100644 index 0000000..ad009d6 Binary files /dev/null and b/src/assets/images/threeLeftNew/item-bg.png differ diff --git a/src/assets/images/threeLeftNew/item0.png b/src/assets/images/threeLeftNew/item0.png new file mode 100644 index 0000000..2359b2a Binary files /dev/null and b/src/assets/images/threeLeftNew/item0.png differ diff --git a/src/assets/images/threeLeftNew/item1.png b/src/assets/images/threeLeftNew/item1.png new file mode 100644 index 0000000..06246e0 Binary files /dev/null and b/src/assets/images/threeLeftNew/item1.png differ diff --git a/src/assets/images/threeLeftNew/item2.png b/src/assets/images/threeLeftNew/item2.png new file mode 100644 index 0000000..6b5490c Binary files /dev/null and b/src/assets/images/threeLeftNew/item2.png differ diff --git a/src/assets/images/threeLeftNew/item3.png b/src/assets/images/threeLeftNew/item3.png new file mode 100644 index 0000000..b0661ec Binary files /dev/null and b/src/assets/images/threeLeftNew/item3.png differ diff --git a/src/assets/images/threeLeftNew/item4.png b/src/assets/images/threeLeftNew/item4.png new file mode 100644 index 0000000..8e428b6 Binary files /dev/null and b/src/assets/images/threeLeftNew/item4.png differ diff --git a/src/assets/images/threeLeftNew/item5.png b/src/assets/images/threeLeftNew/item5.png new file mode 100644 index 0000000..aa706c1 Binary files /dev/null and b/src/assets/images/threeLeftNew/item5.png differ diff --git a/src/assets/images/threeLeftNew/item6.png b/src/assets/images/threeLeftNew/item6.png new file mode 100644 index 0000000..51ec582 Binary files /dev/null and b/src/assets/images/threeLeftNew/item6.png differ diff --git a/src/assets/img/mapIcon1-1.svg b/src/assets/img/mapIcon1-1.svg new file mode 100644 index 0000000..3915593 --- /dev/null +++ b/src/assets/img/mapIcon1-1.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/src/assets/img/mapIcon3.png b/src/assets/img/mapIcon3.png index 1b89f5f..fab6592 100644 Binary files a/src/assets/img/mapIcon3.png and b/src/assets/img/mapIcon3.png differ diff --git a/src/assets/mapUtils/commonFun.ts b/src/assets/mapUtils/commonFun.ts index ecdcb12..da7e3bc 100644 --- a/src/assets/mapUtils/commonFun.ts +++ b/src/assets/mapUtils/commonFun.ts @@ -1,4 +1,4 @@ -import { mapIcon1, mapIcon11, mapIcon4, mapIcon41, mapIcon5, mapIcon51, watchIconR } from '/@/components/chinaMap/chinaHooks.ts'; +import { mapIcon1, mapIcon11, mapIcon3, mapIcon4, mapIcon41, mapIcon5, mapIcon51, watchIconR } from '/@/components/chinaMap/chinaHooks.ts'; import * as turf from '@turf/turf'; /** @@ -20,22 +20,27 @@ export function createIcon({ icon, iconSize, imageSize }) { * @type 1:油田医院,2:健康小屋,4:AED */ export function typeToIcon(type: string) { - const iconSize = [28, 49]; - const imageSize = [28, 49]; + // const iconSize = [28, 49]; + // const imageSize = [28, 49]; if (type == '1') { - return createIcon({ icon: mapIcon1, iconSize, imageSize }); - } - if (type == '2') { - return createIcon({ icon: mapIcon5, iconSize, imageSize }); + // return createIcon({ icon: mapIcon1, iconSize, imageSize }); + return mapIcon1; } if (type == '3') { - return createIcon({ icon: mapIcon5, iconSize, imageSize }); + // return createIcon({ icon: mapIcon5, iconSize, imageSize }); + return mapIcon5; } if (type == '4') { - return createIcon({ icon: mapIcon4, iconSize, imageSize }); + // return createIcon({ icon: mapIcon4, iconSize, imageSize }); + return mapIcon4; + } + if (type == '5') { + // return createIcon({ icon: mapIcon3, iconSize, imageSize }); + return mapIcon3; } if (type === 'user') { - return createIcon({ icon: watchIconR, iconSize, imageSize }); + // return createIcon({ icon: watchIconR, iconSize, imageSize }); + return watchIconR; } } export function typeToIcon1(type: string) { @@ -44,15 +49,15 @@ export function typeToIcon1(type: string) { if (type == '1') { return createIcon({ icon: mapIcon11, iconSize, imageSize }); } - if (type == '2') { - return createIcon({ icon: mapIcon51, iconSize, imageSize }); - } if (type == '3') { return createIcon({ icon: mapIcon51, iconSize, imageSize }); } if (type == '4') { return createIcon({ icon: mapIcon41, iconSize, imageSize }); } + if (type == '5') { + return createIcon({ icon: mapIcon3, iconSize, imageSize }); + } if (type === 'user') { const iconS = [36, 88]; const imageS = [36, 88]; diff --git a/src/assets/mapUtils/map.ts b/src/assets/mapUtils/map.ts index 34c4bbf..399f8cc 100644 --- a/src/assets/mapUtils/map.ts +++ b/src/assets/mapUtils/map.ts @@ -22,7 +22,6 @@ export const Map = { emergencyMarker: null, // 应急人员marker startMarker: null, endMarker: null, - clearSOrE: null, /** * @desc 地图舒适化 * @param el dom元素 id选择器 @@ -140,6 +139,70 @@ export const Map = { * @param computedCenter 是否计算中心点 */ createOverlay(result: ResultType[], extData?: ExtDataType, callback?: Callback, computedCenter?: boolean, iconType?: string) { + this.removeOverlayGroup(); + this.overlayGroup = new AMap.OverlayGroup(); + // const list: any[] = getLonLat(result); + // const center = getCenter(list); + // const zoom = getZoom(list); + let arr: any[] = []; + for (let i = 0; i < result.length; i++) { + let { type, lon, lat, longitude, latitude, lng, centerResource } = result[i]; + + if (longitude) { + lon = longitude; + } + if (latitude) { + lat = latitude; + } + if (lng) { + lon = lng; + } + if (!lon || !lat || !type) { + continue; + } + // 创建一个 Icon + let startIcon = typeToIcon1(type); + // 将 icon 传入 marker + let startMarker = new AMap.Marker({ + // 点的坐标 + position: [lon, lat], // 指定点的icon,也可以是个url ,但这样就不能对图片进行设置了 + icon: startIcon, //启用点击事件 如果需要点击事件,必须开启 + clickable: true, //点额外携带的数据,用户自定义属性,支持JavaScript API任意数据类型 + offset: [-18, -32], + maxZoom: 14, + extData: result[i], + label: { + content: isFunction(extData?.content) && extData?.content(result[i]), + }, + ...extData?.extOption, + }); + arr.push(startMarker); + // 可以调用setExtData()设置自定义属性 + //将组 挂载到地图上 + this.overlayGroup && this.overlayGroup.setMap(this.map); + //将需要批量控制的点放到一个组中,通过控制组,就可以操作组内所有所有覆盖物 + this.overlayGroup && this.overlayGroup.addOverlay(startMarker); + } + + this.overlayGroup && + this.overlayGroup.on('click', function (e: any) { + //拿到点中携带的数据 + if (!isFunction(callback)) return; + callback(e.target.getExtData()); + }); + if (computedCenter) { + this.map && this.map.setFitView(arr, false, [50, 50, 0, 50]); + } + return arr; + }, + /** + * @desc 创建覆盖物组,用于批量处理点 (控制显隐,点击事件等) + * @param result + * @param extData + * @param callback + * @param computedCenter 是否计算中心点 + */ + async createOverlay1(result: ResultType[], extData?: ExtDataType, callback?: Callback, computedCenter?: boolean, iconType?: string) { this.removeOverlayGroup(); this.overlayGroup = new AMap.OverlayGroup(); const list: any[] = getLonLat(result); @@ -148,6 +211,49 @@ export const Map = { if (computedCenter) { this.setZoomCenter(center, zoom); } + function createTextOverlayIcon(originalIconUrl, text, options = {}) { + return new Promise((resolve) => { + const canvas = document.createElement('canvas'); + const ctx = canvas.getContext('2d'); + const img = new Image(); + + img.crossOrigin = 'anonymous'; + img.onload = function () { + // 设置画布大小(比原图稍大以容纳文字) + canvas.width = 28; + canvas.height = 49 + 15; // 为文字留出空间 + + // 绘制原始图标 + ctx.drawImage(img, 0, 10, 28, 49); + // 绘制圆形文字背景 + const textX = 22; // 文字X坐标(居右对齐) + + const textY = 11; // 文字Y坐标 + const textWidth = ctx.measureText(text).width; + const circleRadius = Math.max(textWidth / 2 + 1, 6); // 根据文字宽度计算半径 + + ctx.beginPath(); + ctx.arc(textX, textY, circleRadius, 0, Math.PI * 2); + ctx.fillStyle = 'red'; + ctx.fill(); + + // 绘制文字背景(可选) + // ctx.fillStyle = 'red'; + // ctx.fillRect(0, 0, 28, 15); + + // 绘制文字 + ctx.font = `bold 10px Arial`; + ctx.textAlign = 'right'; + ctx.textBaseline = 'middle'; + ctx.fillStyle = '#ffffff'; + ctx.fillText(text, 25, 10); + + resolve(canvas.toDataURL()); + }; + + img.src = originalIconUrl; + }); + } let arr = []; for (let i = 0; i < result.length; i++) { let { type, lon, lat, longitude, latitude, lng, centerResource } = result[i]; @@ -165,12 +271,13 @@ export const Map = { continue; } // 创建一个 Icon - let startIcon = iconType === '1' ? typeToIcon(type) : typeToIcon1(type); + const startIcon: any = typeToIcon(type); + const newIconUrl = await createTextOverlayIcon(startIcon, i + 1 + ''); // 将 icon 传入 marker - let startMarker = new AMap.Marker({ + const startMarker = new AMap.Marker({ // 点的坐标 position: [lon, lat], // 指定点的icon,也可以是个url ,但这样就不能对图片进行设置了 - icon: startIcon, //启用点击事件 如果需要点击事件,必须开启 + icon: newIconUrl, //启用点击事件 如果需要点击事件,必须开启 clickable: true, //点额外携带的数据,用户自定义属性,支持JavaScript API任意数据类型 offset: [-18, -32], maxZoom: 14, diff --git a/src/components/secondaryScreen/secondMap/secondMap.vue b/src/components/secondaryScreen/secondMap/secondMap.vue index 64b5dd7..10d9cfb 100644 --- a/src/components/secondaryScreen/secondMap/secondMap.vue +++ b/src/components/secondaryScreen/secondMap/secondMap.vue @@ -15,6 +15,7 @@ :style="{ cursor: item.key == 'allotDeviceNum' ? 'pointer' : 'default', }" + :key="`footer-list-${item.key}`" class="col-item nowrap" @click="openWatchList(item)" > @@ -35,10 +36,10 @@ class="footer-dialog-con" style="--moveUp: 20px; --moveDown: -180px" > - + - + diff --git a/src/views/indexSun/threeLeftNew.vue b/src/views/indexSun/threeLeftNew.vue new file mode 100644 index 0000000..31828d9 --- /dev/null +++ b/src/views/indexSun/threeLeftNew.vue @@ -0,0 +1,468 @@ + + + + 心血管监测 + + + + + 全部数据 + + + + + + + {{ item.label }} + + + + + + + + + + {{ tabList[chooseType].label }} + 参考范围: {{ tabList[chooseType].tips }} + + + + + + + + + + + + + + + + + + + + + diff --git a/src/views/indexSun/threeLeftNewItem/item-d.vue b/src/views/indexSun/threeLeftNewItem/item-d.vue new file mode 100644 index 0000000..c36b1d4 --- /dev/null +++ b/src/views/indexSun/threeLeftNewItem/item-d.vue @@ -0,0 +1,120 @@ + + + + + 总人数 + {{ userCount }} + + + + + diff --git a/src/views/indexSun/threeLeftNewItem/pieCharts.ts b/src/views/indexSun/threeLeftNewItem/pieCharts.ts new file mode 100644 index 0000000..0f6de53 --- /dev/null +++ b/src/views/indexSun/threeLeftNewItem/pieCharts.ts @@ -0,0 +1,97 @@ +// 步数 +import { visibleChartLabel } from '/@/utils/utils.ts'; + +export function screenPie(chartData) { + const data = visibleChartLabel(chartData).map((item) => { + // item = { ...item, label: { show: item.value > 0 }, labelLine: { show: item.value > 0 } }; + return item; + }); + return { + color: ['#B750BE', '#6C63F0', '#3AACFF', '#ED589D', '#FB466C'], + tooltip: { + trigger: 'item', + show: true, + textStyle: { + color: '#fff', + }, + backgroundColor: 'rgba(50,50,50,0.7)', + borderColor: '#1b7ef2', + }, + series: [ + { + type: 'pie', + radius: ['50%', '72%'], + center: ['50%', '50%'], + avoidLabelOverlap: false, + label: { + show: true, + position: 'outside', + formatter: function (params: any) { + return `${params.name}\n占比:${params.percent}%\n人次:${params.value}次`; + }, + color: '#ffffff', + fontSize: 14, + }, + labelLine: { + show: true, + length: 2, + length2: 30, + minTurnAngle: 120, + }, + data: data, + }, + ], + }; +} + +//左侧圆 +export function circleRing(chartData, total, color) { + const data = visibleChartLabel(chartData); + return { + color: color, + tooltip: { + trigger: 'item', + show: true, + textStyle: { + color: '#fff', + }, + backgroundColor: 'rgba(50,50,50,0.7)', + borderColor: '#1b7ef2', + }, + series: [ + { + type: 'pie', + radius: ['50%', '75%'], + center: ['50%', '50%'], + avoidLabelOverlap: false, + // label: { + // show: true, + // // position: 'inner', + // formatter: '{d}%', + // color: '#ffffff', + // fontSize: 14, + // }, + // labelLine: { + // show: false, + // }, + label: { + show: true, + position: 'outside', + // formatter: '{a}{d}%\n{c}人次', + formatter: function (params: any) { + return `${params.name}:${params.percent}%\n${params.value}次`; + }, + color: '#ffffff', + fontSize: 14, + }, + labelLine: { + show: true, + length: 2, + length2: 30, + minTurnAngle: 120, + }, + data: data, + }, + ], + }; +} diff --git a/src/views/indexSun/threeLeftNewItem/sleepItem.vue b/src/views/indexSun/threeLeftNewItem/sleepItem.vue new file mode 100644 index 0000000..86ee37e --- /dev/null +++ b/src/views/indexSun/threeLeftNewItem/sleepItem.vue @@ -0,0 +1,112 @@ + + + + + 平均睡眠 {{ nums.avg || 0 }} 深睡 {{ nums.avgLong || 0 }} 浅睡 {{ nums.avgShort || 0 }} + + + + + + + diff --git a/src/views/indexSun/threeLeftNewItem/stepItem.vue b/src/views/indexSun/threeLeftNewItem/stepItem.vue new file mode 100644 index 0000000..7735f5a --- /dev/null +++ b/src/views/indexSun/threeLeftNewItem/stepItem.vue @@ -0,0 +1,105 @@ + + + + + 总人数 + {{ total }} + + + + + diff --git a/src/views/indexSun/threeLeftNewItem/threeLeftNewItem.vue b/src/views/indexSun/threeLeftNewItem/threeLeftNewItem.vue new file mode 100644 index 0000000..c6bca94 --- /dev/null +++ b/src/views/indexSun/threeLeftNewItem/threeLeftNewItem.vue @@ -0,0 +1,129 @@ + + + +r + + + + diff --git a/src/views/indexSun/rowNewR.data.ts b/src/views/indexSun/twoNewR.data.ts similarity index 100% rename from src/views/indexSun/rowNewR.data.ts rename to src/views/indexSun/twoNewR.data.ts diff --git a/src/views/indexSun/rwoNewR.vue b/src/views/indexSun/twoNewR.vue similarity index 99% rename from src/views/indexSun/rwoNewR.vue rename to src/views/indexSun/twoNewR.vue index 2dd2491..00cf034 100644 --- a/src/views/indexSun/rwoNewR.vue +++ b/src/views/indexSun/twoNewR.vue @@ -56,7 +56,7 @@ import { twoRNApi } from '/@/views/indexSun/indexSun.api.ts'; import dayjs from 'dayjs'; import { Row, Col } from 'ant-design-vue'; - import { getName, list } from '/@/views/indexSun/rowNewR.data.ts'; + import { getName, list } from '/@/views/indexSun/twoNewR.data.ts'; const { themeType } = useTheme(); const step = ref(0.2);