summaryrefslogtreecommitdiffstats
path: root/library/Icinga/Web/Widget/Chart/InlinePie.php
blob: 21b4ca490d963ffab8d50eadf941d2e539877442 (plain)
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
<?php
/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */

namespace Icinga\Web\Widget\Chart;

use Icinga\Chart\PieChart;
use Icinga\Module\Monitoring\Plugin\PerfdataSet;
use Icinga\Util\StringHelper;
use Icinga\Web\Widget\AbstractWidget;
use Icinga\Web\Url;
use Icinga\Util\Format;
use Icinga\Application\Logger;
use Icinga\Exception\IcingaException;
use stdClass;

/**
 * A SVG-PieChart intended to be displayed as a small icon next to labels, to offer a better visualization of the
 * shown data
 *
 * NOTE: When InlinePies are shown in a dynamically loaded view, like the side-bar or in the dashboard, the SVGs will
 * be replaced with a jQuery-Sparkline to save resources @see loader.js
 *
 * @package Icinga\Web\Widget\Chart
 */
class InlinePie extends AbstractWidget
{
    const NUMBER_FORMAT_NONE = 'none';
    const NUMBER_FORMAT_TIME = 'time';
    const NUMBER_FORMAT_BYTES = 'bytes';
    const NUMBER_FORMAT_RATIO = 'ratio';

    public static $colorsHostStates = array(
        '#44bb77', // up
        '#ff99aa', // down
        '#cc77ff', // unreachable
        '#77aaff'  // pending
    );

    public static $colorsHostStatesHandledUnhandled = array(
        '#44bb77', // up
        '#44bb77',
        '#ff99aa', // down
        '#ff5566',
        '#cc77ff', // unreachable
        '#aa44ff',
        '#77aaff', // pending
        '#77aaff'
    );

    public static $colorsServiceStates = array(
        '#44bb77', // Ok
        '#ffaa44', // Warning
        '#ff99aa', // Critical
        '#aa44ff', // Unknown
        '#77aaff'  // Pending
    );

    public static $colorsServiceStatesHandleUnhandled = array(
        '#44bb77', // Ok
        '#44bb77',
        '#ffaa44', // Warning
        '#ffcc66',
        '#ff99aa', // Critical
        '#ff5566',
        '#cc77ff', // Unknown
        '#aa44ff',
        '#77aaff', // Pending
        '#77aaff'
    );

    /**
     * The template string used for rendering this widget
     *
     * @var string
     */
    private $template = '<div class="inline-pie {class}">{svg}</div>';

    /**
     * The colors used to display the slices of this pie-chart.
     *
     * @var array
     */
    private $colors = array('#049BAF', '#ffaa44', '#ff5566', '#ddccdd');

    /**
     * The title of the chart
     *
     * @var string
     */
    private $title;

    /**
     * @var int
     */
    private $size = 16;

    /**
     * The data displayed by the pie-chart
     *
     * @var array
     */
    private $data;

    /**
     * @var
     */
    private $class = '';

    /**
     * Set the data to be displayed.
     *
     * @param   $data array
     *
     * @return  $this
     */
    public function setData(array $data)
    {
        $this->data = $data;

        return $this;
    }

    /**
     * Set the size of the inline pie
     *
     * @param int $size     Sets both, the height and width
     *
     * @return $this
     */
    public function setSize($size = null)
    {
        $this->size = $size;

        return $this;
    }

    /**
     * Set the class to define the
     *
     * @param  $class
     *
     * @return $this
     */
    public function setSparklineClass($class)
    {
        $this->class = $class;

        return $this;
    }

    /**
     * Set the colors used by the slices of the pie chart.
     *
     * @param   array $colors
     *
     * @return  $this
     */
    public function setColors(array $colors = null)
    {
        $this->colors = $colors;

        return $this;
    }

    /**
     * Set the title of the displayed Data
     *
     * @param   string $title
     *
     * @return  $this
     */
    public function setTitle($title)
    {
        $this->title = $this->view()->escape($title);

        return $this;
    }

    /**
     * Create a new InlinePie
     *
     * @param array  $data      The data displayed by the slices
     * @param string $title     The title of this Pie
     * @param array  $colors    An array of RGB-Color values to use
     */
    public function __construct(array $data, $title, $colors = null)
    {
        $this->setTitle($title);

        if (array_key_exists('data', $data)) {
            $this->data = $data['data'];
            if (array_key_exists('colors', $data)) {
                $this->colors = $data['colors'];
            }
        } else {
            $this->setData($data);
        }

        if (isset($colors)) {
            $this->setColors($colors);
        } else {
            $this->setColors($this->colors);
        }
    }

    /**
     * Renders this widget via the given view and returns the
     * HTML as a string
     *
     * @return string
     */
    public function render()
    {
        $pie = new PieChart();
        $pie->alignTopLeft();
        $pie->disableLegend();
        $pie->drawPie([
            'data'      => $this->data,
            'colors'    => $this->colors
        ]);

        if ($this->view()->layout()->getLayout() === 'pdf') {
            try {
                $png = $pie->toPng($this->size, $this->size);
                return '<img class="inlinepie" src="data:image/png;base64,' . base64_encode($png) . '" />';
            } catch (IcingaException $_) {
                return '';
            }
        }

        $pie->title = $this->title;
        $pie->description = $this->title;

        $template = $this->template;
        $template = str_replace('{class}', $this->class, $template);
        $template = str_replace('{svg}', $pie->render(), $template);

        return $template;
    }

    public static function createFromStateSummary(stdClass $states, $title, array $colors)
    {
        $handledUnhandledStates = [];
        foreach ($states as $key => $value) {
            if (StringHelper::endsWith($key, '_handled') || StringHelper::endsWith($key, '_unhandled')) {
                $handledUnhandledStates[$key] = $value;
            }
        }

        $chart = new self(array_values($handledUnhandledStates), $title, $colors);

        return $chart
            ->setSize(50)
            ->setTitle('')
            ->setSparklineClass('sparkline-multi');
    }
}