در این پروژه می خواهم نموداری بکشم که توزیع زمان اتفاق افتادن تعداد زیادی رویداد را نشان دهد.
دو تا از دوستانم روی پروژه ی وقوع راهبردهای کلامی (مثل هم پوشانی یا overlap، قطع صحبت یا interruption و وقفه یا pause) در کلاس های دانشگاهی پژوهش می کردند. برای بررسی این راهبردها، صدای کلاس ها را ضبط کرده و زمان وقوع هر راهبرد را (بر حسب ثانیه) مشخص کرده بودند. به ذهنم رسید که برای نشان دادن توزیع این رویدادها از یک نمودار زمانی استفاده کنم. نموداری که ثانیه های کلاس روی آن مشخص باشد و زمان وقوع هر رویداد روی هر ثانیه مشخص شود. چیزی مثل timeline اما ساده تر و برای ثانیه ها.
نمی دانستم نمودار مشابه یا آماده ای وجود دارد یا نه. بنابراین به ذهنم رسید که از یک جدول html استفاده کنم. باید جدولی می کشیدم با یک ردیف و حداقل 5400 ستون که هر ستون نشانگر یک ثانیه باشد و هر ثانیه ای که در آن یکی از راهبردها رخ داده، رنگی شود.
خب! اولین کار کشیدن یک جدول ساده ی htmlی بود:
<table> <tr> <td> </td> <td> </td> </td> </table>
این جدول، جدولی با یک ردیف و دو ستون خالی است. مشکل این است که بدون استایل دادن، این جدول دیده نمی شود! پس یک استایل ساده هم می نویسیم:
<style> table, td { border: 1px solid black; } table { border-collapse: collapse; } td { width: 1px; height: 10px; } </style>
حالا جدولی با 5400 ستون می خواهیم. برای این کار از php استفاده می کنیم:
<body> <table> <tr> <?php for ($j=1; $j <5400; $j++) { echo "<td></td>" } ?> </tr> </table> </body>
مشکل این جاست که چنین جدولی در صفحه نمایشگر نمایش داده نمی شود و با scroll افقی قابل دیدن است. چیزی مثل تصویر زیر.
از طرفی هم حداکثر عرض یک سلول جدول 1 پیکسل می تواند باشد (تا در صفحه نمایش قابل دیدن باشد). پس نمی توان خانه ها را کوچکتر کرد. بنابراین به جای یک ردیف، از چند ردیف با تعداد سلول کمتر استفاده می کنیم. برای این کار از دو حلقه ی for استفاده می کنیم:
<body> <?php for($i=0; $i<=5000; $i+=500) { echo "<table><tr>" for ($j=$i; $j < $i+500; $j++) { echo "<td></td>" } echo "</tr></table>" } ?> </body>
نتیجه جدول زیر می شود:
برای این که بتوانیم ثانیه های اول و آخر هر ردیف را هم نمایش دهیم، مورد زیر را به استایل اضافه می کنیم:
table { margin-bottom: 20px; }
و عدد اول و آخر هر ردیف را هم می نویسیم:
<body> <?php for($i=0; $i<=5000; $i+=500) { $min_i = $i; $max_i = $i+500; echo " <div> <span style='float: left'>$min_i</span> <span style='float: right'>$max_i</span> </div>" echo "<table><tr>" for ($j=$i; $j < $i+500; $j++) { echo "<td></td>" } echo "</tr></table>" } ?> </body>
نتیجه جدول زیر می شود:
خب تقریبن نمودار ما آماده ی پرشدن است. حالا باید مشخص کنیم که چه خانه هایی پر شوند. داده های من در یک فایل csv قرار دارند که هر خط آن مانند زیر است. عدد اول نشان دهنده ی نوع راهبرد و عدد دوم ثانیه ی وقوع راهبرد است.
1,1063
من می خواهم به ازای هر نوع راهبرد یک رنگ تعیین کنم و خانه ی مربوط به ثانیه ی وقوع آن راهبرد را رنگی کنم. پس اول باید مشخص کنم که هر خانه چه عددی دارد. برای این کار در همان حلقه یک آی دی به هر td اختصاص می دهیم:
echo "<td id='td-$j'></td>"
و بعد در یک حلقه ی دیگر (در style) به هر td بر حسب نوع راهبردش یک رنگ اختصاص می دهیم (این کار را با تعریف یک کلاس برای هر نوع راهبرد هم می شد انجام داد اما در آن صورت، حلقه ی خواندن فایل csv را هم باید با دو حلقه ی ساخت جدول ترکیب می کردیم):
<?php $data_file = fopen("data.csv", "r"); while( ($data_line = fgetcsv($data_file)) !== FALSE) { $time = $data_line[1]; $method1_color = "#FF00FF" //صورتی $method2_color = "#AFEEEE" //فیروزه ای $method3_color = "#000000" //سیاه $method_type = $data_line[0]; if ($method_type == 1) { $color = $method1_color; } elseif ($method_type == 2) { $color = $method2_color; } elseif ($method_type == 3) { $color = $method3_color; } echo "#td-$time { background-color: $color; }" } ?>
نتیجه چنین شکلی می شود:
کل کد این پروژه را در گیتهاب گذاشتم.
اگر بخواهیم تصویری کلی از زمان وقوع رویدادها داشته باشیم می توانیم از چنین نموداری استفاده کنیم تا بفهمیم رویدادها در چه بخش هایی بیشتر رخ داده اند و در چه بخش هایی کمتر.