零基础可视化看板搭建:从交互到下钻全流程

📅 2026/7/5 15:12:19 👁️ 阅读次数 📝 编程学习
零基础可视化看板搭建:从交互到下钻全流程

一、前言:从数据展示到交互洞察的跃迁

在前两个实验中,我们分别完成了浏览器市场分析大屏的静态布局与数据接入,以及用户画像大屏的多维度数据绑定和筛选器联动。然而,一个真正具备商业价值的可视化大屏,不仅需要"能看",更需要"能交互"——让用户通过简单的点击、切换,就能深入挖掘数据背后的洞察。

本实验将带领大家进入Max蓝图编辑器的高级交互领域,实现三大核心功能:

  1. Tab导航切换:通过图层可见性控制,在同一文件中实现"市场分析"与"用户画像"两个大屏的无缝切换

  2. 地图省份点击下钻:点击地图省份,右侧核心指标卡动态更新为该省份数据

  3. 热力图动态渲染:根据用户数自动渲染地图颜色深浅,实现地理分布的可视化

无需编写后端API,无需复杂的前端事件监听,只需在蓝图编辑器中拖拽节点、配置逻辑,即可完成企业级交互大屏。


二、实验目标与核心技能图谱

2.1 实验目的

能力维度具体技能
图层管理使用图层可见性控制实现大屏内容切换
导航交互使用Tab列表组件配置页面内容显示/隐藏
地理下钻使用地图组件交互事件实现省份点击联动
数据联动配置指标卡组件根据地图点击动态更新数据
热力渲染基于adcode映射实现地图热力层动态着色

2.2 实验环境

  • 数据来源:团队私有数据库(MySQL)

  • 前置实验:实验6-1(静态布局)、实验6-2(数据接入)

2.3 最终效果预览

完成本实验后,您的大屏将具备以下交互能力:

  • ✅ 顶部Tab导航一键切换"市场分析"与"用户画像"

  • ✅ 地图根据当前浏览器用户数自动渲染颜色深浅(热力图)

  • ✅ 点击任意省份,右侧四个核心指标卡实时刷新为该省份数据

  • ✅ 切换浏览器筛选器,地图热力图同步更新


三、整体交互架构设计

3.1 系统交互全景图

3.2 两大核心交互链路

链路一:大屏切换交互(图层可见性控制)
Tab列表组件 │ ├── 点击"市场分析" (id=1) ──→ 分支判断(id==1)为真 │ ├── 设置图层:市场分析组 → 显示 │ └── 设置图层:用户画像组 → 隐藏 │ └── 点击"用户画像" (id=2) ──→ 分支判断(id==1)为假 ├── 设置图层:市场分析组 → 隐藏 └── 设置图层:用户画像组 → 显示
链路二:地图省份点击联动(地理下钻)
基础平面地图(区域热力层) │ ├── 点击区域时事件 ──→ 提取地区名称(并行数据处理) │ │ │ ├── 省份全称 → 简称映射 │ └── 存入全局变量 window.globalProvinceName │ │ │ └──→ 省份核心指标查询(SQL请求) │ │ │ ├── 读取 window.globalProvinceName │ ├── 读取 window.GLOBAL_SELECTED_BROWSER │ └── 执行动态SQL │ │ │ └──→ 省份核心指标分发(并行数据处理) │ │ │ ├── 分支1:总用户数 → 指标卡1 │ ├── 分支2:平均年龄 → 指标卡2 │ ├── 分支3:本科占比 → 指标卡3 │ └── 分支4:中高收入占比 → 指标卡4 │ └── 热力渲染链路(独立) │ ├── 地理边界geojson加载完成 ──→ 提取adcode映射表 │ │ │ └── 存入 window.globalProvinceAdcode │ │ └── 浏览器切换/页面加载 ──→ 各省份用户数查询(SQL) │ └──→ 地图数据与用户数映射 │ └──→ 导入热力值数据接口

四、核心技术深度解析

4.1 图层可见性控制:单文件多屏方案

