{"id":74,"date":"2008-02-11T00:30:38","date_gmt":"2008-02-11T04:30:38","guid":{"rendered":"http:\/\/ryepup.unwashedmeme.com\/blog\/2008\/02\/11\/the-beginnings-of-bar-charts\/"},"modified":"2008-02-11T00:38:58","modified_gmt":"2008-02-11T04:38:58","slug":"the-beginnings-of-bar-charts","status":"publish","type":"post","link":"http:\/\/ryepup.unwashedmeme.com\/blog\/2008\/02\/11\/the-beginnings-of-bar-charts\/","title":{"rendered":"the beginnings of bar charts"},"content":{"rendered":"<p>Spent a ton of time today playing with adw-charting.  I wanted to expand on the source contributor graphs from the other day, and ended up implementing some basic bar chart functionality.<\/p>\n<p>I&#8217;ve read a lot of complaints about the lack of lisp libraries, so whenever I sit down to do some random task, I try to use libraries as much as I can to test the validity of those complaints.  I also learn a lot by reading and experimenting with other people&#8217;s code, and slowly I can see my style getting more lispish, and less C#-ish.  clbuild makes it trivial to get many libraries usable, and today I had good luck with everything just working.<\/p>\n<p>I used darcs as my source of dataset, its xml changes output has a simply formatted time string.  I told clbuild to install <a href=\"http:\/\/common-lisp.net\/project\/cxml\/\">closure xml<\/a> (cxml), and in fairly short order I had a 80 line program that:<\/p>\n<ol>\n<li>uses the <a href=\"http:\/\/common-lisp.net\/project\/cxml\/klacks.html\">cxml klacks<\/a> system to pull the information I wanted out of the file in one pass<\/li>\n<li>uses <a href=\"http:\/\/www.weitz.de\/cl-ppcre\/\">cl-ppcre<\/a> to parse the username out of the darcs author string, so authors &#8220;Ryan Davis &lt;ryan@acc&#8230;&#8221; and &#8220;ryan@acce&#8230;&#8221; both get displayed as &#8220;ryan&#8221;.<\/li>\n<li>uses <a href=\"http:\/\/common-lisp.net\/project\/adw-charting\/\">adw-charting<\/a> to chart patches per day into a png<\/li>\n<\/ol>\n<p>The result was less than spectacular:<\/p>\n<p><a href=\"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-content\/uploads\/2008\/02\/darcs.png\" title=\"darcs.png\"><img decoding=\"async\" src=\"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-content\/uploads\/2008\/02\/darcs.thumbnail.png\" alt=\"darcs.png\" \/><\/a><\/p>\n<p>The chart looks pretty nice, but its lying horribly.  My data set didn&#8217;t have explicit zeros for days without activity, so the line goes from one active day to another, telling all kinds of lies.  My favorite is the 2.5 patches it says I pushed on 1\/11.  The other fun one is that Russ shows up in the legend, but his one patch isn&#8217;t visible at all, because there was only one data point, and you need two points to make a line.<\/p>\n<p>What is really appropriate here is a bar chart.  Adding explicit zeros is a waste of time and RAM (among other things), so I opted for making a bar chart type.  After many more hours of coding, I changed with-line-chart to with-bar-chart and re-ran my program:<\/p>\n<p><a href=\"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-content\/uploads\/2008\/02\/darcs1.png\" title=\"darcs1.png\"><img decoding=\"async\" src=\"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-content\/uploads\/2008\/02\/darcs1.thumbnail.png\" alt=\"darcs1.png\" \/><\/a><\/p>\n<p>Much better.  There&#8217;s a few rendering problems, but the data is shown alright.<\/p>\n<p>Adding support for bar charts was actually really easy, it was going back and reworking my amatuerish code that took most of the time.  My big accomplishments:<\/p>\n<ul>\n<li>deleted a lot of code by using <a href=\"http:\/\/www.lispworks.com\/documentation\/HyperSpec\/Body\/m_w_acce.htm\">with-accessors<\/a><\/li>\n<li>made all usage of x\/y points go through 3 functions: make-point, x, and y, allowing for easily changing the internal representation of points in the future<\/li>\n<li>removed some slots from an object, replacing it with a few functions to calculate the desired value<\/li>\n<li>added a few more generic functions to support bar charts<\/li>\n<li>reduced the size of the legend<\/li>\n<\/ul>\n<p>After working on the line chart code for awhile, adding bar charts was trivial: one class that extends line-chart, one macro to mirror with-line-chart, one method to draw bars instead of lines, and a couple of helper functions.  I was really pleased with how easy it was to add the different graphing mode.<\/p>\n<p>Of course, giving another dataset exposes more problems:<\/p>\n<p><a href=\"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-content\/uploads\/2008\/02\/darcs2.png\" title=\"darcs2.png\"><img decoding=\"async\" src=\"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-content\/uploads\/2008\/02\/darcs2.thumbnail.png\" alt=\"darcs2.png\" \/><\/a><\/p>\n<p>That&#8217;s for clbuild, and there are a few issues apparent here:<\/p>\n<ul>\n<li>when more than one bar is shown for one day, it draws them next to each other, which makes it hard to tell where on the bar is on the x-axis<\/li>\n<li>the legend wanders off the edge<\/li>\n<li>the month\/day labels aren&#8217;t very descriptive<\/li>\n<\/ul>\n<p>I think I&#8217;m going to solve the first two issues by allowing a summarize mode, where less significant series can be aggregated into a single &#8220;other&#8221; series.  This is how I see a lot of other programs solve it, so I&#8217;ll give that a shot.  I don&#8217;t think that will completely solve the first issue, but should alleviate it a little bit.<\/p>\n<p>The last issue I solved by making a function to show patches by month instead of by day:<\/p>\n<p><a href=\"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-content\/uploads\/2008\/02\/darcs3.png\" title=\"darcs3.png\"><img decoding=\"async\" src=\"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-content\/uploads\/2008\/02\/darcs3.thumbnail.png\" alt=\"darcs3.png\" \/><\/a><\/p>\n<p>That shows the side-by-side bars problem pretty clearly, but what I find most interesting is the right side of the chart where we see more people starting to contribute.  I think that&#8217;s indicative of the project gaining more users and activity.<\/p>\n<p>Another interesting one, arnesi:<\/p>\n<p><a href=\"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-content\/uploads\/2008\/02\/darcs4.png\" title=\"darcs4.png\"><img decoding=\"async\" src=\"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-content\/uploads\/2008\/02\/darcs4.thumbnail.png\" alt=\"darcs4.png\" \/><\/a><\/p>\n<p>Early on, Marco Baringer was the driving force, but somewhere around the middle of 2006 I guess he had finished scratching all his itches, and Atilla Lendvai became the prime mover.<\/p>\n<p>Alright, I could seriously speculate about these things all night, so I&#8217;m gonna stop now.<\/p>\n<p>I still need to fix the above-mentioned bar chart issues, so there&#8217;s no new release of adw-charting, but all the code mentioned here is in the public darcs repository (http:\/\/common-lisp.net\/project\/adw-charting\/darcs\/) for the curious.<\/p>\n<p>See the examples folder for the darc-changes graphing program, you need to get the xml from darcs using: darcs changes &#8211;xml.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Spent a ton of time today playing with adw-charting. I wanted to expand on the source contributor graphs from the other day, and ended up implementing some basic bar chart functionality. I&#8217;ve read a lot of complaints about the lack of lisp libraries, so whenever I sit down to do some random task, I try [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[22,15,8],"tags":[],"class_list":["post-74","post","type-post","status-publish","format-standard","hentry","category-adw-charting","category-lisp","category-open-source"],"_links":{"self":[{"href":"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-json\/wp\/v2\/posts\/74","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-json\/wp\/v2\/comments?post=74"}],"version-history":[{"count":0,"href":"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-json\/wp\/v2\/posts\/74\/revisions"}],"wp:attachment":[{"href":"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-json\/wp\/v2\/media?parent=74"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-json\/wp\/v2\/categories?post=74"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/ryepup.unwashedmeme.com\/blog\/wp-json\/wp\/v2\/tags?post=74"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}