1<?php 2/* 3** Zabbix 4** Copyright (C) 2001-2021 Zabbix SIA 5** 6** This program is free software; you can redistribute it and/or modify 7** it under the terms of the GNU General Public License as published by 8** the Free Software Foundation; either version 2 of the License, or 9** (at your option) any later version. 10** 11** This program is distributed in the hope that it will be useful, 12** but WITHOUT ANY WARRANTY; without even the implied warranty of 13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14** GNU General Public License for more details. 15** 16** You should have received a copy of the GNU General Public License 17** along with this program; if not, write to the Free Software 18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19**/ 20 21 22/** 23 * @var CView $this 24 */ 25 26$widget = new CWidget(); 27 28if ($data['parent_discoveryid'] === null) { 29 $widget 30 ->setTitle(_('Graphs')) 31 ->setNavigation(getHostNavigation('graphs', $data['hostid'])); 32} 33else { 34 $widget 35 ->setTitle(_('Graph prototypes')) 36 ->setNavigation(getHostNavigation('graphs', $data['hostid'], $data['parent_discoveryid'])); 37} 38 39$url = (new CUrl('graphs.php')) 40 ->setArgument('context', $data['context']) 41 ->getUrl(); 42 43// Create form. 44$graphForm = (new CForm('post', $url)) 45 ->setName('graphForm') 46 ->setAttribute('aria-labeledby', ZBX_STYLE_PAGE_TITLE) 47 ->addVar('form', $this->data['form']) 48 ->addVar('hostid', $this->data['hostid']) 49 ->addVar('ymin_itemid', $this->data['ymin_itemid']) 50 ->addVar('ymax_itemid', $this->data['ymax_itemid']); 51 52if ($data['parent_discoveryid'] !== null) { 53 $graphForm->addItem((new CVar('parent_discoveryid', $data['parent_discoveryid']))->removeId()); 54} 55 56if ($data['graphid'] != 0) { 57 $graphForm->addVar('graphid', $data['graphid']); 58} 59 60// Create form list. 61$graphFormList = new CFormList('graphFormList'); 62 63$is_templated = (bool) $this->data['templates']; 64if ($is_templated) { 65 $graphFormList->addRow(_('Parent graphs'), $data['templates']); 66} 67 68$discovered_graph = false; 69if (array_key_exists('flags', $data) && $data['flags'] == ZBX_FLAG_DISCOVERY_CREATED) { 70 $discovered_graph = true; 71} 72 73$readonly = false; 74if ($is_templated || $discovered_graph) { 75 $readonly = true; 76} 77 78if ($discovered_graph) { 79 $graphFormList->addRow(_('Discovered by'), new CLink($data['discoveryRule']['name'], 80 (new CUrl('graphs.php')) 81 ->setArgument('form', 'update') 82 ->setArgument('parent_discoveryid', $data['discoveryRule']['itemid']) 83 ->setArgument('graphid', $data['graphDiscovery']['parent_graphid']) 84 ->setArgument('context', $data['context']) 85 )); 86} 87 88$graphFormList 89 ->addRow( 90 (new CLabel(_('Name'), 'name'))->setAsteriskMark(), 91 (new CTextBox('name', $this->data['name'], $readonly)) 92 ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH) 93 ->setAriaRequired() 94 ->setAttribute('autofocus', 'autofocus') 95 ) 96 ->addRow((new CLabel(_('Width'), 'width'))->setAsteriskMark(), 97 (new CNumericBox('width', $this->data['width'], 5, $readonly)) 98 ->setWidth(ZBX_TEXTAREA_NUMERIC_STANDARD_WIDTH) 99 ->setAriaRequired() 100 ) 101 ->addRow((new CLabel(_('Height'), 'height'))->setAsteriskMark(), 102 (new CNumericBox('height', $this->data['height'], 5, $readonly)) 103 ->setWidth(ZBX_TEXTAREA_NUMERIC_STANDARD_WIDTH) 104 ->setAriaRequired() 105 ) 106 ->addRow((new CLabel(_('Graph type'), 'label-graphtype')), 107 (new CSelect('graphtype')) 108 ->setId('graphtype') 109 ->setFocusableElementId('label-graphtype') 110 ->setValue($this->data['graphtype']) 111 ->addOptions(CSelect::createOptionsFromArray(graphType())) 112 ->setDisabled($readonly) 113 ) 114 ->addRow(_('Show legend'), 115 (new CCheckBox('show_legend')) 116 ->setChecked($this->data['show_legend'] == 1) 117 ->setEnabled(!$readonly) 118 ); 119 120// Append graph types to form list. 121if ($this->data['graphtype'] == GRAPH_TYPE_NORMAL || $this->data['graphtype'] == GRAPH_TYPE_STACKED) { 122 $graphFormList->addRow(_('Show working time'), 123 (new CCheckBox('show_work_period')) 124 ->setChecked($this->data['show_work_period'] == 1) 125 ->setEnabled(!$readonly) 126 ); 127 $graphFormList->addRow(_('Show triggers'), 128 (new CCheckbox('show_triggers')) 129 ->setchecked($this->data['show_triggers'] == 1) 130 ->setEnabled(!$readonly) 131 ); 132 133 if ($this->data['graphtype'] == GRAPH_TYPE_NORMAL) { 134 // Percent left. 135 $percentLeftTextBox = (new CTextBox('percent_left', $this->data['percent_left'], $readonly, 7)) 136 ->setWidth(ZBX_TEXTAREA_TINY_WIDTH); 137 $percentLeftCheckbox = (new CCheckBox('visible[percent_left]')) 138 ->setChecked(true) 139 ->onClick('javascript: showHideVisible("percent_left");') 140 ->setEnabled(!$readonly); 141 142 if(isset($this->data['visible']) && isset($this->data['visible']['percent_left'])) { 143 $percentLeftCheckbox->setChecked(true); 144 } 145 elseif ($this->data['percent_left'] == 0) { 146 $percentLeftTextBox->addStyle('visibility: hidden;'); 147 $percentLeftCheckbox->setChecked(false); 148 } 149 150 $graphFormList->addRow(_('Percentile line (left)'), [$percentLeftCheckbox, SPACE, $percentLeftTextBox]); 151 152 // Percent right. 153 $percentRightTextBox = (new CTextBox('percent_right', $this->data['percent_right'], $readonly, 7)) 154 ->setWidth(ZBX_TEXTAREA_TINY_WIDTH); 155 $percentRightCheckbox = (new CCheckBox('visible[percent_right]')) 156 ->setChecked(true) 157 ->onClick('javascript: showHideVisible("percent_right");') 158 ->setEnabled(!$readonly); 159 160 if(isset($this->data['visible']) && isset($this->data['visible']['percent_right'])) { 161 $percentRightCheckbox->setChecked(true); 162 } 163 elseif ($this->data['percent_right'] == 0) { 164 $percentRightTextBox->addStyle('visibility: hidden;'); 165 $percentRightCheckbox->setChecked(false); 166 } 167 168 $graphFormList->addRow(_('Percentile line (right)'), [$percentRightCheckbox, SPACE, $percentRightTextBox]); 169 } 170 171 $yaxisMinData = []; 172 $yaxisMinData[] = (new CSelect('ymin_type')) 173 ->setId('ymin_type') 174 ->setValue($this->data['ymin_type']) 175 ->addOptions(CSelect::createOptionsFromArray([ 176 GRAPH_YAXIS_TYPE_CALCULATED => _('Calculated'), 177 GRAPH_YAXIS_TYPE_FIXED => _('Fixed'), 178 GRAPH_YAXIS_TYPE_ITEM_VALUE => _('Item') 179 ])) 180 ->setDisabled($readonly); 181 182 if ($this->data['ymin_type'] == GRAPH_YAXIS_TYPE_FIXED) { 183 $yaxisMinData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN); 184 $yaxisMinData[] = (new CTextBox('yaxismin', $this->data['yaxismin'], $readonly)) 185 ->setWidth(ZBX_TEXTAREA_SMALL_WIDTH); 186 } 187 elseif ($this->data['ymin_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) { 188 $graphForm->addVar('yaxismin', $this->data['yaxismin']); 189 190 $ymin_name = ''; 191 if (!empty($this->data['ymin_itemid'])) { 192 $min_host = get_host_by_itemid($this->data['ymin_itemid']); 193 194 $minItems = CMacrosResolverHelper::resolveItemNames([get_item_by_itemid($this->data['ymin_itemid'])]); 195 $minItem = reset($minItems); 196 197 $ymin_name = $min_host['name'].NAME_DELIMITER.$minItem['name_expanded']; 198 } 199 200 $yaxisMinData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN); 201 $yaxisMinData[] = (new CTextBox('ymin_name', $ymin_name, true)) 202 ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH) 203 ->setAriaRequired(); 204 $yaxisMinData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN); 205 206 // Select item button. 207 $yaxisMinData[] = (new CButton('yaxis_min', _('Select'))) 208 ->addClass(ZBX_STYLE_BTN_GREY) 209 ->onClick('return PopUp("popup.generic",jQuery.extend('. 210 json_encode([ 211 'srctbl' => 'items', 212 'srcfld1' => 'itemid', 213 'srcfld2' => 'name', 214 'dstfrm' => $graphForm->getName(), 215 'dstfld1' => 'ymin_itemid', 216 'dstfld2' => 'ymin_name', 217 'with_webitems' => '1', 218 'numeric' => '1', 219 'writeonly' => '1' 220 ]). 221 ',getOnlyHostParam()), null, this);' 222 ) 223 ->setEnabled(!$readonly); 224 225 // Select item prototype button. 226 if ($data['parent_discoveryid'] !== null) { 227 $yaxisMinData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN); 228 $yaxisMinData[] = (new CButton('yaxis_min_prototype', _('Select prototype'))) 229 ->addClass(ZBX_STYLE_BTN_GREY) 230 ->onClick('return PopUp("popup.generic",'. 231 json_encode([ 232 'srctbl' => 'item_prototypes', 233 'srcfld1' => 'itemid', 234 'srcfld2' => 'name', 235 'dstfrm' => $graphForm->getName(), 236 'dstfld1' => 'ymin_itemid', 237 'dstfld2' => 'ymin_name', 238 'parent_discoveryid' => $data['parent_discoveryid'], 239 'numeric' => '1' 240 ]).', null, this);' 241 ) 242 ->setEnabled(!$readonly); 243 } 244 } 245 else { 246 $graphForm->addVar('yaxismin', $this->data['yaxismin']); 247 } 248 249 $yaxismin_label = new CLabel(_('Y axis MIN value')); 250 if ($this->data['ymin_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) { 251 $yaxismin_label 252 ->setAsteriskMark() 253 ->setAttribute('for', 'ymin_name'); 254 } 255 256 $graphFormList->addRow($yaxismin_label, $yaxisMinData); 257 258 $yaxisMaxData = []; 259 $yaxisMaxData[] = (new CSelect('ymax_type')) 260 ->setId('ymax_type') 261 ->setValue($this->data['ymax_type']) 262 ->addOptions(CSelect::createOptionsFromArray([ 263 GRAPH_YAXIS_TYPE_CALCULATED => _('Calculated'), 264 GRAPH_YAXIS_TYPE_FIXED => _('Fixed'), 265 GRAPH_YAXIS_TYPE_ITEM_VALUE => _('Item') 266 ])) 267 ->setDisabled($readonly); 268 269 if ($this->data['ymax_type'] == GRAPH_YAXIS_TYPE_FIXED) { 270 $yaxisMaxData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN); 271 $yaxisMaxData[] = (new CTextBox('yaxismax', $this->data['yaxismax'], $readonly)) 272 ->setWidth(ZBX_TEXTAREA_SMALL_WIDTH); 273 } 274 elseif ($this->data['ymax_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) { 275 $graphForm->addVar('yaxismax', $this->data['yaxismax']); 276 277 $ymax_name = ''; 278 if (!empty($this->data['ymax_itemid'])) { 279 $max_host = get_host_by_itemid($this->data['ymax_itemid']); 280 281 $maxItems = CMacrosResolverHelper::resolveItemNames([get_item_by_itemid($this->data['ymax_itemid'])]); 282 $maxItem = reset($maxItems); 283 284 $ymax_name = $max_host['name'].NAME_DELIMITER.$maxItem['name_expanded']; 285 } 286 287 $yaxisMaxData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN); 288 $yaxisMaxData[] = (new CTextBox('ymax_name', $ymax_name, true)) 289 ->setWidth(ZBX_TEXTAREA_STANDARD_WIDTH) 290 ->setAriaRequired(); 291 $yaxisMaxData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN); 292 293 // Select item button. 294 $yaxisMaxData[] = (new CButton('yaxis_max', _('Select'))) 295 ->addClass(ZBX_STYLE_BTN_GREY) 296 ->onClick('return PopUp("popup.generic",jQuery.extend('. 297 json_encode([ 298 'srctbl' => 'items', 299 'srcfld1' => 'itemid', 300 'srcfld2' => 'name', 301 'dstfrm' => $graphForm->getName(), 302 'dstfld1' => 'ymax_itemid', 303 'dstfld2' => 'ymax_name', 304 'with_webitems' => '1', 305 'numeric' => '1', 306 'writeonly' => '1' 307 ]). 308 ',getOnlyHostParam()), null, this);' 309 ) 310 ->setEnabled(!$readonly); 311 312 // Select item prototype button. 313 if ($data['parent_discoveryid'] !== null) { 314 $yaxisMaxData[] = (new CDiv())->addClass(ZBX_STYLE_FORM_INPUT_MARGIN); 315 $yaxisMaxData[] = (new CButton('yaxis_max_prototype', _('Select prototype'))) 316 ->addClass(ZBX_STYLE_BTN_GREY) 317 ->onClick('return PopUp("popup.generic",'. 318 json_encode([ 319 'srctbl' => 'item_prototypes', 320 'srcfld1' => 'itemid', 321 'srcfld2' => 'name', 322 'dstfrm' => $graphForm->getName(), 323 'dstfld1' => 'ymax_itemid', 324 'dstfld2' => 'ymax_name', 325 'parent_discoveryid' => $data['parent_discoveryid'], 326 'numeric' => '1' 327 ]).', null, this);' 328 ) 329 ->setEnabled(!$readonly); 330 } 331 } 332 else { 333 $graphForm->addVar('yaxismax', $this->data['yaxismax']); 334 } 335 336 $yaxismax_label = new CLabel(_('Y axis MAX value')); 337 if ($this->data['ymax_type'] == GRAPH_YAXIS_TYPE_ITEM_VALUE) { 338 $yaxismax_label 339 ->setAsteriskMark() 340 ->setAttribute('for', 'ymax_name'); 341 } 342 343 $graphFormList->addRow($yaxismax_label, $yaxisMaxData); 344} 345else { 346 $graphFormList->addRow(_('3D view'), 347 (new CCheckBox('show_3d')) 348 ->setChecked($this->data['show_3d'] == 1) 349 ->setEnabled(!$readonly) 350 ); 351} 352 353// Append items to form list. 354$items_table = (new CTable()) 355 ->setId('itemsTable') 356 ->setColumns([ 357 (new CTableColumn())->addClass('table-col-handle'), 358 (new CTableColumn())->addClass('table-col-no'), 359 (new CTableColumn(_('Name')))->addClass(($this->data['graphtype'] == GRAPH_TYPE_NORMAL) 360 ? 'table-col-name-normal' 361 : 'table-col-name' 362 ), 363 in_array($this->data['graphtype'], [GRAPH_TYPE_PIE, GRAPH_TYPE_EXPLODED]) 364 ? (new CTableColumn(_('Type')))->addClass('table-col-type') 365 : null, 366 (new CTableColumn(_('Function')))->addClass('table-col-function'), 367 ($this->data['graphtype'] == GRAPH_TYPE_NORMAL) 368 ? (new CTableColumn( 369 (new CColHeader(_('Draw style')))->addClass(ZBX_STYLE_NOWRAP) 370 )) 371 ->addClass('table-col-draw-style') 372 : null, 373 in_array($this->data['graphtype'], [GRAPH_TYPE_NORMAL, GRAPH_TYPE_STACKED]) 374 ? (new CTableColumn( 375 (new CColHeader(_('Y axis side')))->addClass(ZBX_STYLE_NOWRAP) 376 )) 377 ->addClass('table-col-y-axis-side') 378 : null, 379 (new CTableColumn(_('Colour')))->addClass('table-col-colour'), 380 $readonly ? null : (new CTableColumn(_('Action')))->addClass('table-col-action') 381 ]); 382 383$popup_options_add = [ 384 'srctbl' => 'items', 385 'srcfld1' => 'itemid', 386 'srcfld2' => 'name', 387 'dstfrm' => $graphForm->getName(), 388 'numeric' => '1', 389 'writeonly' => '1', 390 'multiselect' => '1', 391 'with_webitems' => '1' 392]; 393if ($data['normal_only']) { 394 $popup_options_add['normal_only'] = '1'; 395} 396if ($data['hostid']) { 397 $popup_options_add['hostid'] = $data['hostid']; 398} 399 400$popup_options_add_prototype = [ 401 'srctbl' => 'item_prototypes', 402 'srcfld1' => 'itemid', 403 'srcfld2' => 'name', 404 'dstfrm' => $graphForm->getName(), 405 'numeric' => '1', 406 'writeonly' => '1', 407 'multiselect' => '1', 408 'graphtype' => $data['graphtype'] 409]; 410if ($data['normal_only']) { 411 $popup_options_add_prototype['normal_only'] = '1'; 412} 413if ($data['parent_discoveryid']) { 414 $popup_options_add_prototype['parent_discoveryid'] = $data['parent_discoveryid']; 415} 416 417$items_table->addRow( 418 (new CRow( 419 $readonly 420 ? null 421 : (new CCol( 422 new CHorList([ 423 (new CButton('add_item', _('Add'))) 424 ->onClick('return PopUp("popup.generic",jQuery.extend('. 425 json_encode($popup_options_add).',getOnlyHostParam()), null, this);' 426 ) 427 ->addClass(ZBX_STYLE_BTN_LINK), 428 $data['parent_discoveryid'] 429 ? (new CButton('add_protoitem', _('Add prototype'))) 430 ->onClick('return PopUp("popup.generic",'. 431 json_encode($popup_options_add_prototype).', null, this);' 432 ) 433 ->addClass(ZBX_STYLE_BTN_LINK) 434 : null 435 ]) 436 ))->setColSpan(8) 437 ))->setId('itemButtonsRow') 438); 439 440foreach ($this->data['items'] as $n => $item) { 441 $name = $item['host'].NAME_DELIMITER.$item['name_expanded']; 442 443 if (zbx_empty($item['drawtype'])) { 444 $item['drawtype'] = 0; 445 } 446 447 if (zbx_empty($item['yaxisside'])) { 448 $item['yaxisside'] = 0; 449 } 450 451 if (!array_key_exists('gitemid', $item)) { 452 $item['gitemid'] = ''; 453 } 454 455 insert_js('loadItem('.$n.', '.json_encode($item['gitemid']).', '.$item['itemid'].', '. 456 json_encode($name).', '.$item['type'].', '.$item['calc_fnc'].', '.$item['drawtype'].', '. 457 $item['yaxisside'].', \''.$item['color'].'\', '.$item['flags'].');', 458 true 459 ); 460} 461 462$graphFormList->addRow( 463 (new CLabel(_('Items'), $items_table->getId()))->setAsteriskMark(), 464 (new CDiv($items_table))->addClass(ZBX_STYLE_TABLE_FORMS_SEPARATOR) 465); 466 467if ($data['parent_discoveryid']) { 468 $graphFormList->addRow(_('Discover'), 469 (new CCheckBox('discover', ZBX_PROTOTYPE_DISCOVER)) 470 ->setChecked($data['discover'] == ZBX_PROTOTYPE_DISCOVER) 471 ->setUncheckedValue(ZBX_PROTOTYPE_NO_DISCOVER) 472 ); 473} 474 475// Append tabs to form. 476$graphTab = (new CTabView()) 477 ->setSelected(0) 478 ->addTab('graphTab', ($data['parent_discoveryid'] === null) ? _('Graph') : _('Graph prototype'), $graphFormList); 479 480/* 481 * Preview tab 482 */ 483$graphPreviewTable = (new CTable()) 484 ->addStyle('width: 100%;') 485 ->addRow( 486 (new CRow( 487 (new CDiv())->setId('previewChart') 488 ))->addClass(ZBX_STYLE_CENTER) 489 ); 490$graphTab->addTab('previewTab', _('Preview'), $graphPreviewTable); 491 492// Append buttons to form. 493if ($data['graphid'] != 0) { 494 $updateButton = new CSubmit('update', _('Update')); 495 $deleteButton = new CButtonDelete( 496 ($data['parent_discoveryid'] === null) ? _('Delete graph?') : _('Delete graph prototype?'), 497 url_params(['graphid', 'parent_discoveryid', 'hostid', 'context']), 'context' 498 ); 499 500 if ($readonly) { 501 $updateButton->setEnabled(false); 502 } 503 504 if ($is_templated) { 505 $deleteButton->setEnabled(false); 506 } 507 508 $graphTab->setFooter(makeFormFooter( 509 $updateButton, [ 510 new CSubmit('clone', _('Clone')), 511 $deleteButton, 512 new CButtonCancel(url_params(['parent_discoveryid', 'context']).url_param('hostid', $data['hostid'])) 513 ] 514 )); 515} 516else { 517 $graphTab->setFooter(makeFormFooter( 518 new CSubmit('add', _('Add')), 519 [new CButtonCancel(url_params(['parent_discoveryid', 'context']).url_param('hostid', $data['hostid']))] 520 )); 521} 522 523$graph_item_drawtypes = []; 524foreach (graph_item_drawtypes() as $drawtype) { 525 $graph_item_drawtypes[$drawtype] = graph_item_drawtype2str($drawtype); 526} 527 528// Insert js (depended from some variables inside the file). 529require_once dirname(__FILE__).'/js/configuration.graph.edit.js.php'; 530 531$graphForm->addItem($graphTab); 532 533// Append form to widget. 534$widget->addItem($graphForm); 535 536$widget->show(); 537