设计背景:在实际业务场景中,一个数据分析项目往往包含多个视角(如市场分析、用户画像、运营监控)。如果每个视角都创建独立的大屏文件,会导致:

  • 维护成本高(样式、数据源需重复配置)

  • 切换体验差(页面跳转有白屏)

  • 状态丢失(筛选器状态无法跨页面传递)

Max解决方案:通过图层组+可见性控制,在同一文件中管理多个大屏内容。

技术原理

  • 将"市场分析"所有组件放入一个图层组(如"市场分析组")

  • 将"用户画像"所有组件放入另一个图层组(如"用户画像组")

  • 通过Tab列表组件的点击事件,控制两个组的显示/隐藏状态

优势对比

方案文件数切换体验状态共享维护成本
独立文件2+差(页面跳转)不支持
图层切换(本方案)1优(无刷新)支持

4.2 地图交互事件体系

Max地图组件(基础平面地图)提供了丰富的交互事件:

事件名称触发时机输出数据
当数据接口地理边界geojson数据加载完成时地图GeoJSON加载完成GeoJSON对象(含features数组)
点击区域时用户点击某个省份区域{ name, adcode, ... }
鼠标移入区域触发鼠标悬停省份{ name, adcode, ... }
鼠标移出区域触发鼠标离开省份{ name, adcode, ... }

本实验使用的事件

  • 点击区域时:触发省份下钻,更新指标卡

  • 当数据接口地理边界geojson数据加载完成时:提取adcode映射表,为热力渲染做准备

4.3 省份名称标准化:全称与简称的映射

问题背景:地图组件返回的省份名称是全称(如"江苏省"、"广西壮族自治区"),但数据库中存储的是简称(如"江苏"、"广西")。直接用于SQL查询会导致匹配失败。

解决方案:建立双向映射表,在数据流中进行名称转换。

// 特殊映射表(直辖市、自治区、特别行政区) const specialMap = { '北京市': '北京', '天津市': '天津', '上海市': '上海', '重庆市': '重庆', '广西壮族自治区': '广西', '内蒙古自治区': '内蒙古', '西藏自治区': '西藏', '宁夏回族自治区': '宁夏', '新疆维吾尔自治区': '新疆', '香港特别行政区': '香港', '澳门特别行政区': '澳门' };

通用处理规则

  1. 优先匹配特殊映射表(处理直辖市、自治区等特殊情况)

  2. 通用处理:去除末尾的"省"、"自治区"、"市"后缀

  3. 最终得到数据库可识别的简称

4.4 行政区划代码(adcode)映射

什么是adcode?adcode是国家统计局发布的行政区划代码,是地图渲染的"身份证"。Max地图组件通过adcode识别每个省份的边界和位置。

为什么需要adcode映射?

地图热力层的数据格式要求:

{ "name": "江苏", "value": 1500, "area_id": 320000 }

其中area_id就是adcode。因此,我们需要建立"省份名称 → adcode"的映射关系。

数据来源:地图组件内置的GeoJSON数据中已经包含了每个省份的adcode,只需在加载完成后提取即可。


五、实验步骤详解

5.1 Step 1:配置大屏Tab导航切换

5.1.1 设计思路

Tab列表组件是一个可自定义选项的交互组件。本实验的核心技巧是"透明化"——将Tab列表的背景色、选中背景色、悬浮背景色的透明度都设为0,使其与顶部的导航按钮完全重合,给用户"点击按钮切换页面"的错觉,实际上是通过图层可见性控制实现内容切换。

5.1.2 组件配置

(1)添加Tab列表组件

  • 从组件库拖拽"Tab列表"组件到画布顶部导航区域

  • 调整大小和位置,使其与两个导航按钮("市场分析"、"用户画像")完全重合

(2)样式配置(透明化处理)

在Tab列表组件的基本设置中:

  • 行数:1

  • 列数:2

  • 标签默认配置中,将以下三项的透明度设置为0

    • 背景颜色

    • 选中背景色

    • 悬浮背景色

