با عرض سلام و وقت بخیر خدمت کاربران سایت پی وی لرن ، در جلسه آخر از آموزش های دوره D3.js قصد داریم یک مثال کاربردی با D3.js را با توجه به آموزش های جلسات قبلی ایجاد کنیم. با حجم عظیم داده هایی که امروزه تولید می شوند، تحلیل داده ها کاری بسیار دشوار و سخت است، نمایش تصویری داده ها و رسم انواع نمودارها، موثرترین ابزار برای نشان دادن داده ها و تحلیل داده ها است. اجازه دهید یک نمودار نواری متحرک در D3.js را ایجاد کنیم.
همانطور که گفته شد در این جلسه می خواهیم یک نمودار نواری متحرک در D3.js ایجاد کنیم.
برای این مثال کاربردی با D3.js ، از فایل data.csv استفاده شده در فصل قبل از پرونده های جمعیت به عنوان مجموعه داده استفاده می کنیم و نمودار نواری متحرک در D3.js ایجاد می کنیم.
برای انجام این کار، باید مراحل زیر را انجام دهیم :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <style> .bar { fill: green; } .highlight { fill: red; } .title { fill: blue; font-weight: bold; } </style> |
مرحله ۲ : تعریف متغیرها ، اکنون اجازه دهید ویژگی های SVG را با استفاده از اسکریپت زیر تعریف کنیم.
1 2 3 4 5 | <script> var svg = d3.select("svg"), margin = 200, width = svg.attr("width") - margin, height = svg.attr("height") - margin; </script> |
مرحله ۳ : متن را اضافه کنید ، حالا متن را اضافه کنید و با استفاده از کدگذاری زیر، تغییرات را اعمال کنید.
1 2 3 4 5 6 7 | svg.append("text") .attr("transform", "translate(100,0)") .attr("x", 50) .attr("y", 50) .attr("font-size", "20px") .attr("class", "title") .text("Population bar chart") |
مرحله ۴ : ایجاد محدوده مقیاس ، در این مرحله می توانیم یک محدوده مقیاس ایجاد کنیم و عناصر گروه را اضافه کنیم.
1 2 3 4 5 | var x = d3.scaleBand().range([0, width]).padding(0.4), y = d3.scaleLinear() .range([height, 0]); var g = svg.append("g") .attr("transform", "translate(" + 100 + "," + 100 + ")"); |
مرحله ۵ : خواندن داده ها ، ما قبلا فایل data.csv را در نمونه های قبلی ایجاد کرده ایم.
اکنون نیز همان فایل را در اینجا استفاده کردیم.
1 2 3 4 5 6 7 8 | year,population 2006,40 2008,45 2010,48 2012,51 2014,53 2016,57 2017,62 |
حالا، با استفاده از کد زیر، فایل بالا را بخوانید.
1 2 3 4 | d3.csv("data.csv", function(error, data) { if (error) { throw error; } |
مرحله ۶ : تنظیم دامنه ،اکنون دامنه را با استفاده از دستور زیر تعیین کنید.
1 2 | x.domain(data.map(function(d) { return d.year; })); y.domain([0, d3.max(data, function(d) { return d.population; })]); |
مرحله ۷ : اضافه کردن محور X، حالا شما می توانید محور X را به تغییرات اضافه کنید.
همانطور که در زیر نشان داده شده است.
1 2 3 4 5 6 | g.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)).append("text") .attr("y", height - 250).attr("x", width - 100) .attr("text-anchor", "end").attr("font-size", "18px") .attr("stroke", "blue").text("year"); |
مرحله ۸ : اضافه کردن محور Y ، با استفاده از کد داده شده زیر، محور Y را به تغییرات اضافه کنید.
1 2 3 4 5 | g.append("g") .append("text").attr("transform", "rotate(-90)") .attr("y", 6).attr("dy", "-5.1em") .attr("text-anchor", "end").attr("font-size", "18px") .attr("stroke", "blue").text("population"); |
مرحله ۹ : عناصر گروه را اضافه کنید، اکنون عناصر گروه را اضافه کنید و اعمال تغییرات را به محور Y به صورت زیر تعریف کنید.
1 2 3 | g.append("g") .attr("transform", "translate(0, 0)") .call(d3.axisLeft(y)) |
مرحله ۱۰ : کلاس نوار را انتخاب کنید، حالا تمام عناصر در کلاس نوار را به صورت زیر تعریف کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | g.selectAll(".bar") .data(data).enter() .append("rect") .attr("class", "bar") .on("mouseover", onMouseOver) .on("mouseout", onMouseOut) .attr("x", function(d) { return x(d.year); }) .attr("y", function(d) { return y(d.population); }) .attr("width", x.bandwidth()) .transition() .ease(d3.easeLinear) .duration(200) .delay(function (d, i) { return i * 25; }) .attr("height", function(d) { return height - y(d.population); }); }); |
این عمل انیمیشن را هنگامی که ماوس روی یک نوار خاص قرار می گیرد و از آن خارج می شود اجرا می کند.
این توابع در مرحله بعد توضیح داده شده است.
تابع (ease(d3.easeLinear. برای انجام حرکت ظاهری در انیمیشن استفاده می شود.
این روند حرکت slow-in و slow-out را با مدت زمان ۲۰۰ پردازش می کند.
همچنین تاخیر را می توان با استفاده از دستورات زیر محاسبه کرد :
1 2 3 | .delay(function (d, i) { return i * 25; }) |
مرحله ۱۱ – تابع handler رویداد موس، اجازه دهید یک handler رویداد mouseover را برای رسیدگی به یک رویداد ماوس به صورت زیر نشان بدهیم.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | function onMouseOver(d, i) { d3.select(this) .attr('class', 'highlight'); d3.select(this) .transition() .duration(200) .attr('width', x.bandwidth() + 5) .attr("y", function(d) { return y(d.population) - 10; }) .attr("height", function(d) { return height - y(d.population) + 10; }); g.append("text") .attr('class', 'val') .attr('x', function() { return x(d.year); }) .attr('y', function() { return y(d.value) - 10; }) } |
برای رنگ، یک کلاس اضافه کرده ایم که رنگ نوار انتخاب شده را به رنگ قرمز تغییر می دهد.
یک تابع انتقال به نوار برای مدت ۲۰۰ میلی ثانیه نیز در نظر گرفتیم .
هنگامی که عرض نوار را ۵ پیکسل و ارتفاع آن را نیز ۱۰ پیکسل افزایش دهیم :
انتقال از عرض و ارتفاع قبلی به عرض و ارتفاع جدید به مدت ۲۰۰ میلی ثانیه بعد اتفاق می افتد.
سپس ، یک مقدار جدید ‘y’ را با نوار محاسبه کردیم، به طوری که نوار با توجه به مقدار ارتفاع جدید تحریف نشود.
مرحله ۱۲ – تابع handler رویداد ماوس(Mouseout) ، اجازه دهید یک handler رویداد mouseout را برای رسیدگی به رویداد ماوس ایجاد کنیم.
این مفهوم با مثال در زیر تعریف شده است.
1 2 3 4 5 6 7 8 9 10 11 12 | function onMouseOut(d, i) { d3.select(this).attr('class', 'bar'); d3.select(this) .transition() .duration(400).attr('width', x.bandwidth()) .attr("y", function(d) { return y(d.population); }) .attr("height", function(d) { return height - y(d.population); }); d3.selectAll('.val') .remove() } |
در اینجا، در رویداد mouseout، ما می خواهیم ویژگی های انتخابی را که ما در رویداد mouseover اعمال کردیم حذف کنیم.
بنابراین کلاس class bar را به کلاس ‘bar’ واقعی تغییر می دهیم.
همچنین عرض و ارتفاع اصلی نوار انتخاب شده را بازسازی می کنیم و مقدار y را به مقدار اصلی بازگردانیم.
مرحله ۱۳ : عملکرد مثال، برنامه کامل در بلوک کد زیر داده شده است.
یک صفحه وب animated_bar.html ایجاد کنید و تغییرات زیر را به آن اضافه کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | <!DOCTYPE html> <html> <head> <style> .bar { fill: green; } .highlight { fill: red; } .title { fill: blue; font-weight: bold; } </style> <script src = "https://d3js.org/d3.v4.min.js"></script> <title> Animated bar chart </title> </head> <body> <svg width = "500" height = "500"></svg> <script> var svg = d3.select("svg"), margin = 200, width = svg.attr("width") - margin, height = svg.attr("height") - margin; svg.append("text") .attr("transform", "translate(100,0)") .attr("x", 50).attr("y", 50) .attr("font-size", "20px") .attr("class", "title") .text("Population bar chart") var x = d3.scaleBand().range([0, width]).padding(0.4), y = d3.scaleLinear().range([height, 0]); var g = svg.append("g") .attr("transform", "translate(" + 100 + "," + 100 + ")"); d3.csv("data.csv", function(error, data) { if (error) { throw error; } x.domain(data.map(function(d) { return d.year; })); y.domain([0, d3.max(data, function(d) { return d.population; })]); g.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)) .append("text") .attr("y", height - 250) .attr("x", width - 100) .attr("text-anchor", "end") .attr("font-size", "18px") .attr("stroke", "blue").text("year"); g.append("g") .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", "-5.1em") .attr("text-anchor", "end") .attr("font-size", "18px") .attr("stroke", "blue") .text("population"); g.append("g") .attr("transform", "translate(0, 0)") .call(d3.axisLeft(y)) g.selectAll(".bar") .data(data) .enter() .append("rect") .attr("class", "bar") .on("mouseover", onMouseOver) .on("mouseout", onMouseOut) .attr("x", function(d) { return x(d.year); }) .attr("y", function(d) { return y(d.population); }) .attr("width", x.bandwidth()).transition() .ease(d3.easeLinear).duration(200) .delay(function (d, i) { return i * 25; }) .attr("height", function(d) { return height - y(d.population); }); }); function onMouseOver(d, i) { d3.select(this) .attr('class', 'highlight'); d3.select(this) .transition() .duration(200) .attr('width', x.bandwidth() + 5) .attr("y", function(d) { return y(d.population) - 10; }) .attr("height", function(d) { return height - y(d.population) + 10; }); g.append("text") .attr('class', 'val') .attr('x', function() { return x(d.year); }) .attr('y', function() { return y(d.value) - 10; }) } function onMouseOut(d, i) { d3.select(this) .attr('class', 'bar'); d3.select(this) .transition() .duration(200) .attr('width', x.bandwidth()) .attr("y", function(d) { return y(d.population); }) .attr("height", function(d) { return height - y(d.population); }); d3.selectAll('.val') .remove() } </script> </body> </html> |
حالا مرورگر را درخواست کنید و پاسخ زیر را مشاهده نمایید. (نمودار نواری متحرک در D3.js)
مثال کاربردی با D3.js نیز زده شد. D3 با داشتن محیطی بسیار ساده و انعطاف پذیر ، امکان مصور سازی داده ها را به بهترین شکل ممکن برای کاربران به وجود آورده است.به طور کلی می توان گفت D3 شبیه به Protovis است، اما Protovis برای مصور سازی استاتیک انجام می شود، در حالی که D3 بیشتر روی تعاملی بودن و انتقال داده ها متمرکز شده است.