TQ
dev.com

Blog about software development

Subscribe

Celebrating 3 years TQdev

09 May 2019 - by 'Maurits van der Schee'

Today I am celebrating the 3 years that the TQdev.com blog exists. In this period I have written 125 blog posts on various software development related topics. Best visited post was the "The "Boring Software" manifesto" with more than 33 thousand visitors. Below you find the visitors of the blog per month.

Visitors graph

The graph below is a (copy of) a server side generated SVG document from the backend of this blog.

2019-052019-05: 31242019-042019-04: 146252019-032019-03: 102322019-022019-02: 92672019-012019-01: 131032018-122018-12: 92992018-112018-11: 115672018-102018-10: 115112018-092018-09: 113502018-082018-08: 88152018-072018-07: 203562018-062018-06: 251342018-052018-05: 65562018-042018-04: 66342018-032018-03: 76252018-022018-02: 71092018-012018-01: 97492017-122017-12: 79542017-112017-11: 98752017-102017-10: 144922017-092017-09: 66732017-082017-08: 80302017-072017-07: 88482017-062017-06: 87772017-052017-05: 80942017-042017-04: 75012017-032017-03: 75742017-022017-02: 67842017-012017-01: 77732016-122016-12: 72402016-112016-11: 95022016-102016-10: 99542016-092016-09: 74282016-082016-08: 77582016-072016-07: 118752016-062016-06: 62372016-052016-05: 43782016-042016-04: 77812016-032016-03: 51182016-022016-02: 97Unique visitors per month5000040000300002000010000

NB: Visitors are counted based on the different IP address in the log per day, e.g. a visitor is defined as a unique IP address on a day.

The code

This is the code that generates the above graph:

<?php
function verticalBar($values, $height, $title = '')
{
    if (count($values)) {
        $real_max = max($values);
    } else {
        $real_max = 100;
    }
    $max = pow(10, ceil(log10($real_max)));
    while ($max / 2 > $real_max) {
        $max /= 2;
    }
    $html = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0" y="0" width="100%" height="' . $height . '">';
    $html .= '<rect width="100%" height="100%" fill="#eee" style="stroke:#aaa;stroke-width:2px;"/>';
    for ($i = 0; $i < 10; $i++) {
        $top = ($i / 10 * $height);
        if ($i % 2 == 0) {
            $html .= '<line x1="0" y1="' . $top . '" x2="100%" y2="' . $top . '" style="stroke:#aaa;" />';
        } else {
            $html .= '<line x1="0" y1="' . $top . '" x2="100%" y2="' . $top . '" style="stroke:#ccc;" />';
        }
    }
    $c = count($values);
    if ($c) {
        $i = 0;
        foreach ($values as $key => $value) {
            $p = round(100 * ($value / $max));
            $hover = is_string($key) ? $key . ': ' . $value : $value;
            $html .= '<g>';
            $margin = 0.25;
            $html .= '<rect x="' . (($c - $i - 1) * (100 / $c) + $margin) . '%" y="' . (100 - $p) . '%" width="' . (100 / $c - 2 * $margin) . '%" height="' . $p . '%" style="fill:#bbb"/>';
            if (is_string($key)) {
                $html .= '<text x="' . (($c - $i - .5) * (100 / $c)) . '%" y="' . (100 - $p) . '%" style="writing-mode: sideways-lr;font-size: 75%;dominant-baseline:middle;text-anchor:start;fill:#eee;" transform="translate(1,4)">' . $key . '</text>';
            }
            $html .= '<title>' . $hover . '</title>';
            $html .= '</g>';
            $i++;
        }
    }
    $html .= '<text x="50%" y="0" style="dominant-baseline:hanging;text-anchor:middle" transform="translate(0,2)">' . $title . '</text>';
    for ($i = 0; $i < 10; $i++) {
        $top = ($i / 10 * $height);
        $text = ((1 - $i / 10) * $max);
        if ($i % 2 == 0) {
            $html .= '<line x1="0" y1="' . $top . '" x2="9" y2="' . $top . '" style="stroke:#000;" />';
            $html .= '<text x="0" y="' . $top . '" style="dominant-baseline:hanging;text-anchor:start" transform="translate(2,2)">' . $text . '</text>';
        } else {
            $html .= '<line x1="0" y1="' . $top . '" x2="6" y2="' . $top . '" style="stroke:#000;" />';
        }
    }
    $html .= '</svg>';
    return $html;
}

verticalBar(['2018-06'=>25134,'2018-07'=>20356,...], 500, 'Unique visitors per month');

You may want style it different, but that should not be too hard.


PS: Liked this article? Please share it on Facebook, Twitter or LinkedIn.