ایجاد نمودار Choropleth ایران با استفاده از D3

در مقاله قبلی، نحوه ایجاد نقشه ایران با استفاده از D3 را بررسی کردیم. در این مقاله، به ادامه‌ی همان پروژه پرداخته و نقشه Choropleth برای ایران را بر اساس جمعیت استان‌ها ایجاد خواهیم کرد. نقشه Choropleth یک نقشه رنگی است که در آن مناطق مختلف بر اساس مقادیر یک متغیر خاص (در اینجا جمعیت استان‌ها) به رنگ‌های مختلف نمایش داده می‌شوند. این نوع نقشه به ما اجازه می‌دهد تا به‌سادگی الگوهای توزیع جمعیت را مشاهده کنیم.

 

برای این کار، نیاز به دو مجموعه داده داریم:

  • فایل GeoJSON که حاوی مرزهای جغرافیایی استان‌های ایران است. دانلود
  • فایل JSON که شامل اطلاعات جمعیت هر استان است. این فایل به شکل زیر است:

 

[
{"province": "تهران", "id": "23", "population": 13267637},
{"province": "خراسان رضوی", "id": "09", "population": 6434501},
{"province": "اصفهان", "id": "10", "population": 5120850},
{"province": "فارس", "id": "07", "population": 4851274},
{"province": "خوزستان", "id": "06", "population": 4710509},
{"province": "آذربایجان شرقی", "id": "03", "population": 3909652},
{"province": "مازندران", "id": "02", "population": 3283582},
{"province": "آذربایجان غربی", "id": "04", "population": 3265219},
{"province": "کرمان", "id": "08", "population": 3164718},
{"province": "سیستان و بلوچستان", "id": "11", "population": 2775014},
{"province": "البرز", "id": "30", "population": 2712400},
{"province": "گیلان", "id": "01", "population": 2530696},
{"province": "کرمانشاه", "id": "05", "population": 1952434},
{"province": "گلستان", "id": "27", "population": 1868619},
{"province": "هرمزگان", "id": "22", "population": 1776415},
{"province": "لرستان", "id": "15", "population": 1760649},
{"province": "همدان", "id": "13", "population": 1758268},
{"province": "کردستان", "id": "12", "population": 1603011},
{"province": "مرکزی", "id": "00", "population": 1429475},
{"province": "قم", "id": "25", "population": 1292283},
{"province": "قزوین", "id": "26", "population": 1273761},
{"province": "اردبیل", "id": "24", "population": 1270420},
{"province": "بوشهر", "id": "18", "population": 1163400},
{"province": "یزد", "id": "21", "population": 1138533},
{"province": "زنجان", "id": "19", "population": 1057461},
{"province": "چهارمحال و بختیاری", "id": "14", "population": 947763},
{"province": "خراسان شمالی", "id": "28", "population": 863092},
{"province": "خراسان جنوبی", "id": "29", "population": 768898},
{"province": "کهگیلویه و بویراحمد", "id": "17", "population": 713052},
{"province": "سمنان", "id": "20", "population": 702360},
{"province": "ایلام", "id": "16", "population": 580158}
]

 

کد کامل ایجاد نمودار Choropleth

 

var iranpopulationNew = new Map();
iranPopulation.forEach(function(dt){
iranpopulationNew.set(dt.id,dt.population);
});
 
var width = 800;
var height = 800;
 
var svg = d3.create("svg")
.attr('width', width)
.attr('height', height)
 
var projection = d3.geoMercator()
.center([54, 32])
.scale(2200)
.translate([width / 2, height / 2]);
 
var path = d3.geoPath().projection(projection);
 
var colorScale = d3.scaleThreshold()
.domain([500000, 1000000, 1500000, 3000000, 5000000, 10000000])
.range(d3.schemeBlues[7]);
 
svg.append("g")
.selectAll("path")
.data(iran.features)
.join("path")
.attr("d", path)
.attr("fill", function (d) {
d.total = iranpopulationNew.get(Number(d.properties.id) > 9 ? Number(d.properties.id).toString() : '0'+ Number(d.properties.id)) || 0;
return colorScale(d.total);
})
.style("stroke", "#fff")
.append("title")
.text(function(d) { return d.properties.name + '\n' + d.total; });
 
svg.node()

 

خروجی کد

 

 

تبدیل داده‌های JSON جمعیت به Map

 

این قسمت داده‌های جمعیتی استان‌ها را به یک Map تبدیل می‌کند تا بتوان به راحتی به جمعیت هر استان دسترسی داشت.

 

var iranpopulationNew = new Map();
iranPopulation.forEach(function(dt){
iranpopulationNew.set(dt.id,dt.population);
});

 

تنظیمات ابتدایی برای اندازه نقشه

 

این قسمت یک عنصر SVG با عرض و ارتفاع مشخص ایجاد می‌کند که نقشه در آن رسم خواهد شد.

 

var width = 800;
var height = 800;
 
var svg = d3.create("svg")
.attr('width', width)
.attr('height', height)

 

