در این مقاله قصد داریم یک نمودار دایرهای (Pie Chart) با استفاده از کتابخانه D3 رسم کنیم که درصد جمعیت استانهای مختلف ایران را نمایش میدهد.
کد نمودار دایرهای (Pie Chart):
خروجی کد:
تنظیمات اولیه
ابتدا عرض و ارتفاع SVG را تعریف کرده و یک عنصر SVG ایجاد میکنیم.
var width = 600 مشخص کردن عرض svg
var height = 400 مشخص کردن ارتفاع svg
var svg = d3.create('svg') ایجاد svg
attr('width', width) مقداردهی عرض به svg
attr('height', height); مقداردهی ارتفاع به svg
افزودن گروه و انتقال به مرکز
یک گروه (<g>
) به SVG اضافه کرده و آن را به مرکز نمودار منتقل میکنیم.
- var g = svg.append('g') ایجاد تگ g
- attr('transform', 'translate(300, 190)') انتقال تگ g به مرکز svg
هدف از اضافه کردن این گروه و تنظیم موقعیت آن این است که محور مبنای گروه (g
) از مرکز نمودار دایرهای شروع شود. با این کار، رسم کمانها و برچسبهای نمودار دایرهای بر اساس مرکز نمودار آسانتر میشود. به عبارت دیگر، مرکز نمودار دایرهای به نقطه (300, 190)
در داخل svg
منتقل میشود.
دادههای جمعیت استانها
در متغییر iranPopulation دادههای مربوط به جمعیت برخی از استانهای کشور ثبت شده است.
محاسبه درصدها
ابتدا جمع کل جمعیت را محاسبه کرده و سپس درصد جمعیت هر استان را نسبت به کل محاسبه میکنیم.
- var totalCount = iranPopulation.reduce(function(sum, d) { return sum + d.population; }, 0) محاسبه کل جمعیت با استفاده از دادههای موجود
- iranPopulation.forEach(function(d) { d.percentage = (d.population / totalCount) * 100; }) مشخص کردن درصد جمعیت هر یک از استانها
ایجاد Pie Generator
یک Pie Generator
ایجاد میکنیم که دادههای درصد را به صورت زاویهای برای نمودار دایرهای تبدیل میکند.
- var pieGenerator = d3.pie() استفاده از تابع d3.pie() که یک تابع تولیدکننده (generator) برای دادههای نمودار دایرهای (Pie Chart) میباشد.
- value(function(d) {return d.percentage;}) با استفاده از متد value مقدار هر بخش از نمودار دایرهای را مشخص میکنیم. در اینجا d.percentage است.
- var arcData = pieGenerator(iranPopulation) با استفاده از pieGenerator دادههای iranPopulation را به دادههای مورد نیاز برای رسم قوسهای نمودار دایرهای تبدیل میکنیم
ایجاد Arc Generator
یک Arc Generator
ایجاد میکنیم که مشخصات هر کمان از نمودار دایرهای را تعریف میکند.
- var arcGenerator = d3.arc() با استفاده از تابع d3.arc() که یک تولیدکننده (generator) برای رسم قوسها (arcs) در نمودار دایرهای قوسها را ایجاد میکنیم.
- innerRadius(10) تنظیم شعاع داخلی قوسها
- outerRadius(180) تنظیم شعاع خارجی قوسها
- padAngle(.02) ایجاد فضا بین قوسها
- padRadius(50) شعاع فاصله بین قوسها
- cornerRadius(5) گرد کردن گوشههای قوسها
ایجاد مقیاس رنگ
یک مقیاس رنگ ترتیبی تعریف میکنیم که برای هر بخش از نمودار دایرهای یک رنگ متفاوت تخصیص دهد.
- var sequentialScale = d3.scaleSequential() استفاده از مقیاس ترتیبی d3.scaleSequential() که برای نگاشت یک دامنه پیوسته از اعداد به یک بازه پیوسته از رنگها استفاده میشود.
- domain([0, 7]) تعیین دامنه ورودی به مقیاس
- interpolator(d3.interpolateRainbow) با استفاده از d3.interpolateRainbow که یک مفسر رنگی است رنگینکمانی از رنگها را تولید میکنیم.
رسم کمانهای نمودار
با استفاده از دادههای کمان، کمانهای نمودار دایرهای را رسم کرده و رنگ هر کمان را تنظیم میکنیم.
- svg.select('g') انتخاب تگ g که در ابتدا ایجاد کردهایم
- selectAll('path') انتخاب همه عناصر path
- data(arcData) پیوند دادهها به عناصر path
- join('path') ایجاد یک عنصر path به ازای هر داده
- attr('d', arcGenerator) ویژگی d هر عنصر path با استفاده از تابع arcGenerator تنظیم میکند
- attr('fill', function(d, i) {return sequentialScale(i);}) رنگ هر بخش از نمودار را مشخص میکند
- attr('stroke', 'white') خط حاشیه سفید رنگی به اطراف هر بخش از نمودار دایرهای اضافه میکند
افزودن برچسب درصدها
در این بخش، برچسبهای درصد را در مرکز هر کمان قرار میدهیم.
- svg.select('g') انتخاب تگ g که در ابتدا ایجاد کردهایم
- selectAll('text') انتخاب تمام عناصر text (در ابتدا هیچ عنصری وجود ندارد ولی D3 آنها را ایجاد میکند.)
- data(arcData) پیوند دادههای arcData به text
- join('text') ایجاد عنصر text به ازای هر داده
- each(function(d) { اجرای این تابع به ازای هر text
- var centroid = arcGenerator.centroid(d) محاسبه مرکز هر بخش نمودار
- d3.select(this) انتخاب عنصر text
- attr('x', centroid[0]) مشخص کردن محل قرارگیری متن در محور افقی
- attr('y', centroid[1]) مشخص کردن محل قرارگیری متن در محور عمودی
- attr('dy', '0.33em') قرارگیری متن در مرکز
- text(d.data.percentage.toFixed(2) + '%') مشخص کردن متن و اضافه کردن درصد به آن
- attr('text-anchor', 'middle') قرارگیری متن در مرکز
- attr('font-size', 12) مشخص کردن اندازه متن
افزودن عنوان نمودار
یک عنوان به پایین نمودار اضافه میکنیم.
svg.append('text') ایجاد عنصر text
attr('x', width / 2) مشخص کردن محل قرارگیری متن در محور افقی
attr('y', height - 5) مشخص کردن محل قرارگیری متن در محور افقی
attr('text-anchor', 'middle') قرارگیری متن در مرکز صفحه
style('font-size', '16px') مشخص کردن اندازه متن
style('font-weight', 'bold') پررنگ کردن متن
text('درصد جمعیت در استانها') متن
ایجاد توضیحات (Legend)
در این بخش، توضیحات برای نمودار ایجاد میکنیم که هر استان را با رنگ مربوطه نشان میدهد.
var legend = svg.append('g') اضافه کردن تگ g
attr('class', 'legend') اضافه کردن کلاس legend
attr('transform', `translate(${width - 90}, ${height / 2 - 150})`) انتقال تگ g
legend.selectAll('rect') انتخاب تمام عناصر rect (مستطیل) درون گروه legend، در ابتدا هیچ مستطیلی وجود ندارد.
data(iranPopulation) پیوند دادن دادهها به مستطیلها
join('rect') ایجاد یک مستطیل به ازای هر داده
attr('x', 0) مشخص کردن موقعیت مستطیل در محور افقی
attr('y', (d, i) => i * 20) مشخص کردن موقعیت مستطیل در محور عمودی
attr('width', 10) مشخص کردن عرض هر مستطیل
attr('height', 10) مشخص کردن ارتفاع هر مستطیل
style('fill', (d, i) => sequentialScale(i)) مشخص کردن رنگ هر مستطیل
legend.selectAll('text') انتخاب تمام textهای درون گروه legend
data(iranPopulation) پیوند دادهها به متنها
join('text') ایجاد متن به ازای هر یک از دادهها
attr('x', 15) مشخص کردن موقعیت متن در محور افقی
attr('y', (d, i) => i * 20 + 9) مشخص کردن موقعیت متن در محور عمودی
style('font-size', '12px') مشخص کردن اندازه متن
text(d => d.province) مشخص کردن هر متن