【问题标题】:Filling d3.js map with colors depending on data from json根据来自 json 的数据用颜色填充 d3.js 地图
【发布时间】:2021-07-24 09:31:49
【问题描述】:

对 d3 来说太新了,这是我第一个使用该库的项目。目前,我在根据数据用不同颜色填充地图时遇到问题。我在网上找到了很多示例,但它们并不适合我。

我所拥有的是一个带有这种格式数据的 JSON 文件

"Aska": {
    "opening_bal": 138000,
    "total_funds": 1030574000,
    "expenditure_wages": 796017000,
    "expenditure_materials": 234236000,
    "total_expenditure": 1030491000,
    "unspent_bal": 78000,
    "payment_due": 12780000
  },
  "Balasore": {
    "opening_bal": 4660000,
    "total_funds": 233869000,
    "expenditure_wages": 203883000,
    "expenditure_materials": 57571000,
    "total_expenditure": 262518000,
    "unspent_bal": 28658000,
    "payment_due": 2118000
  },

我可以使用 GeoJson 文件创建地图。这是地图的链接:https://mgnregs-d3.vercel.app/filter

我正在考虑使用初始类别“opening_bal”创建一个对象,例如:

{
  "Aska": 138000,
  "Balasore": 4660000
},

点击后,我会将类别更新为“total_funds”等,例如:

{
  "Aska": 1030574000,
  "Balasore": 233869000
},

但首先我需要可视化初始化第一个数据。我做不到。

这样的事情在某些项目上有效,但不适用于我的情况......

d3.json('data.json', function (d) {
    budget.d.properties.pc_name = d.properties.pc_name['opening_bal']
})

var color = d3
    .scaleThreshold()
    .domain(d3.range(2, 18))
    .range(d3.schemeBlues[6])

这里是 GitHub 上的 repo:https://github.com/PixeledCode/MGNREGS_D3

地图组件:https://github.com/PixeledCode/MGNREGS_D3/blob/main/src/components/Filter/Filter.js

data.json:https://github.com/PixeledCode/MGNREGS_D3/blob/main/src/assets/data.json

映射 GeoJson:https://github.com/PixeledCode/MGNREGS_D3/blob/main/src/assets/odihsa.js

感谢任何帮助。

【问题讨论】:

  • 我不明白你的问题。您的问题是读取 json 文件或将值转换为颜色代码?
  • 将值转换为颜色。就像我有一个具有不同 id 和各自值的对象一样,如何根据值用颜色填充地图。谢谢
  • 好的,你有一个值范围(比如说 0100)并且你想把这个范围内的每个值转换成一种颜色(假设从 greenblue)。对吗?
  • 是的,像这样,{ "Aska": 138000, "Balasore": 4660000 },这些是我为 svg 元素的不同路径提供的 id。想要基于这些值的颜色。

标签: javascript json reactjs d3.js data-visualization


【解决方案1】:

你有一个如下形式的数据对象:

const data = {
  "Aska": 138000,
  "Balasore": 4660000,
  ...
},

查找对象的最小值和最大值:

const range = Object.values(data).reduce((r, v) => r ? 
  ({min: Math.min(r.min, v), max: Math.max(r.max, v}) :
  ({min: v, max: v})), null);

现在,您可以编写一个函数,将最小值和最大值之间的任何值转换为颜色。如果最小值的颜色是 green (0, 255, 0),最大值的颜色是 blue (0, 0, 255),则函数看起来像这样:

const colorUnit = 255 / (range.max - range.min);
const getColorByValue = val => {
  const delta = val - range.min;
  return `rgb(0, ${255 - delta * colorUnit}, ${delta * colorUnit})`;
};

【讨论】:

  • 这个答案有帮助。它并没有完全起作用,找到最小值、最大值的 reduce 方法对我不起作用,但传递价值和获得颜色的想法有很大帮助。我最终编写了一个函数来通过改变色调和亮度来获得 hsl 颜色。非常感谢
  • 如果你有一个数组而不是对象,reduce 应该是不同的。让我知道您遇到的错误,我会尝试修复它
  • 错误是Uncaught TypeError: Cannot read property 'min' of null。 reduce 中还缺少一个),但错误来自其他原因。这是带有错误的jsfiddle。检查控制台日志。
  • 我的意思是在答案中,我放在 cmets 中的是固定括号。
  • 关于颜色值,您可以输入Math.floor()。如果您使用Math.round(),您可以获得超出范围的可能值 256...无论如何,舍入不会有太大变化
猜你喜欢
  • 2016-12-11
  • 1970-01-01
  • 1970-01-01
  • 2017-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多