<template>
	<div
		class="container flex-col"
		style="height: 100%;background-color: #ffffff"
	>
		<div class="container-header">
			<!-- 左侧开始 -->
			<a-breadcrumb style="margin-bottom: 10px">
				<a-breadcrumb-item>
					<router-link to="/sta">
						关联关系信息浏览
					</router-link>
				</a-breadcrumb-item>
				<a-breadcrumb-item>关联关系信息浏览统计</a-breadcrumb-item>
			</a-breadcrumb>

			<div>
				<fuzzy-search
					@selected="selectedEntity"
                    @enterSearch="enterSearch"
					key-id="entId"
					module-name="statisticalMap"
					url-name="getEntityListByStr"
					ref="fuzzySearch"
				></fuzzy-search>
				<!-- 左侧结束 -->

				<!-- 右侧-开始 -->
				<a-button
					title="选择一个实体后，方可展开"
					type="default"
					style="float: right"
					@click="openRightMenu"
					:disabled="isOpenRightMenu"
					>筛选
				</a-button>

				<!-- 右侧-显示选项 -->
				<a-dropdown style="float: right;margin-right: 5px;">
					<a-button
						class="ant-dropdown-link"
						@click="(e) => e.preventDefault()"
					>
						显示选项<a-icon type="down" />
					</a-button>
					<a-menu slot="overlay">
						<a-menu-item>
                            <a-switch checked-children="图谱形态-默认" un-checked-children="图谱形态-渐变" default-checked @click="colorChange"/>
						</a-menu-item>
						<a-menu-item>
                            <a-switch checked-children="拓扑形态-中心点" un-checked-children="拓扑形态-追加" default-checked @click="topChange"/>
						</a-menu-item>
						<a-menu-item>
							<a-switch
								v-model="showRelKey"
								checked-children="关系类名称"
								un-checked-children="关系名称"
								@change="onChange"
							/>
						</a-menu-item>
						<a-menu-item>
							<a href="javascript:;" @click="hideIcon">{{
								isShowIcon ? '隐藏图标' : '显示图标'
							}}</a>
						</a-menu-item>
						<a-menu-item>
							<a href="javascript:;" @click="downloadJson"
								>下载图数据</a
							>
						</a-menu-item>
                        <a-menu-item>
                            <a href="javascript:;" @click="exportDataToConsole">
                            导出数据到控制台</a
							>
                        </a-menu-item>
					</a-menu>
				</a-dropdown>

				<!-- 右侧-搜索历史 -->
				<a-badge
					:count="searchHistoryList.length"
					:numberStyle="{ backgroundColor: '#52c41a' }"
					style="float: right; margin-right: 5px;"
				>
					<a-dropdown placement="bottomLeft">
						<a-button>搜索历史<a-icon type="down"/></a-button>
						<a-menu slot="overlay" v-if="searchHistoryList.length">
							<a-menu-item
								v-for="menu in searchHistoryList"
								:key="menu.entId"
							>
								<a @click="redrawChart(menu.entId)">{{
									menu.entName
								}}</a>
							</a-menu-item>
							<a-menu-item v-if="searchHistoryList.length > 0">
								<a @click="clearHistory">清除搜索历史</a>
							</a-menu-item>
						</a-menu>
					</a-dropdown>
				</a-badge>

				<!-- 右侧-结束 -->
			</div>
		</div>
		<a-spin :spinning="spinning" style="height: 100%">
			<chart-comp
				ref="chart"
				@changeRoot="redrawChart"
				@c_click="getInfoTooltip"
				:isShowChart="true"
				:enable="true"
				@reloadChart="reloadChart"
				:showRelKey="showRelKey"
				:nodes="nodes"
				:links="links"
				:isEntChart="isEntChart"
				:contextMenu="['delete']"
				:isShowContextMenu="true"
				@delete="delNode"
			></chart-comp>
		</a-spin>
		<entity-details-tooltip
			class="chart_tooltip"
			ref="entityRef"
			:id="tooltip.entId"
			:key="tooltip.entId"
			v-if="tooltip.entId"
			style="position: absolute;z-index: 1;border-radius: 3px"
			:style="{ left: tooltip.x, top: tooltip.y }"
		></entity-details-tooltip>

		<!--v-show="tooltip.linkShow"-->
		<link-details-tooltip
			class="chart_tooltip"
			:id="tooltip.relID"
			:key="tooltip.relID"
			v-if="tooltip.relID"
			style="position: absolute;z-index: 1;border-radius: 3px"
			:style="{ left: tooltip.x, top: tooltip.y }"
		>
		</link-details-tooltip>
	</div>