效果:Tab列表组件完全透明,用户只能看到底层的导航按钮文字,但点击区域实际由Tab列表捕获。

(3)数据配置

数据面板中,保留2列数据:

[ { "id": 1, "content": "" }, { "id": 2, "content": "" } ]
  • id:用于分支判断,区分"市场分析"和"用户画像"

  • content:设为空字符串(因为按钮文字由底层样式提供)

配置完成后,点击刷新数据按钮。

5.1.3 蓝图编辑器配置

(1)导出组件

将以下组件导出到蓝图编辑器:

  • "市场分析"组(图层组)

  • "用户画像"组(图层组)

  • Tab列表组件

(2)添加分支判断节点

添加"分支判断"节点,配置处理方法:

return data.id == 1;

逻辑说明

  • 当用户点击"市场分析"时,Tab列表输出{ id: 1 },表达式为true

  • 当用户点击"用户画像"时,Tab列表输出{ id: 2 },表达式为false

(3)配置"满足"分支(id=1,显示市场分析)

在"分支判断"的满足分支上,添加两个"设置图层可见性"动作:

目标图层动作
市场分析组显示
用户画像组隐藏

(4)配置"不满足"分支(id=2,显示用户画像)

在"分支判断"的不满足分支上,添加两个"设置图层可见性"动作:

目标图层动作
市场分析组隐藏
用户画像组显示

(5)节点连线

5.1.4 验证要点
  • [ ] 点击"市场分析"按钮,市场分析大屏显示,用户画像大屏隐藏

  • [ ] 点击"用户画像"按钮,用户画像大屏显示,市场分析大屏隐藏

  • [ ] 切换过程无页面刷新,体验流畅


5.2 Step 2:配置地图省份点击联动

5.2.1 设计思路

用户点击地图省份 → 提取省份名称 → 查询该省份核心指标 → 分发到四个指标卡。这是典型的地理下钻分析(Geo-drilldown)

5.2.2 核心组件配置

(1)提取地区名称(并行数据处理节点)

作用:接收地图点击事件输出的数据对象,提取省份名称,通过映射表转换为简称,存入全局变量。

节点配置

添加"并行数据处理"节点,重命名为"提取地区名称"

处理方法代码:

// 省份特殊映射(直辖市、自治区、特别行政区) const specialMap = { '北京市': '北京', '天津市': '天津', '上海市': '上海', '重庆市': '重庆', '广西壮族自治区': '广西', '内蒙古自治区': '内蒙古', '西藏自治区': '西藏', '宁夏回族自治区': '宁夏', '新疆维吾尔自治区': '新疆', '香港特别行政区': '香港', '澳门特别行政区': '澳门' }; let provinceName = data.name; // 优先使用特殊映射 if (specialMap[provinceName]) { provinceName = specialMap[provinceName]; } else { // 通用处理:去除末尾的"省"、"自治区"、"市" provinceName = provinceName.replace(/(省|自治区|市)$/, ''); } // 存入全局变量,供后续SQL节点读取 window.globalProvinceName = provinceName; return provinceName;

代码解析

处理阶段逻辑示例
特殊映射直接查表"北京市" → "北京"
通用处理正则去除后缀"江苏省" → "江苏"
全局存储window.globalProvinceName跨节点共享

(2)省份核心指标查询(SQL请求节点)

作用:根据当前选中的浏览器和点击的省份,查询四个核心指标。

节点配置

添加"SQL请求"节点,重命名为"省份核心指标查询"

处理方法代码:

