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