</template>

<script>
import entityDetailsTooltip from '@/views/knowledge/common/entityDetails'
import linkDetailsTooltip from '@/views/knowledge/common/linkDetails'
import chartComp from '@/views/knowledge/common/chart'
import fuzzySearch from '@/views/knowledge/common/fuzzySearch'
import eventBus from '@/plugins/knowledge/eventBus'

import { getChart } from '@/api/graph/entity'

// 获取路径参数
function getQueryVariable(variable) {
	let url = window.location.hash
	let index = url.indexOf('?')
	var query = url.substring(index + 1, url.length)
	var vars = query.split('&')
	for (var i = 0; i < vars.length; i++) {
		var pair = vars[i].split('=')
		if (pair[0] == variable) {
			return pair[1]
		}
	}
	return ''
}

let directionsList = [
	{ label: '出度', value: 'OUT', checked: true },
	{ label: '入度', value: 'IN', checked: true },
]
export default {
	components: {
		fuzzySearch,
		entityDetailsTooltip,
		linkDetailsTooltip,
		chartComp,
	},
	data() {
		return {
			spinning: false,
			nodes: [],
			links: [],
			searchHistoryList: [], // 存储历史记录
			historyCache: [], // 存储历史ID记录的
			entityClassList: [], // 实体类列表
			linkClassList: [], // 关系类列表
			isOpenRightMenu: true,
			rootId: null, // 当前图谱的根节点
			tooltip: { entId: false, relID: false }, // 点击的实体或关系的悬浮层
			entityClassCache: undefined,
			linkClassCache: undefined,
			degreeCache: 1,
			directionCache: undefined,
			directionsList,
			showRelKey: true, // 图谱显示关系类还是关系名称
			json: null,
			isEntChart: false,
			isShowIcon: true,
            delEntIdsCache: undefined,
			delEntIds: [],

            chartType: true,//图表类型，center中心、add附加

            entName: '',
            ruleList: {}
		}
	},
	mounted() {
        this.rootId = getQueryVariable('entId')
        this.entName = decodeURI(getQueryVariable('entName'))
        
		if (this.entName) {
			this.$refs.fuzzySearch.value = this.entName
			this.isOpenRightMenu = false
		}
		if (this.rootId || (!this.rootId && !!this.entName)) {
			this.spinning = true
			this.getEntityList(
				this.rootId,
				this.degreeCache,
				this.entName
			).then((resp) => {
				let data = resp.data
				this.getJson(data)
				this.$refs.chart.drawChart(
					this.rootId,
					data.entListVO,
					data.relListVO
				)
				this.nodes = data.entListVO
				this.links = data.relListVO
				this.entityClassList = data.entClsListVO
				this.linkClassList = data.relClsListVO
				this.spinning = false
			})
		}
		const vm = this
		eventBus.eventBus.$on('graph:exportData', function() {
			vm.$refs.chart.exportChartData()
		})
	},
	destroyed() {
		eventBus.eventBus.$off('graph:exportData')
	},
	methods: {
        //以什么颜色显示zoomchart，默认橙色/颜色深浅渐变
        colorChange(){
            this.isEntChart=!this.isEntChart;
            this.redrawChart(this.rootId);
        },
        //拓扑-中心、追加
        topChange(){
            this.chartType=!this.chartType
        },
		/**
		 * 根据ID获取实力列表和关系列表
		 * @params id: 实体ID _string，
		 * @params degree： 度数（跳） _string，
         * delEntIds: 排除
         * direction：未知
         * entId：根节点id
         * entName：根节点名称
         * relClsIDs： 未知
         * limitNum：默认3
         * isModel: 默认false
         * entConditionQueries： 高级筛选
		 * */
		getEntityList(id,degree,name) {
            let entConditionQueries = []
            if(!!this.ruleList && JSON.stringify(this.ruleList)!='{}'){
                for(let k in this.ruleList){
                    let item={}
                    item.entClsID = k;
                    // item.entName = decodeURI(getQueryVariable('entName'));
                    let arr = this.ruleList[k]
                    let attrFilters = []
                    arr.forEach((v,i) => {
                        let innerItem = {
                            attrClsId: v.attrClsId,
                            attrValue: v.attrValue,
                            conditionType: v.conditionType,
                            operatorType: v.operatorType,
                            valueType: v.valueType
                        }
                        attrFilters.push(innerItem)
                    })
                    item['attrFilters']=attrFilters
                    entConditionQueries.push(item)
                }
            }
            
            let direction = ''
            if(!!this.directionCache && this.directionCache.split(',').length==2){
                direction = 'BOTH'
            }else{
                direction = this.directionCache;
            }
            
            
            let data = {
                degree: this.degreeCache,
                delEntIds: this.getDelEntIdsString(),
                direction: direction,
                entId: id,
                entName: name,
                relClsIDs: this.linkClassCache,
                limitNum: 3,
                isModel: false,
                entConditionQueries: entConditionQueries
            }

			// 根据搜索记录获取实力列表，以及实体类、关系类列表
			return getChart(data)
		},
        enterSearch(value){
            history.pushState(
				{},
				'',
				`#/sta?entName=${value}`
			)
            this.entName = value;
            this.getEntityList(undefined,this.degreeCache,value,this.entName).then(
				(data) => {
					this.getJson(data)
					this.isOpenRightMenu = false
					this.entityClassList = data.entClsListVO
					this.linkClassList = data.relClsListVO
					this.nodes = data.entListVO
					this.links = data.relListVO
					this.rootId = undefined
					this.$refs.chart.drawChart(
						undefined,
						data.entListVO,
						data.relListVO
					)
					this.spinning = false
				}
			)
        },
		/**
		 * 模糊搜索选中一个后执行的方法
		 * @params selected，模糊搜索选中的项
		 * */
		selectedEntity(selected) {
			// 更改路径不刷新页面
			history.pushState(
				{},
				'',
				`#/sta?entId=${selected.entId}&entName=${selected.entName}`
			)
            this.entName = selected.entName;
			if (this.historyCache.indexOf(selected.entId) === -1) {
				this.searchHistoryList.push(selected)
				this.historyCache.push(selected.entId)
			}
			this.spinning = true
			this.getEntityList(selected.entId, this.degreeCache,this.entName).then(
				(data) => {
					this.getJson(data)
					this.isOpenRightMenu = false
					this.entityClassList = data.entClsListVO
					this.linkClassList = data.relClsListVO
					this.nodes = data.entListVO
					this.links = data.relListVO
					this.rootId = selected.entId
					this.$refs.chart.drawChart(
						selected.entId,
						data.entListVO,
						data.relListVO
					)
					this.spinning = false
				}
			)
		},
		/**
		 * 清空历史记录
		 * */
		clearHistory() {
			this.searchHistoryList = []
			this.historyCache = []
		},
		/**
		 * 调用右侧菜单，传入实体类列表_entityClassList、关系类列表_relationClassList
		 * */
		openRightMenu() {
			if (this.entityClassCache !== undefined) {
				this.entityClassList.forEach((v) => {
					if (this.entityClassCache.indexOf(v.entClsID) > -1) {
						v.checked = true
					} else {
						v.checked = false
					}
				})
			}
			if (this.linkClassCache !== undefined) {
				this.linkClassList.forEach((v) => {
					if (this.linkClassCache.indexOf(v.relClsID) > -1) {
						v.checked = true
					} else {
						v.checked = false
					}
				})
			}
			if (this.directionCache !== undefined) {
				this.directionsList.forEach((v) => {
					if (this.directionCache.indexOf(v.value) > -1) {
						v.checked = true
					} else {
						v.checked = false
					}
				})
			}
            
			this.$open(
				'rightMenuDrawer',
				{
					entityClassList: this.entityClassList,
					linkClassList: this.linkClassList,
					degreeCache: this.degreeCache,
					directionList: this.directionsList,
                    ruleList: this.ruleList,
                    delEntityList: this.delEntIds
				},
				function(response) {
					if (response !== false) {
						this.spinning = true
						let _data = response.data ? response.data : {}
						this.entityClassCache = _data.entityIds  //参数
						this.linkClassCache = _data.linkIds  //参数
						this.degreeCache = _data.degree      //参数
						this.directionCache = _data.direction//方向参数
                        this.ruleList = _data.ruleList       //高级筛选
                        let entConditionQueries = []         //高级筛选-参数
                        let delEntIds = _data.delEntityIds   //被删除的id-参数

                        this.delEntIds = _data.delEntList
                        //高级筛选参数拼接
                        if(!!this.ruleList && JSON.stringify(this.ruleList)!='{}'){
                            for(let k in this.ruleList){
                                let item={}
                                item.entClsID = k;
                                // item.entName = decodeURI(getQueryVariable('entName'));
                                let arr = this.ruleList[k]
                                let attrFilters = []
                                arr.forEach((v,i) => {
                                    let innerItem = {
                                        attrClsId: v.attrClsId,
                                        attrValue: v.attrValue,
                                        conditionType: v.conditionType,
                                        operatorType: v.operatorType,
                                        valueType: v.valueType
                                    }
                                    attrFilters.push(innerItem)
                                })
                                item['attrFilters']=attrFilters
                                entConditionQueries.push(item)
                            }
                        }else{
                            if(!this.entityClassCache){
                                entConditionQueries=[]
                            }else{
                                this.entityClassCache.split(',').forEach(item => {
                                    let innerItem = {
                                        entClsID: item,
                                        attrFilters: []
                                    }
                                    entConditionQueries.push(innerItem)
                                })
                            }
                        }

                        //方向参数拼接，如果为 in，out，则为both
                        let direction = ''
                        if(!!this.directionCache && this.directionCache.split(',').length==2){
                            direction = 'BOTH'
                        }else{
                            direction = this.directionCache;
                        }

                        //高级搜索-----所有参数拼接
                        let data = {
                            degree: this.degreeCache,
                            delEntIds: delEntIds,
                            direction: direction,
                            entId: this.rootId,
                            entName: this.entName,
                            relClsIDs: this.linkClassCache,
                            limitNum: 3,
                            isModel: false,
                            entConditionQueries: entConditionQueries
                        }
                    
                        getChart(data).then(__data => {
                            this.getJson(__data)
							this.tooltip.entityShow = false
							this.tooltip.linkShow = false
							this.entityClassList = __data.entClsListVO
							this.linkClassList = __data.relClsListVO
							this.nodes = __data.entListVO
							this.links = __data.relListVO
							this.directionsList.forEach((v) => {
								v.checked = true
							})
							this.$refs.chart.reDraw(
								this.rootId,
								__data.entListVO,
								__data.relListVO
							)
							this.spinning = false
                        })
					}
				}
			)
		},
		reloadChart(nodes, links) {
			const id = getQueryVariable('entId')
			this.$refs.chart.drawChart(id, nodes, links)
		},
		/**
		 * 点击搜索历史重新绘图
		 * @params id 选中的实力的ID
		 * */
		redrawChart(id) {
			this.spinning = true
            if(this.chartType){
                this.getEntityList(id, this.degreeCache,this.entName).then((data) => {
                    this.rootId = id
                    this.tooltip.entId = false
                    this.tooltip.relID = false
                    this.$refs.fuzzySearch.clearSelected()
                    this.entityClassList = data.entClsListVO
                    this.linkClassList = data.relClsListVO
                    this.nodes = data.entListVO
                    this.links = data.relListVO
                    this.$refs.chart.reDraw(id, data.entListVO, data.relListVO)        
                    this.spinning = false
                })
            }else{
                //add
                if(id!=this.rootId){//中心点变更
                    this.getEntityList(id, this.degreeCache,this.entName).then((data) => {
                        let nodes = data.entListVO
                        let links = data.relListVO
                        let addNodes = nodes.filter(item =>{
                            return !this.nodes.some(c => {
                                return c.entId===item.entId
                            })
                        })
                        let addLinks = links.filter(item =>{
                            return !this.links.some(c => {
                                return c.relID===item.relID
                            })
                        })

                        this.nodes = [...this.nodes,...addNodes]
                        this.links = [...this.links,...addLinks]

                        this.$refs.chart.addDraw(id, addNodes, addLinks)
                        this.spinning = false
                    })
                }else{
                    //中心点不变
                    this.$refs.chart.reDraw(id, this.nodes, this.links)      
                    this.spinning = false  
                }  
            }
		},
		/**
		 * 获取实体或关系的悬浮框
		 * @params event:zoomchart返回的event，args：zoomchart返回的变量，包含了当前点击的实体或关系的数据
		 * */
		getInfoTooltip(event, args) {
			const vm = this
			this.$set(this.tooltip, 'x', event.pageX + 'px')
			this.$set(this.tooltip, 'y', event.pageY + 'px')
			if (args.clickNode) {
				vm.tooltip.entId = args.clickNode.data.entId
				vm.tooltip.relID = false
			} else if (args.clickLink) {
				vm.tooltip.entId = false
				vm.tooltip.relID = args.clickLink.data.relID
			} else {
				vm.tooltip.entId = false
				vm.tooltip.relID = false
			}
		},
		/**
		 * 切换图谱显示关系的名字，然后重绘图谱
		 * */
		onChange() {
			this.spinning = true
			this.getEntityList(
				this.rootId,
				this.degreeCache,
                this.entName,
				// this.entityClassCache,
				// this.linkClassCache,
				// this.directionCache
			).then((__data) => {
				this.tooltip.entityShow = false
				this.tooltip.linkShow = false
				this.entityClassList = __data.entClsListVO
				this.linkClassList = __data.relClsListVO
				this.nodes = __data.entListVO
				this.links = __data.relListVO
				this.directionsList.forEach((v) => {
					v.checked = true
				})
				this.$refs.chart.reDraw(
					this.rootId,
					__data.entListVO,
					__data.relListVO
				)
				this.spinning = false
			})
		},
		downloadJson() {
			if (JSON.stringify(this.json) == 'null') {
				this.$message.error('请选择关系类/实体类名称')
				return false
			}
			let datastr =
				'data:text/json;charset=utf-8,' +
				encodeURIComponent(JSON.stringify(this.json, null, '\t'))
			let downloadAnchorNode = document.createElement('a')
			downloadAnchorNode.setAttribute('href', datastr)
			downloadAnchorNode.setAttribute('download', '可视化.json')
			downloadAnchorNode.click()
			downloadAnchorNode.remove()
		},
		getJson(data) {
			const vm = this
			vm.json = {}
			vm.json['vertex'] = []
			vm.json['edge'] = []
			for (let i in data) {
				if (i === 'entListVO') {
					data[i].forEach(function(item) {
						let data = {}
						data['id'] = item.entId
						data['name'] = item.entName
						data['ent-cls-name'] = item.entClsName
						data['ent-cls-id'] = item.entClsID

						vm.json['vertex'].push(data)
					})
				}
				if (i === 'relListVO') {
					data[i].forEach(function(item) {
						let path = {}
						path['start-id'] = item.startEntID
						path['end-id'] = item.endEntID
						path['rel-cls-name'] = item.relClsName
						path['rel-cls-id'] = item.relClsID

						vm.json['edge'].push(path)
					})
				}
			}
		},
		hideIcon() {
			//隐藏图标
			this.isShowIcon = !this.isShowIcon
			this.$refs.chart.switchOPen()
		},
        getDelEntIdsString () {
            var res = []  
            this.delEntIds.forEach((v) => {
                res.push(v.id)
            })           
            return res.join(',')
        },
		// 选中一个图谱节点后的回调,排除
		delNode(item) {
			if (item[0].id == this.rootId) {
				this.$message.info('中心点不能删除')
				return
			}
            if(this.delEntIds.length>0){
                this.delEntIds.forEach((v,i) => {
                    if(v.id!==item[0].id){
                        this.delEntIds.push(item[0])
                    }
                })
            }else{
                this.delEntIds.push(item[0])
            }
			
			this.getEntityList(
					this.rootId,
					this.degreeCache,
                    this.entName
				)
				.then((res) => {
					this.entityClassList = res.entClsListVO
					this.linkClassList = res.relClsListVO
					this.$refs.chart.reDraw(
						this.rootId,
						res.entListVO,
						res.relListVO
					)
				})
		},
        exportDataToConsole() {
			eventBus.eventBus.$emit('graph:exportData')
		},
	},
}
</script>

<style></style>
