Echarts+D3气泡图(相邻效果,气泡之间不叠加)
<template><div ref="chart" style="width: 500px; height: 500px"></div>
</template><script setup>
import * as echarts from 'echarts/core'
import { DatasetComponent, TooltipComponent, VisualMapComponent } from 'echarts/components'
import { CustomChart } from 'echarts/charts'
import { CanvasRenderer } from 'echarts/renderers'
echarts.use([DatasetComponent, TooltipComponent, VisualMapComponent, CustomChart, CanvasRenderer])
import * as d3 from 'd3'
import { ref, onMounted } from 'vue'const chart = ref(null)const colorList = ['#5470c6','#91cc75','#fac858','#ee6666','#73c0de','#3ba272','#fc8452','#9a60b4','#ea7ccc'
]let option = {}
let seriesData = [{depth: 1,id: 'city',index: 0,value: 2},{depth: 1,id: 'city.孝感',index: 6,value: 6},{depth: 1,id: 'city.武汉',index: 1,value: 36},{depth: 1,id: 'city.荆州',index: 2,value: 26},{depth: 1,id: 'city.咸宁',index: 3,value: 16},{depth: 1,id: 'city.仙桃',index: 4,value: 6},{depth: 1,id: 'city.潜江',index: 5,value: 10},{depth: 1,id: 'city.十堰',index: 6,value: 8}
]let displayRoot = stratify1()function stratify1() {return d3.stratify().parentId(function (d) {return d.id.substring(0, d.id.lastIndexOf('.'))})(seriesData).sum(function (d) {return d.value || 0}).sort(function (a, b) {return b.value - a.value})
}function overallLayout(params, api) {let context = params.contextd3.pack().size([api.getWidth() - 2, api.getHeight() - 2]).padding(0)(displayRoot)context.nodes = {}displayRoot.descendants().forEach(function (node) {context.nodes[node.id] = node})
}function renderItem(params, api) {let context = params.contextlet idx = params.dataIndexif (!context.layout) {context.layout = trueoverallLayout(params, api)}let nodePath = api.value('id')let nodeName = nodePath.slice(nodePath.lastIndexOf('.') + 1).split(/(?=[A-Z][^A-Z])/g).join('\n')let node = context.nodes[nodePath]if (node.id === 'city') {node.r = 0}if (!node) {return}let colorTop = colorList[idx % colorList.length]let colorBottom = colorList[(idx + 1) % colorList.length]let linearGradient = new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: colorTop },{ offset: 1, color: colorBottom }])let z2 = api.value('depth') * 2return {type: 'circle',shape: {cx: node.x,cy: node.y,r: node.r},z2: z2,textContent: {type: 'text',style: {text: nodeName,fill: '#fff',fontFamily: 'Arial',width: node.r * 1.3,overflow: 'truncate',fontSize: node.r / 3},emphasis: {style: {overflow: null,fontSize: Math.max(node.r / 3, 12)}}},textConfig: {position: 'inside'},style: {fill: linearGradient},emphasis: {style: {fontFamily: 'Arial',fontSize: 12,shadowBlur: 20,shadowOffsetX: 3,shadowOffsetY: 5,shadowColor: 'rgba(0,0,0,0.3)'}}}
}option = {dataset: {source: seriesData},tooltip: {},hoverLayerThreshold: Infinity,series: [{type: 'custom',colorBy: 'data',renderItem: renderItem,progressive: 0,coordinateSystem: 'none',encode: {tooltip: 'value',itemName: 'id'}}]
}const initEcharts = () => {const myChart = echarts.init(chart.value)myChart.setOption(option)
}onMounted(() => {initEcharts()
})
</script>