| | |
| | | <template> |
| | | <view class="pageBox"> |
| | | <!-- 顶部导航 --> |
| | | <headNav :idIndex="idIndex" text="中医地域医谱" /> |
| | | <headNav :idIndex="idIndex" text="中医地域医谱" style="z-index: 999" /> |
| | | <view |
| | | class="flex flex-center" |
| | | style="width: 100%; margin: 0.2rem 0 0.34rem; justify-content: flex-start" |
| | |
| | | placehold="输入姓名/别名/朝代/传主职业搜索" |
| | | @onSearch="onSearch" |
| | | :isAvancedTrue="false" |
| | | :keyword="keyword" |
| | | /> |
| | | <ul class="flex"> |
| | | <li style="" v-for="(item, index) in dynasty" :key="item.id"> |
| | |
| | | " |
| | | > |
| | | <view |
| | | class="" |
| | | :style="{ background: item.color }" |
| | | style=" |
| | | margin-right: 0.07rem; |
| | |
| | | border-radius: 50%; |
| | | " |
| | | ></view> |
| | | <view class="" style="color: #2c2c2c; font-size: 0.12rem">{{ |
| | | <view style="color: #2c2c2c; font-size: 0.12rem">{{ |
| | | item.name |
| | | }}</view> |
| | | </view> |
| | |
| | | >关闭</el-button |
| | | > |
| | | </div> |
| | | <view class="" style="overflow: auto; height: 2.5rem"> |
| | | <ul class="information" v-for="(item, index) in SearchArr" :key="index"> |
| | | <li style="font-size: 0.18rem; font-weight: 700">{{ item.name }}</li> |
| | | <li>生卒年: {{ item.birthAndDeath }}</li> |
| | | <li>来源: {{ item.source }}</li> |
| | | <view style="overflow: auto; height: 2.5rem"> |
| | | <ul |
| | | class="information" |
| | | v-for="(item, index) in SearchArr" |
| | | :key="index" |
| | | @click="showCard(item)" |
| | | > |
| | | <li style="font-size: 0.18rem; font-weight: 700"> |
| | | {{ item.name ? item.name : "-" }} |
| | | </li> |
| | | <li> |
| | | 生卒年: |
| | | {{ item.birthAndDeath ? item.birthAndDeath : "-" }} |
| | | </li> |
| | | <li>来源: {{ item.source ? item.source : "-" }}</li> |
| | | <li |
| | | v-if="SearchArr.length - 1 !== index" |
| | | style="margin: 0.1rem 0; border-bottom: 1px solid #d8d8d8" |
| | |
| | | <!-- echarts里面的数据点击后弹框 --> |
| | | <el-card |
| | | class="box-card echartsTrue" |
| | | v-if="isEchTrue" |
| | | v-show="isEchTrue" |
| | | style=" |
| | | overflow: inherit; |
| | | width: 3rem; |
| | |
| | | :style="{ top: isTop, left: isLeft }" |
| | | > |
| | | <div slot="header" class="clearfix"> |
| | | <span>{{ information[0].content }}</span> |
| | | <span v-if="currentMark">{{ |
| | | currentMark.name ? currentMark.name : "-" |
| | | }}</span> |
| | | <el-button |
| | | style=" |
| | | float: right; |
| | |
| | | >关闭</el-button |
| | | > |
| | | </div> |
| | | <ul class="information"> |
| | | <li v-for="(item, index) in information" :key="index"> |
| | | {{ item.label }}: {{ item.content }} |
| | | <ul class="information" v-if="currentMark"> |
| | | <li> |
| | | 姓名: |
| | | {{ currentMark.name ? currentMark.name : "-" }} |
| | | </li> |
| | | <li>别名: {{ currentMark.nikeName ? currentMark.nikeName : "-" }}</li> |
| | | <li> |
| | | 籍贯: {{ currentMark.nativePlace ? currentMark.nativePlace : "-" }} |
| | | </li> |
| | | <li>医学分科: {{ currentMark.barnch ? currentMark.barnch : "-" }}</li> |
| | | <li>小传: {{ currentMark.medical ? currentMark.medical : "-" }}</li> |
| | | </ul> |
| | | <el-button |
| | | class="flex" |
| | |
| | | >查看更多>></el-button |
| | | > |
| | | </el-card> |
| | | <!-- echarts地图 --> |
| | | <view id="main" style="width: 100vw; position: relative"></view> |
| | | |
| | | <div id="map"></div> |
| | | <!-- 朝代 --> |
| | | <view |
| | | class="flex flex-center" |
| | | style="width: 100%; position: fixed; bottom: 0.33rem; left: 0" |
| | | style=" |
| | | width: 100%; |
| | | position: fixed; |
| | | bottom: 0.33rem; |
| | | left: 0; |
| | | right: 0; |
| | | z-index: 99; |
| | | overflow: auto; |
| | | " |
| | | > |
| | | <ul class="flex"> |
| | | <li |
| | |
| | | class="flex flex-center" |
| | | style="height: 0.35rem; background-color: #fff; color: #244a7b" |
| | | > |
| | | {{ item.coord }} |
| | | {{ item.start }} |
| | | </view> |
| | | <view |
| | | class="flex flex-center font-family" |
| | | style=" |
| | | padding: 0.05rem 0.19rem; |
| | | min-width: 0.6rem; |
| | | height: 0.3rem; |
| | | line-height: 0.3rem; |
| | | text-align: center; |
| | | color: #fff; |
| | | font-size: 0.14rem; |
| | | margin-top: 0.03rem; |
| | |
| | | background: dynasty1Color == item.id ? '#244A7B' : '#597AA5' |
| | | }" |
| | | > |
| | | {{ item.name }} |
| | | {{ item.dynastyChs }} |
| | | </view> |
| | | </li> |
| | | </ul> |
| | |
| | | <!-- 5USVDAhhS4ssz44HLq3gNPZai7naXf4Q --> |
| | | <script> |
| | | import { loadBMap } from "@/static/map.js"; |
| | | import L from "leaflet"; |
| | | import "leaflet.chinatmsproviders"; |
| | | |
| | | import * as echarts from "echarts"; |
| | | import "echarts/extension/bmap/bmap"; |
| | | import { getRetrieval, getDynasty } from "@/api/index.js"; |
| | | export default { |
| | | data() { |
| | | return { |
| | | // echarts元素点击时出来的弹窗和坐标 |
| | | keyword: "", |
| | | isEchTrue: false, |
| | | isLeft: 0, |
| | | isTop: 0, |
| | |
| | | } |
| | | ], |
| | | // 下面的朝代1 |
| | | dynasty1Color: 1, |
| | | dynasty1Color: "", |
| | | dynasty1: [ |
| | | { |
| | | name: "夏朝", |
| | |
| | | // 朝代 |
| | | dynasty: [ |
| | | { |
| | | name: "夏朝", |
| | | name: "夏", |
| | | color: "#90BBD8", |
| | | id: 1 |
| | | }, |
| | | { |
| | | name: "商朝", |
| | | name: "商", |
| | | color: "#EDD28B", |
| | | id: 2 |
| | | }, |
| | |
| | | id: 3 |
| | | }, |
| | | { |
| | | name: "秦朝", |
| | | name: "秦", |
| | | color: "#9CC27A", |
| | | id: 4 |
| | | }, |
| | | { |
| | | name: "汉朝", |
| | | name: "汉", |
| | | color: "#5B6CB9", |
| | | id: 5 |
| | | }, |
| | | { |
| | | name: "隋朝", |
| | | name: "隋", |
| | | color: "#8860A8", |
| | | id: 6 |
| | | }, |
| | | { |
| | | name: "唐朝", |
| | | name: "唐", |
| | | color: "#DE8E66", |
| | | id: 7 |
| | | }, |
| | | { |
| | | name: "明", |
| | | color: "#DE8E66", |
| | | id: 8 |
| | | } |
| | | ], |
| | | // 搜索后是否显示弹框 |
| | | isSearch: false, |
| | | currentMark: null, |
| | | SearchArr: [ |
| | | { |
| | | id: 1, |
| | |
| | | }, |
| | | onLoad(options) { |
| | | this.idIndex = options.id; |
| | | console.log("optionsoptionsoptions", options.id); |
| | | }, |
| | | mounted() { |
| | | console.log("ss"); |
| | | // this.$nextTick(() => { |
| | | loadBMap("1NJdwrI1CfT6lrykVhDkmWgsO6O2bjQK").then(() => { |
| | | this.innt(); |
| | | }); |
| | | // }) |
| | | this.getDynastyList(); |
| | | |
| | | this.getDataList(); |
| | | }, |
| | | methods: { |
| | | getDynastyList() { |
| | | getDynasty().then((res) => { |
| | | this.dynasty1 = res.list; |
| | | }); |
| | | }, |
| | | showCard(info) { |
| | | const item = this.markerList.find((f) => f.id == info.id); |
| | | var latlng = L.latLng(item.yCoord, item.xCoord); |
| | | this.map.setView(latlng, 10); |
| | | }, |
| | | getDataList() { |
| | | getRetrieval({ keyword: this.keyword, dynasty: this.dynasty1Color }).then( |
| | | (res) => { |
| | | if (res.object) { |
| | | let markerList = []; |
| | | const listData = res.object.personList; |
| | | for (let i = 0; i < listData.length; i++) { |
| | | const item = listData[i]; |
| | | if (item.NATIVE_PLACE?.length > 0) { |
| | | item.NATIVE_PLACE.forEach((citem) => { |
| | | if (citem.xCoord && citem.yCoord) { |
| | | const currentDynasty = this.dynasty1.find( |
| | | (f) => f.id == item.PERIOD[0].content1 |
| | | ); |
| | | if (currentDynasty) { |
| | | item.dynastyInfo = currentDynasty; |
| | | } |
| | | markerList.push({ ...citem, ...item }); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | this.initMap(markerList); |
| | | this.SearchArr = markerList.map((item) => ({ |
| | | birthAndDeath: item?.BIRTH_YEAR[0]?.content1 |
| | | ? item?.BIRTH_YEAR[0]?.content1 + |
| | | "-" + |
| | | item?.DEATH_YEAR[0]?.content1 |
| | | : "-", |
| | | name: item?.NAME[0]?.content1, |
| | | source: "-", |
| | | id: item.id |
| | | })); |
| | | this.markerList = markerList; |
| | | } |
| | | } |
| | | ); |
| | | }, |
| | | //初始化地图 |
| | | initMap(markerList) { |
| | | this.isEchTrue = false; |
| | | if (this.map) { |
| | | this.map.remove(); |
| | | } |
| | | var map = L.map("map", { |
| | | preferCanvas: true, |
| | | attributionControl: false |
| | | }).setView([39.91667, 116.41667], 3); |
| | | |
| | | L.tileLayer |
| | | .chinaProvider("TianDiTu.Normal.Map", { |
| | | key: "76bc34ead7e30e663a4eded8aeaf5860", |
| | | maxZoom: 18, |
| | | minZoom: 3 |
| | | }) |
| | | .addTo(map); |
| | | let DefaultIcon1 = L.icon({ |
| | | iconUrl: this.icoName, |
| | | iconSize: [24, 41], // 图标的大小 【值1,值2】 为具体你自定义图标的尺寸,比如我图标尺寸是32×52,表示该图标:宽度32像素,高度:52像素,那么值1:就是32,值2:就是52 |
| | | iconAnchor: [24, 41], // 图标将对应标记点的位置 这个是重点, 【值1,值2】,值1:为图标坐标第一个值(即32)的一半,值2:为图标坐标第二个值(即52) |
| | | popupAnchor: [1, -24] // 该点是相对于iconAnchor弹出信息的位置 这个是我手动调出来的,文档默认原始值是[-1,-76],我是去一半值,取一半值调出来的 |
| | | }); |
| | | |
| | | let icon = L.divIcon({ |
| | | html: "<div class='map-circle-name '></div>", |
| | | iconSize: [80, 80], |
| | | className: "map-circle" |
| | | }); |
| | | this.map = map; |
| | | if (markerList.length) { |
| | | for (let i = 0; i < markerList.length; i++) { |
| | | const item = markerList[i]; |
| | | let currentClassName = "map-circle-name"; |
| | | switch (item.dynastyInfo.dynastyChs) { |
| | | case "夏": |
| | | currentClassName = "map-circle-xia"; |
| | | break; |
| | | case "商": |
| | | currentClassName = "map-circle-shang"; |
| | | break; |
| | | case "西周": |
| | | currentClassName = "map-circle-zhou"; |
| | | break; |
| | | case "秦": |
| | | currentClassName = "map-circle-qin"; |
| | | break; |
| | | case "汉": |
| | | currentClassName = "map-circle-han"; |
| | | break; |
| | | case "隋": |
| | | currentClassName = "map-circle-sui"; |
| | | break; |
| | | case "唐": |
| | | currentClassName = "map-circle-tang"; |
| | | break; |
| | | case "明": |
| | | currentClassName = "map-circle-ming"; |
| | | break; |
| | | } |
| | | let icon = L.divIcon({ |
| | | html: `<div class='${currentClassName} ripple'></div>`, |
| | | iconSize: [80, 80], |
| | | className: "map-circle" |
| | | }); |
| | | const temp_mark = L.marker([item.yCoord, item.xCoord], { |
| | | icon: icon |
| | | }).addTo(map); |
| | | temp_mark.on("click", (e) => { |
| | | this.isEchTrue = true; |
| | | this.currentMark = { |
| | | name: item?.WEAK_NAME[0]?.content1, |
| | | nikeName: item?.ALIAS[0]?.content2, |
| | | nativePlace: item?.content1, |
| | | barnch: item?.MEDICAL_BRANCH[0]?.content1, |
| | | medical: item?.MEDICAL_EXPERTISE[0]?.content1 |
| | | }; |
| | | this.$nextTick(() => { |
| | | this.isTop = |
| | | e.containerPoint.y - |
| | | document.querySelector(".echartsTrue").offsetHeight / 2 + |
| | | "px"; |
| | | this.isLeft = |
| | | e.containerPoint.x - |
| | | document.querySelector(".echartsTrue").offsetWidth / 2 + |
| | | "px"; |
| | | }); |
| | | }); |
| | | } |
| | | } |
| | | }, |
| | | |
| | | // 点击下面的朝代按钮 |
| | | dynastyBottomClick(id) { |
| | | console.log(id); |
| | | this.dynasty1Color = id; |
| | | this.getDataList(); |
| | | }, |
| | | onSearch(val) { |
| | | console.log(val); |
| | | // |
| | | this.isSearch = true; |
| | | this.keyword = val.text; |
| | | this.map.invalidateSize(); |
| | | |
| | | this.getDataList(); |
| | | }, |
| | | // 点击上面的朝代按钮 |
| | | SchoolClick(id) { |
| | | console.log(id); |
| | | }, |
| | | innt() { |
| | | this.$nextTick(() => { |
| | | var chartDom = document.getElementById("main"); |
| | | var myChart = echarts.init(chartDom); |
| | | var option; |
| | | |
| | | const data = [ |
| | | { |
| | | name: "海门", |
| | | value: [121.15, 31.89] |
| | | }, |
| | | { |
| | | name: "鄂尔多斯", |
| | | value: [109.781327, 39.608266] |
| | | }, |
| | | { |
| | | name: "招远", |
| | | value: [120.38, 37.35] |
| | | }, |
| | | { |
| | | name: "舟山", |
| | | value: [122.207216, 29.985295] |
| | | }, |
| | | { |
| | | name: "齐齐哈尔", |
| | | value: [123.97, 47.33] |
| | | } |
| | | ]; |
| | | option = { |
| | | title: { |
| | | text: "", |
| | | subtext: "", |
| | | sublink: "", |
| | | left: "center" |
| | | }, |
| | | tooltip: { |
| | | trigger: "item" |
| | | }, |
| | | bmap: { |
| | | center: [104.114129, 37.550339], |
| | | zoom: 5, |
| | | roam: true, |
| | | mapStyle: { |
| | | styleJson: [ |
| | | { |
| | | featureType: "water", |
| | | elementType: "all", |
| | | stylers: { |
| | | color: "#86a1ac" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "land", |
| | | elementType: "all", |
| | | stylers: { |
| | | color: "#f1d99d" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "railway", |
| | | elementType: "all", |
| | | stylers: { |
| | | visibility: "off" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "highway", |
| | | elementType: "all", |
| | | stylers: { |
| | | color: "#f1d99d" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "highway", |
| | | elementType: "labels", |
| | | stylers: { |
| | | visibility: "off" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "arterial", |
| | | elementType: "geometry", |
| | | stylers: { |
| | | color: "#f1d99d" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "arterial", |
| | | elementType: "geometry.fill", |
| | | stylers: { |
| | | color: "#f1d99d" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "poi", |
| | | elementType: "all", |
| | | stylers: { |
| | | visibility: "off" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "green", |
| | | elementType: "all", |
| | | stylers: { |
| | | visibility: "off" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "subway", |
| | | elementType: "all", |
| | | stylers: { |
| | | visibility: "off" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "manmade", |
| | | elementType: "all", |
| | | stylers: { |
| | | color: "#f1d99d" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "local", |
| | | elementType: "all", |
| | | stylers: { |
| | | color: "#f1d99d" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "local", |
| | | elementType: "labels", |
| | | stylers: { |
| | | visibility: "off" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "arterial", |
| | | elementType: "labels", |
| | | stylers: { |
| | | visibility: "off" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "boundary", |
| | | elementType: "all", |
| | | stylers: { |
| | | color: "#f1d99d" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "building", |
| | | elementType: "all", |
| | | stylers: { |
| | | color: "#f1d99d" |
| | | } |
| | | }, |
| | | { |
| | | featureType: "label", |
| | | elementType: "labels.text.fill", |
| | | stylers: { |
| | | color: "#000" |
| | | } |
| | | } |
| | | ] |
| | | } |
| | | }, |
| | | series: [ |
| | | { |
| | | name: "", |
| | | type: "scatter", |
| | | coordinateSystem: "bmap", |
| | | data: data, |
| | | symbolSize: 0, |
| | | encode: { |
| | | value: 2 |
| | | }, |
| | | label: { |
| | | formatter: "{b}", |
| | | position: "right", |
| | | show: false |
| | | }, |
| | | emphasis: { |
| | | label: { |
| | | show: true |
| | | } |
| | | } |
| | | }, |
| | | { |
| | | name: "", |
| | | type: "effectScatter", |
| | | coordinateSystem: "bmap", |
| | | data: data, |
| | | symbolSize: 20, |
| | | encode: { |
| | | value: 2 |
| | | }, |
| | | showEffectOn: "render", |
| | | rippleEffect: { |
| | | brushType: "stroke" |
| | | }, |
| | | label: { |
| | | formatter: "{b}", |
| | | position: "right", |
| | | show: false |
| | | }, |
| | | itemStyle: { |
| | | color: "#ec7b43", |
| | | shadowBlur: 10, |
| | | shadowColor: "#333" |
| | | }, |
| | | emphasis: { |
| | | scale: false |
| | | }, |
| | | zlevel: 1 |
| | | } |
| | | ] |
| | | }; |
| | | // 设置点击事件监听 |
| | | myChart.on("click", (params) => { |
| | | console.log(params.event.offsetX, params.event.offsetY); |
| | | if (params.componentType === "series") { |
| | | var dataName = params.data.name; // 获取点击的数据名称 |
| | | var dataValue = params.data.value; // 获取点击的数据值 |
| | | // 在这里可以根据需要处理点击事件,比如弹出对应数据的详细信息等操作 |
| | | console.log("点击了", dataName, "数据,数值为", dataValue); |
| | | // 这里可以编写触发时间获取对应数据信息的逻辑 |
| | | this.spaceTimeArr(params); |
| | | } |
| | | }); |
| | | |
| | | option && myChart.setOption(option); |
| | | }); |
| | | }, |
| | | // 时空地图点击时获取的数据 |
| | | spaceTimeArr(Arr) { |
| | | // 修改 Vue 组件的数据,例如显示菜单导航 |
| | | // 时空地图的数据 |
| | | console.log(Arr); |
| | | |
| | | this.isEchTrue = true; |
| | | this.$nextTick(() => { |
| | | this.isTop = |
| | | Arr.event.offsetY - |
| | | 0.18 - |
| | | document.querySelector(".echartsTrue").offsetHeight / 2.1 + |
| | | "px"; |
| | | this.isLeft = |
| | | Arr.event.offsetX - |
| | | document.querySelector(".echartsTrue").offsetWidth / 2.1 + |
| | | "px"; |
| | | console.log( |
| | | document.querySelector(".echartsTrue").offsetHeight / 2 / 100 |
| | | ); |
| | | }); |
| | | }, |
| | | SchoolClick(id) {}, |
| | | // 查看更多>> |
| | | viewMoreClick() { |
| | | uni.navigateTo({ |
| | |
| | | </script> |
| | | |
| | | <style> |
| | | ::v-deep .map-circle-name { |
| | | width: 20px; |
| | | height: 20px; |
| | | border-radius: 50%; |
| | | background-color: rgb(144, 187, 216); |
| | | } |
| | | ::v-deep .map-circle-xia { |
| | | width: 20px; |
| | | height: 20px; |
| | | border-radius: 50%; |
| | | background-color: rgb(144, 187, 216); |
| | | } |
| | | ::v-deep .map-circle-shang { |
| | | width: 20px; |
| | | height: 20px; |
| | | border-radius: 50%; |
| | | background-color: rgb(237, 210, 139); |
| | | } |
| | | ::v-deep .map-circle-zhou { |
| | | width: 20px; |
| | | height: 20px; |
| | | border-radius: 50%; |
| | | background-color: rgb(207, 116, 109); |
| | | } |
| | | ::v-deep .map-circle-qin { |
| | | width: 20px; |
| | | height: 20px; |
| | | border-radius: 50%; |
| | | background-color: rgb(156, 194, 122); |
| | | } |
| | | ::v-deep .map-circle-han { |
| | | width: 20px; |
| | | height: 20px; |
| | | border-radius: 50%; |
| | | background-color: rgb(91, 108, 185); |
| | | } |
| | | ::v-deep .map-circle-sui { |
| | | width: 20px; |
| | | height: 20px; |
| | | border-radius: 50%; |
| | | background-color: rgb(136, 96, 168); |
| | | } |
| | | ::v-deep .map-circle-tang { |
| | | width: 20px; |
| | | height: 20px; |
| | | border-radius: 50%; |
| | | background-color: rgb(136, 96, 168); |
| | | } |
| | | ::v-deep .map-circle-ming { |
| | | width: 20px; |
| | | height: 20px; |
| | | border-radius: 50%; |
| | | background-color: rgb(222, 142, 102); |
| | | } |
| | | |
| | | .pageBox { |
| | | width: 100%; |
| | | height: 100%; |
| | |
| | | line-height: 1; |
| | | margin-left: 0.19rem; |
| | | } |
| | | |
| | | #map { |
| | | height: 100%; |
| | | width: 100%; |
| | | margin: 0 auto; |
| | | font-size: 14px !important; |
| | | z-index: 10 !important; |
| | | } |
| | | |
| | | ::v-deep .ripple { |
| | | border-radius: 50%; |
| | | position: relative; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | ::v-deep .ripple::before { |
| | | content: ""; |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | width: 150%; /* Ensure it covers the entire parent */ |
| | | height: 150%; |
| | | background: rgba(255, 255, 255, 0.5); |
| | | border-radius: 50%; |
| | | transform: translate(-50%, -50%) scale(1); |
| | | animation: ripple-animation 1s infinite linear; |
| | | } |
| | | |
| | | @keyframes ripple-animation { |
| | | to { |
| | | transform: translate(-50%, -50%) scale(0); |
| | | opacity: 0; |
| | | } |
| | | } |
| | | </style> |