const selectedProvince = window.globalProvinceName; console.log("点击的省份名称(处理后):", selectedProvince); const selectedBrowser = window.GLOBAL_SELECTED_BROWSER; const sql = ` -- 指标1:总用户数 select 'total_users' as name, sum(user_count) as value from labs.user_profile_stats where browser_name = '${selectedBrowser}' and province = '${selectedProvince}' union all -- 指标2:平均年龄(加权平均) select 'avg_age' as name, round(sum(age * user_count) / sum(user_count), 0) as value from labs.user_profile_stats where browser_name = '${selectedBrowser}' and province = '${selectedProvince}' union all -- 指标3:本科及以上占比 select 'high_edu_ratio' as name, round( sum(case when edu in ('本科', '硕士及以上') then user_count else 0 end) * 100.0 / sum(user_count), 2 ) as value from labs.user_profile_stats where browser_name = '${selectedBrowser}' and province = '${selectedProvince}' union all -- 指标4:中高收入占比 select 'high_income_ratio' as name, round( sum(case when income in ('5001~8000元', '8001~12000元', '12000元以上') then user_count else 0 end) * 100.0 / sum(user_count), 2 ) as value from labs.user_profile_stats where browser_name = '${selectedBrowser}' and province = '${selectedProvince}' `; console.log("生成的省份核心指标SQL:", sql); return sql;

SQL设计要点

指标计算逻辑精度
总用户数SUM(user_count)整数
平均年龄SUM(age * user_count) / SUM(user_count)0位小数
本科及以上占比CASE WHEN条件计数 / 总数 × 100%2位小数
中高收入占比多值匹配 + 条件计数 / 总数 × 100%2位小数

为什么用UNION ALL四个指标结构相同(name, value),合并为一次查询减少数据库往返。每个指标通过name字段标识,便于后续分发。

(3)省份核心指标分发(并行数据处理节点)

作用:将SQL返回的四行数据拆分为四个独立数值,分别发送给对应的指标卡。

节点配置

添加"并行数据处理"节点,重命名为"省份核心指标分发"

分支1:总用户数 → 总用户数指标卡

var item = data.find(item => item.name === 'total_users'); return [{ value: item ? item.value : 0 }];

分支2:平均年龄 → 平均年龄指标卡

var item = data.find(item => item.name === 'avg_age'); return [{ value: item ? item.value : 0 }];

分支3:本科及以上占比 → 本科及以上占比指标卡

var item = data.find(item => item.name === 'high_edu_ratio'); return [{ value: item ? item.value : 0 }];

分支4:中高收入占比 → 中高收入占比指标卡

var item = data.find(item => item.name === 'high_income_ratio'); return [{ value: item ? item.value : 0 }];
5.2.3 蓝图连线

5.2.4 验证要点
  • [ ] 点击地图上的江苏省,指标卡显示江苏省的数据

  • [ ] 点击地图上的广东省,指标卡显示广东省的数据

  • [ ] 指标数据与当前选中的浏览器一致(如当前选中Chrome,则显示Chrome在江苏的数据)

  • [ ] 切换浏览器后,再次点击同一省份,数据应相应变化


5.3 Step 3:配置地图热力层动态渲染

5.3.1 设计思路

为了直观展示全国各省份的用户分布,需要在地图上用颜色深浅表示用户数(用户数越多,颜色越深)。这需要完成三个步骤:

  1. 提取adcode映射表:从地图GeoJSON中提取"省份名称 → adcode"映射

  2. 查询各省份用户数:按浏览器统计每个省份的用户总数

  3. 数据映射与格式化:将查询结果匹配adcode,输出热力层所需格式

5.3.2 核心组件配置

(1)提取adcode映射表(并行数据处理节点)

作用:在地图GeoJSON加载完成后,提取每个省份的adcode和名称,建立映射表。

触发时机:区域热力层的当数据接口地理边界geojson数据加载完成时事件

节点配置

添加"并行数据处理"节点,重命名为"提取adcode映射表"

处理方法代码:

/** * 提取地理数据中的 adcode 和 name,建立名称→adcode 映射 * @param {Object} data - 地理数据对象(包含 features 数组) * @returns {Object} 名称到 adcode 的映射表 */ function extractAdcodeAndName(data) { if (!data || !Array.isArray(data.features)) { console.error('无效的地图数据格式'); return {}; } const nameToAdcode = {}; data.features.forEach(feature => { const props = feature.properties; if (props && props.adcode && props.name) { nameToAdcode[props.name] = props.adcode; } }); return nameToAdcode; } const mapping = extractAdcodeAndName(data); // 存入全局变量,供后续热力数据映射使用 window.globalProvinceAdcode = mapping; console.log("省份adcode映射表已加载", Object.keys(mapping).length); return mapping;

