D3.js处理JSON数据:根据选中项获取国家/地区列表求助
嘿,我来帮你搞定这个问题!先从你举的简化例子入手,再对应到你的国家地区场景,最后聊聊nest()的用法~
先解决你的简化示例问题
首先得假设你的users数组是类似分组结构的(毕竟你没给具体结构,我按你的例子反推),比如:
const users = [ { group: "spices", name: "cinnamon" }, { group: "spices", name: "ginger" }, { group: "spices", name: "salt" }, { group: "people", name: "Corbin" }, { group: "people", name: "John" } ];
要实现“已知某个name,获取其所在分组的所有name”,可以用find()先定位目标项的分组,再用filter()+map()提取同组数据:
function getGroupMembers(targetName, data) { // 先找到目标项对应的分组 const targetItem = data.find(item => item.name === targetName); if (!targetItem) return []; // 没找到的话返回空数组 // 筛选同分组的所有项,提取name字段 return data.filter(item => item.group === targetItem.group).map(item => item.name); } // 测试一下 console.log(getGroupMembers('ginger', users)); // 输出 ["cinnamon", "ginger", "salt"] console.log(getGroupMembers('Corbin', users)); // 输出 ["Corbin", "John"]
对应到你的国家地区D3场景
假设你的JSON数据结构是类似这样的(每个条目包含国家和地区):
const countryRegionData = [ { country: "China", region: "Beijing" }, { country: "China", region: "Shanghai" }, { country: "USA", region: "California" }, { country: "USA", region: "New York" } ];
你的需求是:
- 当
cs(选中国家)非空时,获取所有国家列表(你已经实现的allCountries没问题,这里再补个去重的写法):
const allCountries = [...new Set(countryRegionData.map(item => item.country))]; // 输出 ["China", "USA"]
- 当
rs(选中地区)非空时,获取该地区所属国家的全部地区列表,这就是你卡壳的currentRegions,用类似简化示例的思路就能解决:
function getCountryRegions(selectedRegion, data) { // 找到选中地区对应的国家 const targetCountry = data.find(item => item.region === selectedRegion)?.country; if (!targetCountry) return []; // 筛选该国家的所有地区并提取 return data.filter(item => item.country === targetCountry).map(item => item.region); } // 赋值currentRegions let currentRegions = rs ? getCountryRegions(rs, countryRegionData) : []; // 比如rs是"Beijing",currentRegions就会是["Beijing", "Shanghai"]
关于是否使用nest()方法
上面的写法已经能解决问题,但D3的nest()确实是处理分组数据的利器,当数据量大或者需要频繁切换选中地区/国家时,用nest()预先构建分组结构,能大幅提升查询效率。
用nest()的实现方式:
// 预先构建「国家-地区列表」的分组结构 const countryGroups = d3.nest() .key(d => d.country) // 按country分组 .rollup(values => values.map(d => d.region)) // 把每组的region提取成数组 .object(countryRegionData); // 此时countryGroups的结构是:{ China: ["Beijing", "Shanghai"], USA: ["California", "New York"] } // 再构建「地区-国家」的映射表,方便快速查找选中地区所属国家 const regionToCountry = new Map(countryRegionData.map(item => [item.region, item.country])); // 处理rs非空的情况 if (rs) { const targetCountry = regionToCountry.get(rs); currentRegions = countryGroups[targetCountry] || []; }
这种方式只需要预先做一次分组,后续每次查询都是直接取数,效率更高,适合交互频繁的场景。
内容的提问来源于stack exchange,提问作者user7558372
相关产品推荐
相关产品推荐