ایجاد طرح نقشه و مسیر

 

این بخش یک projection از نوع Mercator ایجاد می‌کند و مرکز، مقیاس و محل قرارگیری نقشه را تنظیم می‌کند. سپس، یک مسیر (path) ایجاد می‌شود که از این projection استفاده می‌کند.

 

var projection = d3.geoMercator()
.center([54, 32])
.scale(2200)
.translate([width / 2, height / 2]);
 
var path = d3.geoPath().projection(projection);

 

تنظیم مقیاس رنگ‌ها برای نقشه Choropleth

 

این بخش یک مقیاس رنگی از نوع threshold ایجاد می‌کند که مقادیر مختلف جمعیت را به رنگ‌های مختلف مرتبط می‌کند.

 

var colorScale = d3.scaleThreshold()
.domain([500000, 1000000, 1500000, 3000000, 5000000, 10000000])
.range(d3.schemeBlues[7]);

 

d3.scaleThreshold() یک مقیاس آستانه‌ای ایجاد می‌کند که به شما امکان می‌دهد مقادیر ورودی را به دسته‌های مجزا تقسیم کنید و برای هر دسته یک رنگ خاص اختصاص دهید.

 

domain یک آرایه از مقادیر عددی است که به عنوان آستانه‌های دسته‌بندی استفاده می‌شود. مقادیر 500000، 1000000، 1500000، 3000000، 5000000 و 10000000 به عنوان آستانه‌های دسته‌بندی تعیین شده‌اند. این آستانه‌ها مقادیر جمعیت را به دسته‌های مختلف تقسیم می‌کنند.

 

یک آرایه از رنگ‌ها است که به هر دسته‌ای که در دامنه تعریف شده مرتبط می‌شود. d3.schemeBlues[7] یک آرایه از 7 رنگ مختلف از طیف رنگ‌های آبی است که توسط D3.js ارائه می‌شود. این آرایه رنگ‌ها به ترتیب به دسته‌های تعریف شده در دامنه اختصاص داده می‌شوند.

 

بارگذاری فایل GeoJSON و رسم نقشه

 

این بخش نقشه استان‌ها را بر اساس داده‌های GeoJSON رسم می‌کند. هر استان با استفاده از مسیر (path) خود رسم می‌شود و رنگ آن بر اساس جمعیت آن استان از Map تنظیم می‌گردد. همچنین، یک عنوان (title) به هر استان اضافه می‌شود که نام و جمعیت آن را نمایش می‌دهد.

 

svg.append("g")
.selectAll("path")
.data(iran.features)
.join("path")
.attr("d", path)
.attr("fill", function (d) {
d.total = iranpopulationNew.get(Number(d.properties.id) > 9 ? Number(d.properties.id).toString() : '0'+ Number(d.properties.id)) || 0;
return colorScale(d.total);
})
.style("stroke", "#fff")
.append("title")
.text(function(d) { return d.properties.name + '\n' + d.total; });

 

تابع محاسبه کننده جمعیت هر استان به صورت زیر عمل می‌کند:

 

  • d.properties.id شناسه (ID) هر استان است که در ویژگی‌های جغرافیایی ذخیره شده است.

  • Number(d.properties.id) شناسه را به عدد تبدیل می‌کند.

  • Number(d.properties.id) > 9 ? Number(d.properties.id).toString() : '0' + Number(d.properties.id) شناسه عددی را به رشته تبدیل می‌کند و اگر شناسه کمتر از 10 باشد، یک صفر به ابتدای آن اضافه می‌کند تا طول رشته به دو رقم برسد (این کار برای سازگاری با شناسه‌های موجود در نقشه و داده‌های جمعیت است).

  • iranpopulationNew.get(...) مقدار جمعیت را از Map که قبلاً ساخته شده بود، بر اساس شناسه به دست می‌آورد.

  • || 0 اگر هیچ مقدار جمعیتی برای شناسه پیدا نشود، مقدار 0 را به عنوان پیش‌فرض برمی‌گرداند.

  • نتیجه نهایی به عنوان d.total ذخیره می‌شود که نشان‌دهنده جمعیت آن استان است.

  • colorScale(d.total) از مقیاس رنگی colorScale که قبلاً تعریف شده بود استفاده می‌کند تا بر اساس مقدار جمعیت (d.total) یک رنگ مناسب برگرداند.

 

نمایش نقشه

 

این بخش نقشه نهایی را نمایش می‌دهد.

 

svg.node()

 

در این مقاله، یاد گرفتیم چگونه یک نقشه Choropleth برای استان‌های ایران بر اساس جمعیت آن‌ها رسم کنیم. با استفاده از D3 و داده‌های GeoJSON و JSON، می‌توانیم نقشه‌های بصری و مفیدی ایجاد کنیم که اطلاعات مهمی را به نمایش بگذارند. این نقشه‌ها می‌توانند در تحلیل داده‌ها و تصمیم‌گیری‌ها بسیار مفید باشند.