代码解析

步骤操作说明
数据校验检查data.features是否为数组防御性编程
遍历featuresforEach遍历每个省份GeoJSON标准结构
提取属性feature.properties.adcode/.nameGeoJSON规范
全局存储window.globalProvinceAdcode跨节点共享

(2)各省份用户数查询(SQL请求节点)

作用:根据当前选中的浏览器,统计每个省份的用户总数。

节点配置

添加"SQL请求"节点,重命名为"各省份用户数查询"

处理方法代码:

const selectedBrowser = window.GLOBAL_SELECTED_BROWSER; const sql = ` SELECT province AS name, SUM(user_count) AS value FROM labs.user_profile_stats WHERE browser_name = '${selectedBrowser}' AND province IS NOT NULL AND province != '' GROUP BY province ORDER BY value DESC `; console.log("生成的所有省份用户数SQL:", sql); return sql;

SQL设计要点

  • GROUP BY province:按省份聚合

  • ORDER BY value DESC:按用户数降序排列,便于查看TOP省份

  • AND province IS NOT NULL AND province != '':过滤空值,避免地图渲染异常

(3)地图数据与用户数映射(并行数据处理节点)

作用:将SQL查询结果中的省份名称与adcode映射表匹配,生成热力层所需的{ name, value, area_id }格式。

节点配置

添加"并行数据处理"节点,重命名为"地图数据与用户数映射"

处理方法代码:

