diff --git a/dist.zip b/dist.zip new file mode 100644 index 0000000..15078c0 Binary files /dev/null and b/dist.zip differ diff --git a/src/components/bar/3DIndex.vue b/src/components/bar/3DIndex.vue index 945dd48..7eed67f 100644 --- a/src/components/bar/3DIndex.vue +++ b/src/components/bar/3DIndex.vue @@ -9,11 +9,8 @@ export default { name: 'JilinCityBar', props: { - chartHeight: { type: String, default: '220px' }, - interval: { type: Number, default: 2500 }, // 滚动间隔(ms) - districtName: { type: String, default: null }, // 当前选中的区县 - districtData: { type: Object, default: () => ({}) }, // 区县数据 - dataType: { type: String, default: 'patents' } // 数据类型:patents(专利数量)、research(研究机构)、conversion(转化数量) + chartHeight: {type: String, default: '220px'}, + interval: {type: Number, default: 2500} // 滚动间隔(ms) }, data() { return { @@ -21,65 +18,25 @@ export default { timer: null, pageSize: 4, cursor: 0, - - // 默认数据,当没有提供区县数据时使用 - defaultXData: [ - '朝阳区', '南关区', '宽城区', '二道区', - '绿园区', '双阳区', '九台区', '农安县' + + /* —— 数据 —— */ + xData: [ + '长春市', '吉林市', '四平市', '辽源市', + '通化市', '白山市', '松原市', '白城市', '延边自治州' ], - defaultValues: [220, 180, 190, 170, 185, 120, 140, 130] + values: [22, 10, 120, 2222, 1111, 3333, 123, 871, 61] }; }, - computed: { - // 根据props计算实际要显示的数据 - xData() { - return Object.keys(this.districtData).length > 0 ? Object.keys(this.districtData) : this.defaultXData; - }, - values() { - if (Object.keys(this.districtData).length === 0) { - return this.defaultValues; - } - - // 根据dataType选择要显示的数据类型 - return this.xData.map(district => { - if (this.districtData[district]) { - return this.districtData[district][this.dataType] || 0; - } - return 0; - }); - }, - // 图表标题 - chartTitle() { - switch(this.dataType) { - case 'research': - return '研究机构数量'; - case 'conversion': - return '专利转化数量'; - default: - return '专利数量'; - } - }, - // 高亮的区县索引 - highlightIndex() { - return this.districtName ? this.xData.indexOf(this.districtName) : -1; - } - }, watch: { - chartHeight() { - this.myChart && this.myChart.resize(); - }, - districtName() { - this.updateChart(); - }, - dataType() { - this.updateChart(); + chartHeight() { + this.myChart && this.myChart.resize(); } }, - mounted() { - this.initChart(); + mounted() { + this.initChart(); }, - beforeDestroy() { - clearInterval(this.timer); + beforeDestroy() { + clearInterval(this.timer); }, methods: { @@ -89,9 +46,9 @@ export default { const g = this.$echarts.graphic; const L = g.extendShape({ - shape: { x: 0, y: 0 }, + shape: {x: 0, y: 0}, buildPath(ctx, s) { - const { x, y, xAxisPoint } = s; + const {x, y, xAxisPoint} = s; ctx.moveTo(x + dx, y) .lineTo(x - 9 + dx, y - 9) .lineTo(xAxisPoint[0] - 9 + dx, xAxisPoint[1] - 9) @@ -100,9 +57,9 @@ export default { } }); const R = g.extendShape({ - shape: { x: 0, y: 0 }, + shape: {x: 0, y: 0}, buildPath(ctx, s) { - const { x, y, xAxisPoint } = s; + const {x, y, xAxisPoint} = s; ctx.moveTo(x + dx, y) .lineTo(xAxisPoint[0] + dx, xAxisPoint[1]) .lineTo(xAxisPoint[0] + 12 + dx, xAxisPoint[1] - 6) @@ -111,9 +68,9 @@ export default { } }); const T = g.extendShape({ - shape: { x: 0, y: 0 }, + shape: {x: 0, y: 0}, buildPath(ctx, s) { - const { x, y } = s; + const {x, y} = s; ctx.moveTo(x + dx, y) .lineTo(x + 12 + dx, y - 6) .lineTo(x + 3 + dx, y - 15) @@ -121,9 +78,9 @@ export default { .closePath(); } }); - g.registerShape('CubeLeft', L); + g.registerShape('CubeLeft', L); g.registerShape('CubeRight', R); - g.registerShape('CubeTop', T); + g.registerShape('CubeTop', T); }, /* ---------- 初始化 ---------- */ @@ -133,80 +90,30 @@ export default { this.render(); // 首次渲染 if (this.xData.length > this.pageSize) this.startScroll(); }, - - /* ---------- 更新图表 ---------- */ - updateChart() { - if (this.myChart) { - // 停止自动滚动 - clearInterval(this.timer); - - // 如果有选中的区县,确保它在视图中 - if (this.highlightIndex >= 0) { - // 计算滚动位置,使选中的区县在视图中 - const startIdx = Math.max(0, Math.min(this.highlightIndex, this.xData.length - this.pageSize)); - this.cursor = startIdx; - - this.myChart.setOption({ - dataZoom: [{ - startValue: startIdx, - endValue: startIdx + this.pageSize - 1 - }] - }); - } - - // 更新图表数据 - this.myChart.setOption({ - xAxis: [{ - data: this.xData - }], - series: [ - { - data: this.values, - itemStyle: { - color: (params) => { - // 如果是当前选中的区县,使用高亮颜色 - if (this.highlightIndex === params.dataIndex) { - return '#FFE777'; // 高亮黄色 - } - return undefined; // 使用默认颜色 - } - } - }, - { - data: this.values - } - ] - }); - - // 重新启动自动滚动 - if (this.xData.length > this.pageSize) this.startScroll(); - } - }, /* ---------- 配置 & 渲染 ---------- */ render() { const TEAL_LIGHT = '#86F3CE'; - const TEAL_DEEP = '#1EAF9A'; - const HIGHLIGHT_COLOR = '#FFE777'; // 高亮颜色 + const TEAL_DEEP = '#1EAF9A'; const option = { backgroundColor: 'transparent', animationDurationUpdate: 600, animationEasingUpdate: 'cubicOut', - grid: { left: 30, right: 30, bottom: 20, top: 40, containLabel: true }, + grid: {left: 30, right: 30, bottom: 20, top: 40, containLabel: true}, tooltip: { trigger: 'axis', - axisPointer: { type: 'shadow' }, + axisPointer: {type: 'shadow'}, formatter: d => `${d[0].axisValue}
- - ${this.chartTitle} ${d[0].value}` + + 数量 ${d[0].value}` }, legend: { - data: [{ name: this.chartTitle, itemStyle: {color: TEAL_LIGHT}}], + data: [{name: '数量', itemStyle: {color: TEAL_LIGHT}}], textStyle: {fontSize: 14, color: '#A7C4F6'}, itemWidth: 10, itemHeight: 8, top: '1%', right: '3%' }, @@ -239,17 +146,10 @@ export default { series: [ { type: 'custom', - name: this.chartTitle, + name: '数量', renderItem: (p, api) => { const loc = api.coord([api.value(0), api.value(1)]); const axis = api.coord([api.value(0), 0]); - - // 确定颜色 - 如果是高亮项目则使用高亮颜色 - const isHighlight = this.highlightIndex === api.dataIndex(); - const topColor = isHighlight ? HIGHLIGHT_COLOR : TEAL_LIGHT; - const deepColor = isHighlight ? '#E5C848' : TEAL_DEEP; - const sideColor = isHighlight ? '#B19A3A' : '#157B6E'; - return { type: 'group', children: [ @@ -258,8 +158,8 @@ export default { shape: {x: loc[0], y: loc[1], xAxisPoint: axis}, style: { fill: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [ - {offset: 0, color: deepColor}, - {offset: 1, color: sideColor} + {offset: 0, color: TEAL_DEEP}, + {offset: 1, color: '#157B6E'} ]) } }, @@ -268,15 +168,15 @@ export default { shape: {x: loc[0], y: loc[1], xAxisPoint: axis}, style: { fill: new this.$echarts.graphic.LinearGradient(0, 0, 0, 1, [ - {offset: 0, color: topColor}, - {offset: 1, color: deepColor} + {offset: 0, color: TEAL_LIGHT}, + {offset: 1, color: TEAL_DEEP} ]) } }, { type: 'CubeTop', shape: {x: loc[0], y: loc[1], xAxisPoint: axis}, - style: {fill: topColor} + style: {fill: TEAL_LIGHT} } ] }; @@ -295,7 +195,7 @@ export default { type: 'bar', data: this.values, itemStyle: {color: 'transparent'}, - name: this.chartTitle + name: '数量' } ] }; @@ -305,8 +205,6 @@ export default { /* ---------- 平滑滚动 ---------- */ startScroll() { - clearInterval(this.timer); // 先清除之前的定时器 - const len = this.xData.length; this.timer = setInterval(() => { this.cursor = (this.cursor + 1) % len;