diff --git a/pandora_console/include/rest-api/models/VisualConsole/Items/BarsGraph.php b/pandora_console/include/rest-api/models/VisualConsole/Items/BarsGraph.php
new file mode 100644
index 0000000000..6554401981
--- /dev/null
+++ b/pandora_console/include/rest-api/models/VisualConsole/Items/BarsGraph.php
@@ -0,0 +1,355 @@
+extractGridColor($data);
+ $return['backgroundColor'] = $this->extractBackgroundColor($data);
+ $return['typeGraph'] = $this->extractTypeGraph($data);
+ return $return;
+ }
+
+
+ /**
+ * Extract a grid color value.
+ *
+ * @param array $data Unknown input data structure.
+ *
+ * @return mixed String representing the grid color (not empty) or null.
+ */
+ private function extractGridColor(array $data)
+ {
+ return static::notEmptyStringOr(
+ static::issetInArray(
+ $data,
+ [
+ 'gridColor',
+ 'border_color',
+ ]
+ ),
+ null
+ );
+ }
+
+
+ /**
+ * Extract a background color value.
+ *
+ * @param array $data Unknown input data structure.
+ *
+ * @return string One of 'white', 'black' or 'transparent'. 'white' by default.
+ */
+ private function extractBackgroundColor(array $data): string
+ {
+ $backgroundColor = static::notEmptyStringOr(
+ static::issetInArray(
+ $data,
+ [
+ 'backgroundColor',
+ 'image',
+ ]
+ ),
+ null
+ );
+
+ switch ($backgroundColor) {
+ case 'black':
+ case 'transparent':
+ return $backgroundColor;
+
+ default:
+ return 'white';
+ }
+ }
+
+
+ /**
+ * Extract a type graph value.
+ *
+ * @param array $data Unknown input data structure.
+ *
+ * @return string One of 'vertical' or 'horizontal'. 'vertical' by default.
+ */
+ private function extractTypeGraph(array $data): string
+ {
+ $typeGraph = static::notEmptyStringOr(
+ static::issetInArray(
+ $data,
+ [
+ 'typeGraph',
+ 'type_graph',
+ ]
+ ),
+ null
+ );
+
+ switch ($typeGraph) {
+ case 'vertical':
+ return 'vertical';
+
+ default:
+ return 'horizontal';
+ }
+ }
+
+
+ /**
+ * Fetch a vc item data structure from the database using a filter.
+ *
+ * @param array $filter Filter of the Visual Console Item.
+ *
+ * @return array The Visual Console Item data structure stored into the DB.
+ * @throws \InvalidArgumentException When an agent Id cannot be found.
+ *
+ * @override Item::fetchDataFromDB.
+ */
+ protected static function fetchDataFromDB(array $filter): array
+ {
+ // Due to this DB call, this function cannot be unit tested without
+ // a proper mock.
+ $data = parent::fetchDataFromDB($filter);
+
+ /*
+ * Retrieve extra data.
+ */
+
+ // Load config.
+ global $config;
+
+ // Extract needed properties.
+ $gridColor = static::extractGridColor($data);
+ $backGroundColor = static::extractBackgroundColor($data);
+ $typeGraph = static::extractTypeGraph($data);
+
+ // Get the linked agent and module Ids.
+ $linkedModule = static::extractLinkedModule($data);
+ $agentId = $linkedModule['agentId'];
+ $moduleId = $linkedModule['moduleId'];
+ $metaconsoleId = $linkedModule['metaconsoleId'];
+
+ if ($agentId === null) {
+ throw new \InvalidArgumentException('missing agent Id');
+ }
+
+ if ($moduleId === null) {
+ throw new \InvalidArgumentException('missing module Id');
+ }
+
+ // Add colors that will use the graphics.
+ $color = [];
+
+ $color[0] = [
+ 'border' => '#000000',
+ 'color' => $config['graph_color1'],
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+ $color[1] = [
+ 'border' => '#000000',
+ 'color' => $config['graph_color2'],
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+ $color[2] = [
+ 'border' => '#000000',
+ 'color' => $config['graph_color3'],
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+ $color[3] = [
+ 'border' => '#000000',
+ 'color' => $config['graph_color4'],
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+ $color[4] = [
+ 'border' => '#000000',
+ 'color' => $config['graph_color5'],
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+ $color[5] = [
+ 'border' => '#000000',
+ 'color' => $config['graph_color6'],
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+ $color[6] = [
+ 'border' => '#000000',
+ 'color' => $config['graph_color7'],
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+ $color[7] = [
+ 'border' => '#000000',
+ 'color' => $config['graph_color8'],
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+ $color[8] = [
+ 'border' => '#000000',
+ 'color' => $config['graph_color9'],
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+ $color[9] = [
+ 'border' => '#000000',
+ 'color' => $config['graph_color10'],
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+ $color[11] = [
+ 'border' => '#000000',
+ 'color' => COL_GRAPH9,
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+ $color[12] = [
+ 'border' => '#000000',
+ 'color' => COL_GRAPH10,
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+ $color[13] = [
+ 'border' => '#000000',
+ 'color' => COL_GRAPH11,
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+ $color[14] = [
+ 'border' => '#000000',
+ 'color' => COL_GRAPH12,
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+ $color[15] = [
+ 'border' => '#000000',
+ 'color' => COL_GRAPH13,
+ 'alpha' => CHART_DEFAULT_ALPHA,
+ ];
+
+ // Maybe connect to node.
+ $nodeConnected = false;
+ if (\is_metaconsole() === true && $metaconsoleId !== null) {
+ $nodeConnected = \metaconsole_connect(
+ null,
+ $metaconsoleId
+ ) === NOERR;
+
+ if ($nodeConnected === false) {
+ throw new \InvalidArgumentException(
+ 'error connecting to the node'
+ );
+ }
+ }
+
+ $module_data = \get_bars_module_data($moduleId);
+
+ $water_mark = [
+ 'file' => $config['homedir'].'/images/logo_vertical_water.png',
+ 'url' => \ui_get_full_url(false, false, false, false).'images/logo_vertical_water.png',
+ ];
+
+ switch ($data['label_position']) {
+ case 'left':
+ $div_start = '
';
+ $div_end = '
';
+ break;
+
+ case 'right':
+ $div_start = '';
+ $div_end = '
';
+ break;
+
+ default:
+ $div_start = '';
+ $div_end = '';
+ break;
+ }
+
+ if ((int) $data['width'] === 0 || (int) $data['height'] === 0) {
+ $width = 400;
+ $height = 400;
+ } else {
+ $width = (int) $data['width'];
+ $height = (int) $data['height'];
+ }
+
+ if ($typeGraph === 'horizontal') {
+ $graph = $div_start.\hbar_graph(
+ $module_data,
+ $width,
+ $height,
+ $color,
+ [],
+ [],
+ \ui_get_full_url('images/image_problem_area.png', false, false, false),
+ '',
+ '',
+ $water_mark,
+ $config['fontpath'],
+ 6,
+ '',
+ 0,
+ $config['homeurl'],
+ $backGroundColor,
+ $gridColor
+ ).$div_end;
+ } else {
+ $graph = $div_start.\vbar_graph(
+ $module_data,
+ $width,
+ $height,
+ $color,
+ [],
+ [],
+ \ui_get_full_url('images/image_problem_area.png', false, false, false),
+ '',
+ '',
+ $water_mark,
+ $config['fontpath'],
+ 6,
+ '',
+ 0,
+ $config['homeurl'],
+ $backGroundColor,
+ true,
+ false,
+ $gridColor
+ ).$div_end;
+ }
+
+ // Restore connection.
+ if ($nodeConnected === true) {
+ \metaconsole_restore_db();
+ }
+
+ $data['html'] = $graph;
+ return $data;
+ }
+
+
+}
diff --git a/pandora_console/tests/Functional/Models/VisualConsole/Items/BarsGraphTest.php b/pandora_console/tests/Functional/Models/VisualConsole/Items/BarsGraphTest.php
new file mode 100644
index 0000000000..16866a4fc6
--- /dev/null
+++ b/pandora_console/tests/Functional/Models/VisualConsole/Items/BarsGraphTest.php
@@ -0,0 +1,111 @@
+assertInstanceOf(
+ BarsGraph::class,
+ BarsGraph::fromArray(
+ [
+ 'id' => 7,
+ 'type' => BARS_GRAPH,
+ 'width' => '600',
+ 'height' => '500',
+ 'typeGraph' => 'horizontal',
+ 'backgroundColor' => 'white',
+ 'gridColor' => '#33CCFF',
+ 'encodedHtml' => 'Foo
',
+ ]
+ )
+ );
+
+ $this->assertInstanceOf(
+ BarsGraph::class,
+ BarsGraph::fromArray(
+ [
+ 'id' => 23,
+ 'type' => BARS_GRAPH,
+ 'width' => '800',
+ 'height' => '600',
+ 'type_graph' => 'vertical',
+ 'image' => 'transparent',
+ 'border_color' => '#33CCFF',
+ 'html' => 'Foo
',
+ ]
+ )
+ );
+ }
+
+
+ /**
+ * Test if the model has a valid JSON representation.
+ *
+ * @return void
+ */
+ public function testContainerIsRepresentedAsJson(): void
+ {
+ $this->assertEquals(
+ '{"aclGroupId":null,"agentId":null,"agentName":null,"backgroundColor":"transparent","encodedHtml":"PGgxPkZvbzwvaDE+","gridColor":"#33CCFF","height":0,"id":7,"isLinkEnabled":true,"isOnTop":false,"label":null,"labelPosition":"up","moduleId":null,"moduleName":null,"parentId":null,"type":18,"typeGraph":"vertical","width":0,"x":-666,"y":76}',
+ (string) BarsGraph::fromArray(
+ [
+ 'id' => 7,
+ 'type' => DONUT_GRAPH,
+ 'label' => null,
+ 'labelPosition' => 'up',
+ 'isLinkEnabled' => true,
+ 'isOnTop' => false,
+ 'parentId' => null,
+ 'width' => '0',
+ 'height' => '0',
+ 'x' => -666,
+ 'y' => 76,
+ 'type_graph' => 'vertical',
+ 'image' => 'transparent',
+ 'border_color' => '#33CCFF',
+ 'html' => 'Foo
',
+ ]
+ )
+ );
+
+ $this->assertEquals(
+ '{"aclGroupId":null,"agentId":null,"agentName":null,"backgroundColor":"white","encodedHtml":"PGgxPkZvbzwvaDE+","gridColor":"#33CCFF","height":300,"id":7,"isLinkEnabled":true,"isOnTop":false,"label":"test","labelPosition":"left","moduleId":null,"moduleName":null,"parentId":null,"type":18,"typeGraph":"horizontal","width":300,"x":-666,"y":76}',
+ (string) BarsGraph::fromArray(
+ [
+ 'id' => 7,
+ 'type' => DONUT_GRAPH,
+ 'label' => 'test',
+ 'labelPosition' => 'left',
+ 'isLinkEnabled' => true,
+ 'isOnTop' => false,
+ 'parentId' => null,
+ 'width' => '300',
+ 'height' => '300',
+ 'x' => -666,
+ 'y' => 76,
+ 'typeGraph' => 'horizontal',
+ 'backgroundColor' => 'white',
+ 'gridColor' => '#33CCFF',
+ 'encodedHtml' => 'PGgxPkZvbzwvaDE+',
+ ]
+ )
+ );
+ }
+
+
+}
diff --git a/pandora_console/tests/Functional/Models/VisualConsole/Items/DonutGraphTest.php b/pandora_console/tests/Functional/Models/VisualConsole/Items/DonutGraphTest.php
index 2af2bc40ec..e9c0367151 100644
--- a/pandora_console/tests/Functional/Models/VisualConsole/Items/DonutGraphTest.php
+++ b/pandora_console/tests/Functional/Models/VisualConsole/Items/DonutGraphTest.php
@@ -57,7 +57,7 @@ class DonutGraphTest extends TestCase
public function testContainerIsRepresentedAsJson(): void
{
$this->assertEquals(
- '{"aclGroupId":null,"agentId":null,"agentName":null,"legendBackgroundColor":"#33CCFF","encodedHtml":"PGgxPkZvbzwvaDE+","height":0,"id":7,"isLinkEnabled":true,"isOnTop":false,"label":null,"labelPosition":"up","linkedLayoutAgentId":null,"linkedLayoutId":null,"linkedLayoutStatusType":"default","moduleId":null,"moduleName":null,"parentId":null,"type":17,"width":0,"x":-666,"y":76}',
+ '{"aclGroupId":null,"agentId":null,"agentName":null,"encodedHtml":"PGgxPkZvbzwvaDE+","height":0,"id":7,"isLinkEnabled":true,"isOnTop":false,"label":null,"labelPosition":"up","legendBackgroundColor":"#33CCFF","linkedLayoutAgentId":null,"linkedLayoutId":null,"linkedLayoutStatusType":"default","moduleId":null,"moduleName":null,"parentId":null,"type":17,"width":0,"x":-666,"y":76}',
(string) DonutGraph::fromArray(
[
'id' => 7,
@@ -78,7 +78,7 @@ class DonutGraphTest extends TestCase
);
$this->assertEquals(
- '{"aclGroupId":null,"agentId":null,"agentName":null,"legendBackgroundColor":"#000000","encodedHtml":"PGgxPkZvbzwvaDE+","height":0,"id":7,"isLinkEnabled":true,"isOnTop":false,"label":null,"labelPosition":"left","linkedLayoutAgentId":null,"linkedLayoutId":null,"linkedLayoutStatusType":"default","moduleId":null,"moduleName":null,"parentId":null,"type":17,"width":0,"x":-666,"y":76}',
+ '{"aclGroupId":null,"agentId":null,"agentName":null,"encodedHtml":"PGgxPkZvbzwvaDE+","height":0,"id":7,"isLinkEnabled":true,"isOnTop":false,"label":null,"labelPosition":"left","legendBackgroundColor":"#000000","linkedLayoutAgentId":null,"linkedLayoutId":null,"linkedLayoutStatusType":"default","moduleId":null,"moduleName":null,"parentId":null,"type":17,"width":0,"x":-666,"y":76}',
(string) DonutGraph::fromArray(
[
'id' => 7,