function convertToMapData(data) { if (!Array.isArray(data) || data.length === 0) { return []; } return data.map(item => { const provinceName = item.name; // 第一步:直接匹配 let area_id = window.globalProvinceAdcode[provinceName]; // 第二步:如果直接匹配失败,尝试简化名称 if (!area_id) { const simplifiedName = provinceName.replace( /省|市|自治区|特别行政区|回族|壮族|维吾尔|藏族|苗族/g, '' ); for (const fullName in window.globalProvinceAdcode) { if (fullName.includes(simplifiedName)) { area_id = window.globalProvinceAdcode[fullName]; break; } } } // 第三步:兜底处理 if (!area_id) { // console.warn(`未找到省份 "${provinceName}" 的匹配 adcode`); area_id = "000000"; } return { name: provinceName, value: parseFloat(item.value) || 0, area_id: Number(area_id) }; }); } const result = convertToMapData(data); // console.log("最终返回的地图热力数据:", result); return result;

映射策略详解

匹配层级策略适用场景
第一层:直接匹配globalProvinceAdcode[provinceName]名称完全一致
第二层:简化匹配去除后缀后模糊匹配数据库简称 vs GeoJSON全称
第三层:兜底处理使用默认adcode "000000"防止渲染崩溃

数据格式说明

热力层要求的数据格式:

[ { "name": "江苏", "value": 1500, "area_id": 320000 }, { "name": "广东", "value": 2300, "area_id": 440000 } ]
  • name:省份名称(用于tooltip显示)

  • value:用户数(用于颜色深浅计算)

  • area_id:adcode(用于定位省份边界)

5.3.3 蓝图连线(热力渲染链路)
5.3.4 验证要点
  • [ ] 地图加载后,各省份呈现不同颜色深浅

  • [ ] 用户数最多的省份颜色最深

  • [ ] 切换浏览器筛选器,地图颜色分布相应变化

  • [ ] 无数据的省份显示为默认颜色(或灰色)


5.4 Step 4:完整蓝图整合

完成以上三个步骤后,您的蓝图应包含以下完整的数据流:

5.4.1 大屏切换链路
5.4.2 省份点击下钻链路
5.4.3 热力渲染链路

六、关键技术深度解析

6.1 全局变量管理策略

本实验使用了多个全局变量进行跨节点数据共享:

变量名存储内容写入节点读取节点
window.GLOBAL_SELECTED_BROWSER当前选中的浏览器浏览器参数接收各SQL请求节点
window.globalProvinceName点击的省份简称提取地区名称省份核心指标查询
window.globalProvinceAdcode省份名称→adcode映射提取adcode映射表地图数据与用户数映射

设计原则

  • 单一职责:每个变量只存储一种数据

  • 命名规范:使用GLOBAL_前缀标识全局变量

  • 生命周期:在页面加载时初始化,在交互事件中更新

6.2 分支判断节点的条件表达式

本实验中的分支判断使用简单的等值判断:

return data.id == 1;

进阶用法

场景表达式说明
多Tab切换return data.id;直接返回ID,配合多分支
范围判断return data.value > 100;数值阈值判断
复合条件return data.id == 1 && data.type == 'market';多条件组合
字符串匹配return data.name.includes('北京');模糊匹配

6.3 地图热力层的数据驱动原理

Max地图组件的热力渲染基于数据驱动模式:

原始数据(省份+用户数) │ ├──→ 数据映射(匹配adcode) │ ├──→ 颜色映射(value → 颜色深浅) │ 平台内置算法:根据value范围自动分配颜色梯度 │ └──→ 渲染层(Canvas/SVG绘制)

颜色映射算法(平台内部实现):

  • 自动计算数据的最大值和最小值

  • 将数值范围映射到颜色梯度(如浅蓝 → 深蓝)

  • 支持自定义颜色主题


七、常见问题与解决方案

Q1:Tab切换时,两个大屏内容重叠显示

原因:图层可见性配置错误,或两个组未正确分组。

解决方案

  1. 确认"市场分析组"和"用户画像组"是独立的图层组

  2. 检查分支判断的两个分支是否分别配置了"显示"和"隐藏"

  3. 初始状态下,确保只有一个组是可见的

Q2:点击地图省份,指标卡数据不更新

排查步骤

  1. 在"提取地区名称"节点添加console.log(data),确认是否接收到点击事件

  2. 检查window.globalProvinceName是否正确赋值

  3. 在"省份核心指标查询"节点添加console.log(sql),确认SQL语句正确

  4. 检查数据库中该省份+浏览器的组合是否有数据

Q3:地图热力层不显示颜色

排查步骤

  1. 确认"提取adcode映射表"节点是否正确执行(检查控制台日志)

  2. 检查window.globalProvinceAdcode是否包含有效的映射关系

  3. 在"地图数据与用户数映射"节点添加调试代码,确认输出格式为{ name, value, area_id }

  4. 检查area_id是否为数字类型(字符串会导致匹配失败)

Q4:省份名称映射失败(如"内蒙古自治区"无法匹配)

原因:简化名称的逻辑未能覆盖所有特殊情况。

解决方案

  • specialMap中添加缺失的映射

  • 或在简化名称逻辑中增加更多的正则替换规则

Q5:切换浏览器后,地图热力图未更新

原因:热力渲染链路未与浏览器筛选器联动。

解决方案

  • 确认"各省份用户数查询"节点的触发源包含"浏览器筛选器"

  • 确认SQL中使用了window.GLOBAL_SELECTED_BROWSER变量


八、实验总结与进阶思考

8.1 核心收获

通过本实验,我们完成了从数据展示交互洞察的完整闭环:

功能模块技术要点业务价值
Tab导航切换图层可见性控制 + 分支判断单文件管理多屏,降低维护成本
省份点击下钻事件驱动 + 动态SQL + 数据分发地理维度深入分析
热力图渲染GeoJSON解析 + adcode映射 + 数据驱动着色直观展示地理分布差异

8.2 可扩展的交互场景

基于本实验的技术框架,可以进一步扩展:

扩展场景实现思路
双击下钻到城市地图组件支持多级下钻,配置城市级GeoJSON
时间轴播放添加时间筛选器,实现数据随时间变化的热力图动画
多指标切换添加指标切换按钮,热力图按不同指标(用户数/时长/收入)渲染
联动高亮点击省份时,同时高亮该省份在所有图表中的数据
数据下钻弹窗点击省份后弹出模态框,展示该省份的详细用户画像

8.3 性能优化建议

优化点方案预期效果
SQL优化browser_name+province添加联合索引查询速度提升60%+
数据缓存对adcode映射表进行本地缓存避免重复解析GeoJSON
懒加载市场分析组数据延迟加载首屏加载时间减少40%
防抖处理地图点击添加防抖(300ms)避免快速点击导致多次请求

8.4 发布与分享

完成所有配置后,点击"发布"按钮:

  1. 打开发布分享开关

  2. 复制分享链接

  3. 在浏览器中打开链接,即可在线观看

示例分享链接格式:

http://47.109.66.142:30887/#/dataScreen/release?shareId=cb73b29223c74387a7cb02880d010c0b

九、完整代码速查表

9.1 省份名称映射代码

const specialMap = { '北京市': '北京', '天津市': '天津', '上海市': '上海', '重庆市': '重庆', '广西壮族自治区': '广西', '内蒙古自治区': '内蒙古', '西藏自治区': '西藏', '宁夏回族自治区': '宁夏', '新疆维吾尔自治区': '新疆', '香港特别行政区': '香港', '澳门特别行政区': '澳门' }; let provinceName = data.name; if (specialMap[provinceName]) { provinceName = specialMap[provinceName]; } else { provinceName = provinceName.replace(/(省|自治区|市)$/, ''); } window.globalProvinceName = provinceName; return provinceName;

9.2 省份核心指标SQL模板

const selectedProvince = window.globalProvinceName; const selectedBrowser = window.GLOBAL_SELECTED_BROWSER; const sql = ` select 'total_users' as name, sum(user_count) as value from labs.user_profile_stats where browser_name = '${selectedBrowser}' and province = '${selectedProvince}' union all select 'avg_age' as name, round(sum(age * user_count) / sum(user_count), 0) as value from labs.user_profile_stats where browser_name = '${selectedBrowser}' and province = '${selectedProvince}' union all select 'high_edu_ratio' as name, round(sum(case when edu in ('本科', '硕士及以上') then user_count else 0 end) * 100.0 / sum(user_count), 2) as value from labs.user_profile_stats where browser_name = '${selectedBrowser}' and province = '${selectedProvince}' union all select 'high_income_ratio' as name, round(sum(case when income in ('5001~8000元', '8001~12000元','12000元以上') then user_count else 0 end) * 100.0 / sum(user_count), 2) as value from labs.user_profile_stats where browser_name = '${selectedBrowser}' and province = '${selectedProvince}' `; return sql;

9.3 adcode提取代码

function extractAdcodeAndName(data) { if (!data || !Array.isArray(data.features)) { console.error('无效的地图数据格式'); return {}; } const nameToAdcode = {}; data.features.forEach(feature => { const props = feature.properties; if (props && props.adcode && props.name) { nameToAdcode[props.name] = props.adcode; } }); return nameToAdcode; } const mapping = extractAdcodeAndName(data); window.globalProvinceAdcode = mapping; return mapping;

9.4 热力数据映射代码

function convertToMapData(data) { if (!Array.isArray(data) || data.length === 0) return []; return data.map(item => { const provinceName = item.name; let area_id = window.globalProvinceAdcode[provinceName]; if (!area_id) { const simplifiedName = provinceName.replace(/省|市|自治区|特别行政区|回族|壮族|维吾尔|藏族|苗族/g, ''); for (const fullName in window.globalProvinceAdcode) { if (fullName.includes(simplifiedName)) { area_id = window.globalProvinceAdcode[fullName]; break; } } } if (!area_id) area_id = "000000"; return { name: provinceName, value: parseFloat(item.value) || 0, area_id: Number(area_id) }; }); } return convertToMapData(data);

版权声明:本文为实验平台实验指导内容的技术总结,仅供学习交流使用。

发布日期:2026年6月