This is an automated email from the ASF dual-hosted git repository.

ilgrosso pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/master by this push:
     new 283685af5a Bump org.webjars:chartjs from 4.4.3 to 4.5.1 (#1379)
283685af5a is described below

commit 283685af5a0aa68b9f97d475adf3e81d5af43716
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
AuthorDate: Wed Jun 3 16:11:05 2026 +0200

    Bump org.webjars:chartjs from 4.4.3 to 4.5.1 (#1379)
    
    Signed-off-by: dependabot[bot] <[email protected]>
    Co-authored-by: dependabot[bot] 
<49699333+dependabot[bot]@users.noreply.github.com>
    Co-authored-by: TatoniMatteo <[email protected]>
---
 .../apache/syncope/client/console/chartjs/Bar.java |  45 ---
 .../client/console/chartjs/BarChartOptions.java    | 157 --------
 .../syncope/client/console/chartjs/BarDataSet.java |  48 ---
 .../client/console/chartjs/BaseDataSet.java        |  69 ----
 .../syncope/client/console/chartjs/Chart.java      |  46 ++-
 .../client/console/chartjs/ChartJSPanel.java       |  45 +--
 .../client/console/chartjs/ChartJSRenderer.java    |  52 +++
 .../client/console/chartjs/ChartOptions.java       | 404 ---------------------
 .../chartjs/{BarChartData.java => ChartType.java}  |  57 ++-
 .../client/console/chartjs/DataSetChart.java       |  44 ---
 .../syncope/client/console/chartjs/Doughnut.java   |  39 --
 .../console/chartjs/DoughnutAndPieChartData.java   |  57 ---
 .../console/chartjs/DoughnutChartOptions.java      |  48 ---
 .../syncope/client/console/chartjs/Line.java       |  40 --
 .../client/console/chartjs/LineChartData.java      |  30 --
 .../client/console/chartjs/LineChartOptions.java   | 237 ------------
 .../client/console/chartjs/LineDataSet.java        |  43 ---
 .../apache/syncope/client/console/chartjs/Pie.java |  39 --
 .../client/console/chartjs/PieChartOptions.java    | 145 --------
 .../client/console/chartjs/PointColorDataSet.java  |  80 ----
 .../client/console/chartjs/SimpleChart.java        |  41 ---
 .../console/chartjs/{ => data}/ChartData.java      |  89 +++--
 .../client/console/chartjs/data/Dataset.java       |  74 ++++
 .../client/console/chartjs/options/Animation.java  |  78 ++++
 .../console/chartjs/options/AnimationCallback.java |  44 +++
 .../console/chartjs/options/ChartOptions.java      |  79 ++++
 .../client/console/chartjs/options/Plugins.java    |  39 ++
 .../client/console/chartjs/options/Scale.java      |  78 ++++
 .../client/console/chartjs/options/Scales.java     |  53 +++
 .../console/chartjs/options/TooltipCallback.java   |  42 +++
 .../console/chartjs/options/TooltipOptions.java    |  49 +++
 .../client/console/widgets/AnyByRealmWidget.java   | 142 +++++---
 .../client/console/widgets/CompletenessWidget.java | 137 ++++---
 .../syncope/client/console/widgets/LoadWidget.java | 102 ++++--
 .../console/widgets/UsersByStatusWidget.java       |  51 ++-
 .../syncope/common/lib/info/NumbersInfo.java       |  10 +-
 pom.xml                                            |   2 +-
 37 files changed, 968 insertions(+), 1867 deletions(-)

diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Bar.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Bar.java
deleted file mode 100644
index 0d3089b2bf..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Bar.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-/**
- * Provides a simple implementation of chart.js bar chart.
- *
- * @see <a href="http://www.chartjs.org/docs/#barChart";>chart.js docs</a>
- */
-public class Bar extends DataSetChart<BarChartData<BarDataSet>, 
BarChartOptions, BarDataSet> {
-
-    private static final long serialVersionUID = -332976997065056554L;
-
-    @Override
-    public BarChartOptions getOptions() {
-        if (options == null) {
-            options = new BarChartOptions();
-        }
-        return options;
-    }
-
-    @Override
-    public BarChartData<BarDataSet> getData() {
-        if (data == null) {
-            data = new BarChartData<>();
-        }
-        return data;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/BarChartOptions.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/BarChartOptions.java
deleted file mode 100644
index 6616f2ac9c..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/BarChartOptions.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-/**
- * Provides options, that are available for {@link Bar}.
- */
-public class BarChartOptions extends ChartOptions {
-
-    private static final long serialVersionUID = -5356780831848556616L;
-
-    /**
-     * Whether to show horizontal lines (except X axis).
-     */
-    private Boolean scaleShowHorizontalLines = true;
-
-    /**
-     * Whether to show vertical lines (except Y axis).
-     */
-    private Boolean scaleShowVerticalLines = true;
-
-    /**
-     * A legend template.
-     */
-    private String legendTemplate = "<ul 
class=\"<%=name.toLowerCase()%>-legend\">"
-            + "<% for (var i=0; i<datasets.length; i++){%><li>"
-            + "<span 
style=\"background-color:<%=datasets[i].fillColor%>\"></span>"
-            + 
"<%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>";
-
-    /**
-     * The bar show stroke.
-     */
-    private Boolean barShowStroke;
-
-    /**
-     * The bar stroke width.
-     */
-    private Integer barStrokeWidth;
-
-    /** The bar value spacing. */
-    private Integer barValueSpacing;
-
-    /** The bar dataset spacing. */
-    private Integer barDatasetSpacing;
-
-    public Boolean getScaleShowHorizontalLines() {
-        return scaleShowHorizontalLines;
-    }
-
-    public void setScaleShowHorizontalLines(final Boolean 
scaleShowHorizontalLines) {
-        this.scaleShowHorizontalLines = scaleShowHorizontalLines;
-    }
-
-    public Boolean getScaleShowVerticalLines() {
-        return scaleShowVerticalLines;
-    }
-
-    public void setScaleShowVerticalLines(final Boolean 
scaleShowVerticalLines) {
-        this.scaleShowVerticalLines = scaleShowVerticalLines;
-    }
-
-    public String getLegendTemplate() {
-        return legendTemplate;
-    }
-
-    public void setLegendTemplate(final String legendTemplate) {
-        this.legendTemplate = legendTemplate;
-    }
-
-    /**
-     * Gets the bar show stroke.
-     *
-     * @return the bar show stroke
-     */
-    public Boolean getBarShowStroke() {
-        return barShowStroke;
-    }
-
-    /**
-     * Sets the bar show stroke.
-     *
-     * @param barShowStroke the new bar show stroke (default is true).
-     */
-    public void setBarShowStroke(final Boolean barShowStroke) {
-        this.barShowStroke = barShowStroke;
-    }
-
-    /**
-     * Gets the bar stroke width.
-     *
-     * @return the bar stroke width
-     */
-    public Integer getBarStrokeWidth() {
-        return barStrokeWidth;
-    }
-
-    /**
-     * Sets the bar stroke width.
-     *
-     * @param barStrokeWidth the new bar stroke width (default is 2).
-     */
-    public void setBarStrokeWidth(final Integer barStrokeWidth) {
-        this.barStrokeWidth = barStrokeWidth;
-    }
-
-    /**
-     * Gets the bar value spacing.
-     *
-     * @return the bar value spacing
-     */
-    public Integer getBarValueSpacing() {
-        return barValueSpacing;
-    }
-
-    /**
-     * Sets the bar value spacing.
-     *
-     * @param barValueSpacing the spacing between each of the X value sets 
(default is 5)
-     */
-    public void setBarValueSpacing(final Integer barValueSpacing) {
-        this.barValueSpacing = barValueSpacing;
-    }
-
-    /**
-     * Gets the bar dataset spacing.
-     *
-     * @return the bar dataset spacing
-     */
-    public Integer getBarDatasetSpacing() {
-        return barDatasetSpacing;
-    }
-
-    /**
-     * Sets the bar dataset spacing.
-     *
-     * @param barDatasetSpacing the spacing between data sets within X values 
(default is 1).
-     */
-    public void setBarDatasetSpacing(final Integer barDatasetSpacing) {
-        this.barDatasetSpacing = barDatasetSpacing;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/BarDataSet.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/BarDataSet.java
deleted file mode 100644
index f561c44e68..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/BarDataSet.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-import java.util.List;
-
-/**
- * Provides all information needed for {@link BarChartData}.
- */
-public class BarDataSet extends BaseDataSet {
-
-    private static final long serialVersionUID = 3095383371272813559L;
-
-    private String label;
-
-    /**
-     * Instantiates a new bar data set.
-     *
-     * @param data the values
-     */
-    public BarDataSet(final List<? extends Number> data) {
-        super(data);
-    }
-
-    public String getLabel() {
-        return label;
-    }
-
-    public void setLabel(final String label) {
-        this.label = label;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/BaseDataSet.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/BaseDataSet.java
deleted file mode 100644
index 842fe1d174..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/BaseDataSet.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * Provides the simplest kind of a dataset.
- * Besides the list of data itself, it contains default values for fill - and 
stroke color.
- */
-public abstract class BaseDataSet implements Serializable {
-
-    private static final long serialVersionUID = 1581171902504828797L;
-
-    private String backgroundColor = "rgba(220,220,220,0.5)";
-
-    private String borderColor = "rgba(220,220,220,1)";
-
-    /** The data. */
-    private final List<? extends Number> data;
-
-    /**
-     * Instantiates a new abstract base data set.
-     *
-     * @param data the data values
-     */
-    public BaseDataSet(final List<? extends Number> data) {
-        this.data = data;
-    }
-
-    public String getBackgroundColor() {
-        return backgroundColor;
-    }
-
-    public BaseDataSet setBackgroundColor(final String backgroundColor) {
-        this.backgroundColor = backgroundColor;
-        return this;
-    }
-
-    public String getBorderColor() {
-        return borderColor;
-    }
-
-    public BaseDataSet setBorderColor(final String borderColor) {
-        this.borderColor = borderColor;
-        return this;
-    }
-
-    public List<? extends Number> getData() {
-        return data;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Chart.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Chart.java
index 435b6ddbfb..6eae948aa8 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Chart.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Chart.java
@@ -16,23 +16,49 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.syncope.client.console.chartjs;
 
+import com.fasterxml.jackson.annotation.JsonInclude;
 import java.io.Serializable;
+import org.apache.syncope.client.console.chartjs.data.ChartData;
+import org.apache.syncope.client.console.chartjs.options.ChartOptions;
 
-/**
- * Provides chart options and a pojo-json mapper to communicate with 
javascript.
- *
- * @param <O> the generic type of options
- */
-public abstract class Chart<O extends ChartOptions> implements Serializable {
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class Chart implements Serializable {
+
+    private static final long serialVersionUID = -1787318832624463674L;
 
-    private static final long serialVersionUID = 4733939203616971674L;
+    private ChartType type;
 
-    /** The options. */
-    protected O options;
+    private ChartData<?> data = new ChartData<>();
 
-    public O getOptions() {
+    private ChartOptions options;
+
+    public ChartType getType() {
+        return type;
+    }
+
+    public void setType(final ChartType type) {
+        this.type = type;
+    }
+
+    public ChartData<?> getData() {
+        return data;
+    }
+
+    public void setData(final ChartData<?> data) {
+        this.data = data;
+    }
+
+    public ChartOptions getOptions() {
+        if (options == null) {
+            options = new ChartOptions();
+        }
         return options;
     }
+
+    public void setOptions(final ChartOptions options) {
+        this.options = options;
+    }
 }
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartJSPanel.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartJSPanel.java
index dbc946aae0..120813defa 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartJSPanel.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartJSPanel.java
@@ -21,63 +21,34 @@ package org.apache.syncope.client.console.chartjs;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.panel.Panel;
 import org.apache.wicket.model.IModel;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import tools.jackson.databind.json.JsonMapper;
 
 public class ChartJSPanel extends Panel {
 
-    private static final long serialVersionUID = -3844680585650585253L;
+    private static final long serialVersionUID = -8670277955339192068L;
 
-    private static final Logger LOG = 
LoggerFactory.getLogger(ChartJSPanel.class);
-
-    private static final JsonMapper MAPPER = 
JsonMapper.builder().findAndAddModules().build();
-
-    private final IModel<? extends Chart<?>> model;
+    private final IModel<Chart> model;
 
     private final WebMarkupContainer container;
 
-    public ChartJSPanel(
-            final String id,
-            final IModel<? extends Chart<?>> model) {
+    private final ChartJSRenderer renderer = new ChartJSRenderer();
 
+    public ChartJSPanel(final String id, final IModel<Chart> model) {
         super(id, model);
 
         this.model = model;
+
         this.container = new WebMarkupContainer("chart");
-    }
+        this.container.setOutputMarkupId(true);
 
-    @Override
-    protected void onInitialize() {
-        super.onInitialize();
         add(container);
-        container.setOutputMarkupId(true);
         container.add(new ChartJSBehavior());
     }
 
-    public Chart<?> getChart() {
+    public Chart getChart() {
         return model.getObject();
     }
 
     public String generateChart(final String markupId) {
-        String dataString = null;
-        String optionString = null;
-        try {
-            Object data = (model.getObject() instanceof final SimpleChart<?, 
?> simpleChart)
-                    ? simpleChart.getData()
-                    : ((DataSetChart) model.getObject()).getData();
-            dataString = MAPPER.writeValueAsString(data);
-            optionString = 
MAPPER.writeValueAsString(model.getObject().getOptions());
-        } catch (Exception e) {
-            LOG.error("Unexpected error during JSON serialization", e);
-        }
-
-        return "WicketCharts['" + markupId + "'] = new Chart("
-                + "getChartCtx('" + markupId + "'),"
-                + "{"
-                + "type: '" + 
model.getObject().getClass().getSimpleName().toLowerCase() + "',"
-                + "data: " + dataString + ","
-                + "options:" + optionString
-                + "})";
+        return renderer.render(markupId, model.getObject());
     }
 }
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartJSRenderer.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartJSRenderer.java
new file mode 100644
index 0000000000..b56bf06188
--- /dev/null
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartJSRenderer.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.syncope.client.console.chartjs;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ChartJSRenderer {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(ChartJSRenderer.class);
+
+    private static final ObjectMapper MAPPER = new ObjectMapper()
+            .setDefaultPropertyInclusion(JsonInclude.Include.NON_NULL);
+
+    public String render(final String markupId, final Chart chart) {
+        try {
+            String data = MAPPER.writeValueAsString(chart.getData());
+            String options = MAPPER.writeValueAsString(chart.getOptions());
+
+            return "WicketCharts['" + markupId + "'] = new Chart("
+                    + "getChartCtx('" + markupId + "'),"
+                    + "{"
+                    + "type: '" + chart.getType() + "',"
+                    + "data: " + data + ","
+                    + "options: " + options
+                    + "});";
+
+        } catch (Exception e) {
+            LOG.error("Error rendering chart JS", e);
+            return "";
+        }
+    }
+}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartOptions.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartOptions.java
deleted file mode 100644
index 2a3ec7aba1..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartOptions.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-import com.fasterxml.jackson.annotation.JsonRawValue;
-import java.io.Serializable;
-
-/**
- * Provides some basic options, that are available for all kinds of charts.
- */
-public abstract class ChartOptions implements Serializable {
-
-    private static final long serialVersionUID = 2401861279216541412L;
-
-    public static class Axis implements Serializable {
-
-        private static final long serialVersionUID = 1L;
-
-        private Boolean display;
-
-        public Boolean getDisplay() {
-            return display;
-        }
-
-        public void setDisplay(final Boolean display) {
-            this.display = display;
-        }
-    }
-
-    public static class Scales implements Serializable {
-
-        private static final long serialVersionUID = 1L;
-
-        private Axis x;
-
-        private Axis y;
-
-        public Axis getX() {
-            return x;
-        }
-
-        public void setX(final Axis x) {
-            this.x = x;
-        }
-
-        public Axis getY() {
-            return y;
-        }
-
-        public void setY(final Axis y) {
-            this.y = y;
-        }
-    }
-
-    /** The animation. */
-    private Boolean animation;
-
-    /** The animation steps. */
-    private Integer animationSteps;
-
-    /** The animation easing. */
-    private String animationEasing;
-
-    /** The on animation complete. */
-    private String onAnimationComplete;
-
-    @JsonRawValue
-    private String customTooltips;
-
-    private Boolean responsive;
-
-    private Boolean maintainAspectRatio;
-
-    private Boolean showTooltips;
-
-    private String[] tooltipEvents = { "mousemove", "touchstart", "touchmove" 
};
-
-    private String tooltipFillColor;
-
-    private String tooltipFontFamily;
-
-    private Integer tooltipFontSize;
-
-    private String tooltipFontStyle;
-
-    private String tooltipFontColor;
-
-    private String tooltipTitleFontFamily;
-
-    private Integer tooltipTitleFontSize;
-
-    private String tooltipTitleFontStyle;
-
-    private String tooltipTitleFontColor;
-
-    private Integer tooltipYPadding;
-
-    private Integer tooltipXPadding;
-
-    private Integer tooltipCaretSize;
-
-    private Integer tooltipCornerRadius;
-
-    private Integer tooltipXOffset;
-
-    private String tooltipTemplate;
-
-    private String multiTooltipTemplate;
-
-    private Scales scales;
-
-    @JsonRawValue
-    private String onAnimationProgress;
-
-    public String getCustomTooltips() {
-        return customTooltips;
-    }
-
-    public void setCustomTooltips(final String customTooltips) {
-        this.customTooltips = customTooltips;
-    }
-
-    /**
-     * Gets the animation.
-     *
-     * @return the animation
-     */
-    public Boolean getAnimation() {
-        return animation;
-    }
-
-    /**
-     * Sets the animation.
-     *
-     * @param animation decides whether to animate the chart (default is true)
-     */
-    public void setAnimation(final Boolean animation) {
-        this.animation = animation;
-    }
-
-    /**
-     * Gets the animation steps.
-     *
-     * @return the animation steps
-     */
-    public Integer getAnimationSteps() {
-        return animationSteps;
-    }
-
-    /**
-     * Sets the animation steps.
-     *
-     * @param animationSteps the number of animation steps (default is 60)
-     */
-    public void setAnimationSteps(final Integer animationSteps) {
-        this.animationSteps = animationSteps;
-    }
-
-    /**
-     * Gets the animation easing.
-     *
-     * @return the animation easing
-     */
-    public String getAnimationEasing() {
-        return animationEasing;
-    }
-
-    /**
-     * Sets the animation easing.
-     *
-     * @param animationEasing the animation easing effect (default is 
"easeOutQuart")
-     */
-    public void setAnimationEasing(final String animationEasing) {
-        this.animationEasing = animationEasing;
-    }
-
-    /**
-     * Gets the javascript function that fires on animation complete.
-     *
-     * @return the onAnimationComplete javascript function
-     */
-    public String getOnAnimationComplete() {
-        return onAnimationComplete;
-    }
-
-    /**
-     * Sets the onAnimationComplete javascript function.
-     *
-     * @param onAnimationComplete a function, that fires when the animation is 
complete
-     */
-    public void setOnAnimationComplete(final String onAnimationComplete) {
-        this.onAnimationComplete = onAnimationComplete;
-    }
-
-    public Boolean getResponsive() {
-        return responsive;
-    }
-
-    public void setResponsive(final Boolean responsive) {
-        this.responsive = responsive;
-    }
-
-    public Boolean getMaintainAspectRatio() {
-        return maintainAspectRatio;
-    }
-
-    public void setMaintainAspectRatio(final Boolean maintainAspectRatio) {
-        this.maintainAspectRatio = maintainAspectRatio;
-    }
-
-    public Boolean getShowTooltips() {
-        return showTooltips;
-    }
-
-    public void setShowTooltips(final Boolean showTooltips) {
-        this.showTooltips = showTooltips;
-    }
-
-    public String[] getTooltipEvents() {
-        return tooltipEvents;
-    }
-
-    public void setTooltipEvents(final String[] tooltipEvents) {
-        this.tooltipEvents = tooltipEvents;
-    }
-
-    public String getTooltipFillColor() {
-        return tooltipFillColor;
-    }
-
-    public void setTooltipFillColor(final String tooltipFillColor) {
-        this.tooltipFillColor = tooltipFillColor;
-    }
-
-    public String getTooltipFontFamily() {
-        return tooltipFontFamily;
-    }
-
-    public void setTooltipFontFamily(final String tooltipFontFamily) {
-        this.tooltipFontFamily = tooltipFontFamily;
-    }
-
-    public Integer getTooltipFontSize() {
-        return tooltipFontSize;
-    }
-
-    public void setTooltipFontSize(final Integer tooltipFontSize) {
-        this.tooltipFontSize = tooltipFontSize;
-    }
-
-    public String getTooltipFontStyle() {
-        return tooltipFontStyle;
-    }
-
-    public void setTooltipFontStyle(final String tooltipFontStyle) {
-        this.tooltipFontStyle = tooltipFontStyle;
-    }
-
-    public String getTooltipFontColor() {
-        return tooltipFontColor;
-    }
-
-    public void setTooltipFontColor(final String tooltipFontColor) {
-        this.tooltipFontColor = tooltipFontColor;
-    }
-
-    public String getTooltipTitleFontFamily() {
-        return tooltipTitleFontFamily;
-    }
-
-    public void setTooltipTitleFontFamily(final String tooltipTitleFontFamily) 
{
-        this.tooltipTitleFontFamily = tooltipTitleFontFamily;
-    }
-
-    public Integer getTooltipTitleFontSize() {
-        return tooltipTitleFontSize;
-    }
-
-    public void setTooltipTitleFontSize(final Integer tooltipTitleFontSize) {
-        this.tooltipTitleFontSize = tooltipTitleFontSize;
-    }
-
-    public String getTooltipTitleFontStyle() {
-        return tooltipTitleFontStyle;
-    }
-
-    public void setTooltipTitleFontStyle(final String tooltipTitleFontStyle) {
-        this.tooltipTitleFontStyle = tooltipTitleFontStyle;
-    }
-
-    public String getTooltipTitleFontColor() {
-        return tooltipTitleFontColor;
-    }
-
-    public void setTooltipTitleFontColor(final String tooltipTitleFontColor) {
-        this.tooltipTitleFontColor = tooltipTitleFontColor;
-    }
-
-    public Integer getTooltipYPadding() {
-        return tooltipYPadding;
-    }
-
-    public void setTooltipYPadding(final Integer tooltipYPadding) {
-        this.tooltipYPadding = tooltipYPadding;
-    }
-
-    public Integer getTooltipXPadding() {
-        return tooltipXPadding;
-    }
-
-    public void setTooltipXPadding(final Integer tooltipXPadding) {
-        this.tooltipXPadding = tooltipXPadding;
-    }
-
-    public Integer getTooltipCaretSize() {
-        return tooltipCaretSize;
-    }
-
-    public void setTooltipCaretSize(final Integer tooltipCaretSize) {
-        this.tooltipCaretSize = tooltipCaretSize;
-    }
-
-    public Integer getTooltipCornerRadius() {
-        return tooltipCornerRadius;
-    }
-
-    public void setTooltipCornerRadius(final Integer tooltipCornerRadius) {
-        this.tooltipCornerRadius = tooltipCornerRadius;
-    }
-
-    public Integer getTooltipXOffset() {
-        return tooltipXOffset;
-    }
-
-    public void setTooltipXOffset(final Integer tooltipXOffset) {
-        this.tooltipXOffset = tooltipXOffset;
-    }
-
-    public String getTooltipTemplate() {
-        return tooltipTemplate;
-    }
-
-    public void setTooltipTemplate(final String tooltipTemplate) {
-        this.tooltipTemplate = tooltipTemplate;
-    }
-
-    public String getMultiTooltipTemplate() {
-        return multiTooltipTemplate;
-    }
-
-    public void setMultiTooltipTemplate(final String multiTooltipTemplate) {
-        this.multiTooltipTemplate = multiTooltipTemplate;
-    }
-
-    public String getOnAnimationProgress() {
-        return onAnimationProgress;
-    }
-
-    public void setOnAnimationProgress(final String onAnimationProgress) {
-        this.onAnimationProgress = onAnimationProgress;
-    }
-
-    /**
-     * Tests whether this chart is responsive or not.
-     *
-     * @return true if its responsive, false otherwise.
-     */
-    public boolean isResponsive() {
-        return responsive;
-    }
-
-    /**
-     * Sets the responsive option for this chart.
-     *
-     * @param responsive the responsive option value.
-     */
-    public void setResponsive(final boolean responsive) {
-        this.responsive = responsive;
-    }
-
-    public Scales getScales() {
-        return scales;
-    }
-
-    public void setScales(final Scales scales) {
-        this.scales = scales;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/BarChartData.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartType.java
similarity index 75%
rename from 
client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/BarChartData.java
rename to 
client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartType.java
index 45608a47ed..8556bb53ab 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/BarChartData.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartType.java
@@ -1,30 +1,27 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-/**
- * Provides chart data used by bar charts.
- *
- * @param <T> the generic type of it's dataset
- */
-public class BarChartData<T extends BaseDataSet> extends ChartData<T> {
-
-    private static final long serialVersionUID = 9057475640743455047L;
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.chartjs;
+
+public enum ChartType {
+    line,
+    bar,
+    pie,
+    doughnut,
+    scatter
+}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/DataSetChart.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/DataSetChart.java
deleted file mode 100644
index cc4d896927..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/DataSetChart.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-/**
- * Provides chart data and options.
- *
- * @param <D> the generic type of chart data
- * @param <O> the generic type of chart options
- * @param <S> the generic type of a chart data set
- */
-abstract class DataSetChart<
-        D extends ChartData<S>, O extends ChartOptions, S extends BaseDataSet>
-        extends Chart<O> {
-
-    private static final long serialVersionUID = 999846601210465414L;
-
-    /** The data. */
-    protected D data;
-
-    public D getData() {
-        return data;
-    }
-
-    public void setData(final D data) {
-        this.data = data;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Doughnut.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Doughnut.java
deleted file mode 100644
index f2c2fa207a..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Doughnut.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-import java.io.Serializable;
-
-/**
- * Provides a simple implementation of chart.js doughnut chart.
- *
- * @see <a href="http://www.chartjs.org/docs/#doughnutChart";>chart.js docs</a>
- */
-public class Doughnut extends SimpleChart<DoughnutAndPieChartData, 
DoughnutChartOptions> implements Serializable {
-
-    private static final long serialVersionUID = -6898362145345731457L;
-
-    @Override
-    public DoughnutChartOptions getOptions() {
-        if (options == null) {
-            options = new DoughnutChartOptions();
-        }
-        return options;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/DoughnutAndPieChartData.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/DoughnutAndPieChartData.java
deleted file mode 100644
index c61fa27825..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/DoughnutAndPieChartData.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-public class DoughnutAndPieChartData implements Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    public static class DataSet implements Serializable {
-
-        private static final long serialVersionUID = 1L;
-
-        private final List<Number> data = new ArrayList<>();
-
-        private final List<String> backgroundColor = new ArrayList<>();
-
-        public List<Number> getData() {
-            return data;
-        }
-
-        public List<String> getBackgroundColor() {
-            return backgroundColor;
-        }
-    }
-
-    private final List<DataSet> datasets = new ArrayList<>();
-
-    private final List<String> labels = new ArrayList<>();
-
-    public List<DataSet> getDatasets() {
-        return datasets;
-    }
-
-    public List<String> getLabels() {
-        return labels;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/DoughnutChartOptions.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/DoughnutChartOptions.java
deleted file mode 100644
index b8facd6a4a..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/DoughnutChartOptions.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-/**
- * Provides options, that are available for {@link Doughnut}.
- */
-public class DoughnutChartOptions extends PieChartOptions {
-
-    private static final long serialVersionUID = -5356780831848556616L;
-
-    /** The percentage inner cutout. */
-    private Integer percentageInnerCutout;
-
-    /**
-     * Gets the percentage inner cutout.
-     *
-     * @return the percentage inner cutout
-     */
-    public Integer getPercentageInnerCutout() {
-        return percentageInnerCutout;
-    }
-
-    /**
-     * Sets the percentage inner cutout.
-     *
-     * @param percentageInnerCutout the percentage of the chart that we cut 
out of the middle (default is 50).
-     */
-    public void setPercentageInnerCutout(final Integer percentageInnerCutout) {
-        this.percentageInnerCutout = percentageInnerCutout;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Line.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Line.java
deleted file mode 100644
index 9af958a29e..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Line.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-public class Line extends DataSetChart<LineChartData<LineDataSet>, 
LineChartOptions, LineDataSet> {
-
-    private static final long serialVersionUID = -2467327116468783154L;
-
-    @Override
-    public LineChartOptions getOptions() {
-        if (options == null) {
-            options = new LineChartOptions();
-        }
-        return options;
-    }
-
-    @Override
-    public LineChartData<LineDataSet> getData() {
-        if (data == null) {
-            data = new LineChartData<>();
-        }
-        return data;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/LineChartData.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/LineChartData.java
deleted file mode 100644
index f8617d226e..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/LineChartData.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-/**
- * Provides chart data used by line charts.
- *
- * @param <T> the generic type of it's dataset
- */
-public class LineChartData<T extends PointColorDataSet> extends ChartData<T> {
-
-    private static final long serialVersionUID = 9057475640743455047L;
-
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/LineChartOptions.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/LineChartOptions.java
deleted file mode 100644
index 51060356a6..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/LineChartOptions.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-/**
- * Provides options for {@link Line}.
- */
-public class LineChartOptions extends ChartOptions {
-
-    private static final long serialVersionUID = -5356780831848556616L;
-
-    private Boolean scaleShowHorizontalLines = true;
-
-    private Boolean scaleShowVerticalLines = true;
-
-    private Integer pointHitDetectionRadius = 20;
-
-    private String legendTemplate = "<ul 
class=\"<%=name.toLowerCase()%>-legend\">"
-            + "<% for (var i=0; i<datasets.length; i++){%><li>"
-            + "<span 
style=\"background-color:<%=datasets[i].strokeColor%>\"></span>"
-            + 
"<%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>";
-
-    /** The bezier curve. */
-    private Boolean bezierCurve;
-
-    /** The point dot. */
-    private Boolean pointDot;
-
-    /** The point dot radius. */
-    private Integer pointDotRadius;
-
-    /** The point dot stroke width. */
-    private Integer pointDotStrokeWidth;
-
-    /** The dataset stroke. */
-    private Boolean datasetStroke;
-
-    /** The dataset stroke width. */
-    private Integer datasetStrokeWidth;
-
-    /** The dataset fill. */
-    private Boolean datasetFill;
-
-    private Boolean showLine = true;
-
-    private Double tension = 0.0;
-
-    public Boolean getScaleShowHorizontalLines() {
-        return scaleShowHorizontalLines;
-    }
-
-    public void setScaleShowHorizontalLines(final Boolean 
scaleShowHorizontalLines) {
-        this.scaleShowHorizontalLines = scaleShowHorizontalLines;
-    }
-
-    public Boolean getScaleShowVerticalLines() {
-        return scaleShowVerticalLines;
-    }
-
-    public void setScaleShowVerticalLines(final Boolean 
scaleShowVerticalLines) {
-        this.scaleShowVerticalLines = scaleShowVerticalLines;
-    }
-
-    public Integer getPointHitDetectionRadius() {
-        return pointHitDetectionRadius;
-    }
-
-    public void setPointHitDetectionRadius(final Integer 
pointHitDetectionRadius) {
-        this.pointHitDetectionRadius = pointHitDetectionRadius;
-    }
-
-    public String getLegendTemplate() {
-        return legendTemplate;
-    }
-
-    public void setLegendTemplate(final String legendTemplate) {
-        this.legendTemplate = legendTemplate;
-    }
-
-    /**
-     * Gets the bezier curve.
-     *
-     * @return the bezier curve
-     */
-    public Boolean getBezierCurve() {
-        return bezierCurve;
-    }
-
-    /**
-     * Sets the bezier curve.
-     *
-     * @param bezierCurve decides whether the line is curved between points 
(default is true).
-     */
-    public void setBezierCurve(final Boolean bezierCurve) {
-        this.bezierCurve = bezierCurve;
-    }
-
-    /**
-     * Gets the point dot.
-     *
-     * @return the point dot
-     */
-    public Boolean getPointDot() {
-        return pointDot;
-    }
-
-    /**
-     * Sets the point dot.
-     *
-     * @param pointDot decides whether to show a dot for each point (default 
is true).
-     */
-    public void setPointDot(final Boolean pointDot) {
-        this.pointDot = pointDot;
-    }
-
-    /**
-     * Gets the point dot radius.
-     *
-     * @return the point dot radius
-     */
-    public Integer getPointDotRadius() {
-        return pointDotRadius;
-    }
-
-    /**
-     * Sets the point dot radius.
-     *
-     * @param pointDotRadius the new point dot radius (default is 3).
-     */
-    public void setPointDotRadius(final Integer pointDotRadius) {
-        this.pointDotRadius = pointDotRadius;
-    }
-
-    /**
-     * Gets the point dot stroke width.
-     *
-     * @return the point dot stroke width
-     */
-    public Integer getPointDotStrokeWidth() {
-        return pointDotStrokeWidth;
-    }
-
-    /**
-     * Sets the point dot stroke width.
-     *
-     * @param pointDotStrokeWidth the new point dot stroke width (default is 
1).
-     */
-    public void setPointDotStrokeWidth(final Integer pointDotStrokeWidth) {
-        this.pointDotStrokeWidth = pointDotStrokeWidth;
-    }
-
-    /**
-     * Gets the dataset stroke.
-     *
-     * @return the dataset stroke
-     */
-    public Boolean getDatasetStroke() {
-        return datasetStroke;
-    }
-
-    /**
-     * Sets the dataset stroke.
-     *
-     * @param datasetStroke decides whether to show a stroke for datasets 
(default is true)
-     */
-    public void setDatasetStroke(final Boolean datasetStroke) {
-        this.datasetStroke = datasetStroke;
-    }
-
-    /**
-     * Gets the dataset stroke width.
-     *
-     * @return the dataset stroke width
-     */
-    public Integer getDatasetStrokeWidth() {
-        return datasetStrokeWidth;
-    }
-
-    /**
-     * Sets the dataset stroke width.
-     *
-     * @param datasetStrokeWidth the new dataset stroke width (default is 2).
-     */
-    public void setDatasetStrokeWidth(final Integer datasetStrokeWidth) {
-        this.datasetStrokeWidth = datasetStrokeWidth;
-    }
-
-    /**
-     * Gets the dataset fill.
-     *
-     * @return the dataset fill
-     */
-    public Boolean getDatasetFill() {
-        return datasetFill;
-    }
-
-    /**
-     * Sets the dataset fill.
-     *
-     * @param datasetFill whether to fill the dataset with a color (default is 
true)
-     */
-    public void setDatasetFill(final Boolean datasetFill) {
-        this.datasetFill = datasetFill;
-    }
-
-    public Boolean getShowLine() {
-        return showLine;
-    }
-
-    public void setShowLine(final Boolean showLine) {
-        this.showLine = showLine;
-    }
-
-    public Double getTension() {
-        return tension;
-    }
-
-    public void setTension(final Double tension) {
-        this.tension = tension;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/LineDataSet.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/LineDataSet.java
deleted file mode 100644
index 610dccc541..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/LineDataSet.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-import java.util.List;
-
-/**
- * Provides all information needed for {@link LineChartData}.
- */
-public class LineDataSet extends PointColorDataSet {
-
-    private static final long serialVersionUID = -3154092519924576329L;
-
-    private String label;
-
-    public LineDataSet(final List<? extends Number> data) {
-        super(data);
-    }
-
-    public String getLabel() {
-        return label;
-    }
-
-    public void setLabel(final String label) {
-        this.label = label;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Pie.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Pie.java
deleted file mode 100644
index 007a21239c..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/Pie.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-import java.io.Serializable;
-
-/**
- * Provides a simple implementation of chart.js pie chart.
- *
- * @see <a href="http://www.chartjs.org/docs/#pieChart";>chart.js docs</a>
- */
-public class Pie extends SimpleChart<DoughnutAndPieChartData, PieChartOptions> 
implements Serializable {
-
-    private static final long serialVersionUID = -6898362145345731457L;
-
-    @Override
-    public PieChartOptions getOptions() {
-        if (options == null) {
-            options = new PieChartOptions();
-        }
-        return options;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/PieChartOptions.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/PieChartOptions.java
deleted file mode 100644
index 9177d8b8e5..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/PieChartOptions.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-/**
- * Provides options, that are available for {@link Pie}.
- */
-public class PieChartOptions extends ChartOptions {
-
-    private static final long serialVersionUID = -5356780831848556616L;
-
-    /** The segment show stroke. */
-    private Boolean segmentShowStroke;
-
-    /** The segment stroke color. */
-    private String segmentStrokeColor;
-
-    /** The segment stroke width. */
-    private Integer segmentStrokeWidth;
-
-    /** The animate rotate. */
-    private Boolean animateRotate;
-
-    /** The animate scale. */
-    private Boolean animateScale;
-
-    private String legendTemplate = "<ul 
class=\"<%=name.toLowerCase()%>-legend\">"
-            + "<% for (var i=0; i<segments.length; i++){%><li>"
-            + "<span style=\"background-color:<%=segments[i].fillColor%>\">"
-            + 
"<%if(segments[i].label){%><%=segments[i].label%><%}%></span></li><%}%></ul>";
-
-    public String getLegendTemplate() {
-        return legendTemplate;
-    }
-
-    public void setLegendTemplate(final String legendTemplate) {
-        this.legendTemplate = legendTemplate;
-    }
-
-    /**
-     * Gets the segment show stroke.
-     *
-     * @return the segment show stroke
-     */
-    public Boolean getSegmentShowStroke() {
-        return segmentShowStroke;
-    }
-
-    /**
-     * Sets the segment show stroke.
-     *
-     * @param segmentShowStroke decides whether we should show a stroke on 
each segment (default is true)
-     */
-    public void setSegmentShowStroke(final Boolean segmentShowStroke) {
-        this.segmentShowStroke = segmentShowStroke;
-    }
-
-    /**
-     * Gets the segment stroke color.
-     *
-     * @return the segment stroke color
-     */
-    public String getSegmentStrokeColor() {
-        return segmentStrokeColor;
-    }
-
-    /**
-     * Sets the segment stroke color.
-     *
-     * @param segmentStrokeColor the new segment stroke color (default is 
"#fff").
-     */
-    public void setSegmentStrokeColor(final String segmentStrokeColor) {
-        this.segmentStrokeColor = segmentStrokeColor;
-    }
-
-    /**
-     * Gets the segment stroke width.
-     *
-     * @return the segment stroke width
-     */
-    public Integer getSegmentStrokeWidth() {
-        return segmentStrokeWidth;
-    }
-
-    /**
-     * Sets the segment stroke width.
-     *
-     * @param segmentStrokeWidth the new segment stroke width (default is 2).
-     */
-    public void setSegmentStrokeWidth(final Integer segmentStrokeWidth) {
-        this.segmentStrokeWidth = segmentStrokeWidth;
-    }
-
-    /**
-     * Gets the animate rotate.
-     *
-     * @return the animate rotate
-     */
-    public Boolean getAnimateRotate() {
-        return animateRotate;
-    }
-
-    /**
-     * Sets the animate rotate.
-     *
-     * @param animateRotate decides whether we animate the rotation of the pie 
(default is true).
-     */
-    public void setAnimateRotate(final Boolean animateRotate) {
-        this.animateRotate = animateRotate;
-    }
-
-    /**
-     * Gets the animate scale.
-     *
-     * @return the animate scale
-     */
-    public Boolean getAnimateScale() {
-        return animateScale;
-    }
-
-    /**
-     * Sets the animate scale.
-     *
-     * @param animateScale decides whether we animate scaling the Pie from the 
center (default is false).
-     */
-    public void setAnimateScale(final Boolean animateScale) {
-        this.animateScale = animateScale;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/PointColorDataSet.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/PointColorDataSet.java
deleted file mode 100644
index 7d96b218b4..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/PointColorDataSet.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-import java.util.List;
-
-/**
- * Provides some additional point color and point stroke color information.
- */
-public abstract class PointColorDataSet extends BaseDataSet {
-
-    private static final long serialVersionUID = 1581171902504828797L;
-
-    /** The point color. */
-    private String pointColor = "rgba(220,220,220,1)";
-
-    /** The point stroke color. */
-    private String pointStrokeColor = "#fff";
-
-    /**
-     * Instantiates a new abstract point color data set.
-     *
-     * @param data the values
-     */
-    public PointColorDataSet(final List<? extends Number> data) {
-        super(data);
-    }
-
-    /**
-     * Gets the point color.
-     *
-     * @return the point color
-     */
-    public String getPointColor() {
-        return pointColor;
-    }
-
-    /**
-     * Sets the point color.
-     *
-     * @param pointColor the point color
-     */
-    public void setPointColor(final String pointColor) {
-        this.pointColor = pointColor;
-    }
-
-    /**
-     * Gets the point stroke color.
-     *
-     * @return the point stroke color
-     */
-    public String getPointStrokeColor() {
-        return pointStrokeColor;
-    }
-
-    /**
-     * Sets the point stroke color.
-     *
-     * @param pointStrokeColor the point stroke color
-     */
-    public void setPointStrokeColor(final String pointStrokeColor) {
-        this.pointStrokeColor = pointStrokeColor;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/SimpleChart.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/SimpleChart.java
deleted file mode 100644
index 7aa5ef912d..0000000000
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/SimpleChart.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-/**
- * Provides chart data and options.
- *
- * @param <D> the generic type of chart data
- * @param <O> the generic type of chart options
- */
-public abstract class SimpleChart<D extends DoughnutAndPieChartData, O extends 
ChartOptions> extends Chart<O> {
-
-    private static final long serialVersionUID = 4176838766615656412L;
-
-    /** The data. */
-    protected D data;
-
-    public D getData() {
-        return data;
-    }
-
-    public void setData(final D data) {
-        this.data = data;
-    }
-}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartData.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/data/ChartData.java
similarity index 69%
rename from 
client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartData.java
rename to 
client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/data/ChartData.java
index 33510c9243..a2c6350740 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/ChartData.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/data/ChartData.java
@@ -1,47 +1,42 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.console.chartjs;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Provides labels and datasets.
- *
- * @param <T> the dataset type
- */
-abstract class ChartData<T extends BaseDataSet> implements Serializable {
-
-    private static final long serialVersionUID = -5230056951310645070L;
-
-    /** The labels. */
-    private final List<String> labels = new ArrayList<>();
-
-    /** The datasets. */
-    private final List<T> datasets = new ArrayList<>();
-
-    public List<String> getLabels() {
-        return labels;
-    }
-
-    public List<T> getDatasets() {
-        return datasets;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.chartjs.data;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ChartData<T extends Dataset> implements Serializable {
+
+    private static final long serialVersionUID = -8489073681001237058L;
+
+    private final List<String> labels = new ArrayList<>();
+
+    private final List<Dataset> datasets = new ArrayList<>();
+
+    public List<String> getLabels() {
+        return labels;
+    }
+
+    public List<Dataset> getDatasets() {
+        return datasets;
+    }
+}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/data/Dataset.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/data/Dataset.java
new file mode 100644
index 0000000000..5fb7e0575c
--- /dev/null
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/data/Dataset.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.chartjs.data;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public abstract class Dataset implements Serializable {
+
+    private static final long serialVersionUID = -9143409945075593686L;
+
+    private final List<Number> data = new ArrayList<>();
+
+    private final List<String> label = new ArrayList<>();
+
+    private final List<String> backgroundColor = new ArrayList<>();
+
+    private final List<String> borderColor = new ArrayList<>();
+
+    private Boolean hidden;
+
+    private Double tension;
+
+    public Double getTension() {
+        return tension;
+    }
+
+    public void setTension(final Double tension) {
+        this.tension = tension;
+    }
+
+    public List<Number> getData() {
+        return data;
+    }
+
+    public List<String> getLabel() {
+        return label;
+    }
+
+    public List<String> getBackgroundColor() {
+        return backgroundColor;
+    }
+
+    public List<String> getBorderColor() {
+        return borderColor;
+    }
+
+    public Boolean getHidden() {
+        return hidden;
+    }
+
+    public void setHidden(final Boolean hidden) {
+        this.hidden = hidden;
+    }
+}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/Animation.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/Animation.java
new file mode 100644
index 0000000000..c909f81d0c
--- /dev/null
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/Animation.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.chartjs.options;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.io.Serializable;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class Animation implements Serializable {
+
+    private static final long serialVersionUID = 3958509378965197343L;
+
+    private Integer duration;
+
+    private String easing;
+
+    private Boolean loop;
+
+    private AnimationCallback onProgress;
+
+    private AnimationCallback onComplete;
+
+    public Integer getDuration() {
+        return duration;
+    }
+
+    public void setDuration(final Integer duration) {
+        this.duration = duration;
+    }
+
+    public String getEasing() {
+        return easing;
+    }
+
+    public void setEasing(final String easing) {
+        this.easing = easing;
+    }
+
+    public Boolean getLoop() {
+        return loop;
+    }
+
+    public void setLoop(final Boolean loop) {
+        this.loop = loop;
+    }
+
+    public AnimationCallback getOnProgress() {
+        return onProgress;
+    }
+
+    public void setOnProgress(final AnimationCallback onProgress) {
+        this.onProgress = onProgress;
+    }
+
+    public AnimationCallback getOnComplete() {
+        return onComplete;
+    }
+
+    public void setOnComplete(final AnimationCallback onComplete) {
+        this.onComplete = onComplete;
+    }
+}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/AnimationCallback.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/AnimationCallback.java
new file mode 100644
index 0000000000..f0fec102be
--- /dev/null
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/AnimationCallback.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.chartjs.options;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonRawValue;
+import java.io.Serializable;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class AnimationCallback implements Serializable {
+
+    private static final long serialVersionUID = 8947792440189446252L;
+
+    @JsonRawValue
+    private String body;
+
+    public AnimationCallback(final String body) {
+        this.body = body;
+    }
+
+    public String getBody() {
+        return body;
+    }
+
+    public void setBody(final String body) {
+        this.body = body;
+    }
+}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/ChartOptions.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/ChartOptions.java
new file mode 100644
index 0000000000..8f924791c3
--- /dev/null
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/ChartOptions.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.syncope.client.console.chartjs.options;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.io.Serializable;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ChartOptions implements Serializable {
+
+    private static final long serialVersionUID = -424268454800409829L;
+
+    private Boolean responsive;
+
+    private Boolean maintainAspectRatio;
+
+    private Animation animation;
+
+    private Plugins plugins;
+
+    private Scales scales;
+
+    public Boolean getResponsive() {
+        return responsive;
+    }
+
+    public void setResponsive(final Boolean responsive) {
+        this.responsive = responsive;
+    }
+
+    public Boolean getMaintainAspectRatio() {
+        return maintainAspectRatio;
+    }
+
+    public void setMaintainAspectRatio(final Boolean maintainAspectRatio) {
+        this.maintainAspectRatio = maintainAspectRatio;
+    }
+
+    public Animation getAnimation() {
+        return animation;
+    }
+
+    public void setAnimation(final Animation animation) {
+        this.animation = animation;
+    }
+
+    public Plugins getPlugins() {
+        return plugins;
+    }
+
+    public void setPlugins(final Plugins plugins) {
+        this.plugins = plugins;
+    }
+
+    public Scales getScales() {
+        return scales;
+    }
+
+    public void setScales(final Scales scales) {
+        this.scales = scales;
+    }
+}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/Plugins.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/Plugins.java
new file mode 100644
index 0000000000..785ebabce9
--- /dev/null
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/Plugins.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.syncope.client.console.chartjs.options;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.io.Serializable;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class Plugins implements Serializable {
+
+    private static final long serialVersionUID = 1839738480949285923L;
+
+    private TooltipOptions tooltip;
+
+    public TooltipOptions getTooltip() {
+        return tooltip;
+    }
+
+    public void setTooltip(final TooltipOptions tooltip) {
+        this.tooltip = tooltip;
+    }
+}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/Scale.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/Scale.java
new file mode 100644
index 0000000000..10fed55abe
--- /dev/null
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/Scale.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.console.chartjs.options;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.io.Serializable;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class Scale implements Serializable {
+
+    private static final long serialVersionUID = 1870456183966939178L;
+
+    private Boolean display;
+
+    private Number min;
+
+    private Number max;
+
+    private Boolean beginAtZero;
+
+    private String type;
+
+    public Boolean getDisplay() {
+        return display;
+    }
+
+    public void setDisplay(final Boolean display) {
+        this.display = display;
+    }
+
+    public Number getMin() {
+        return min;
+    }
+
+    public void setMin(final Number min) {
+        this.min = min;
+    }
+
+    public Number getMax() {
+        return max;
+    }
+
+    public void setMax(final Number max) {
+        this.max = max;
+    }
+
+    public Boolean getBeginAtZero() {
+        return beginAtZero;
+    }
+
+    public void setBeginAtZero(final Boolean beginAtZero) {
+        this.beginAtZero = beginAtZero;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(final String type) {
+        this.type = type;
+    }
+}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/Scales.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/Scales.java
new file mode 100644
index 0000000000..c2085f4f2d
--- /dev/null
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/Scales.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.syncope.client.console.chartjs.options;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class Scales implements Serializable {
+
+    private static final long serialVersionUID = 9016231209839859089L;
+
+    private final Map<String, Scale> x = new HashMap<>();
+
+    private final Map<String, Scale> y = new HashMap<>();
+
+    public Map<String, Scale> getX() {
+        return x;
+    }
+
+    public Map<String, Scale> getY() {
+        return y;
+    }
+
+    public void setX(final Scale scale) {
+        x.clear();
+        x.put("x", scale);
+    }
+
+    public void setY(final Scale scale) {
+        y.clear();
+        y.put("y", scale);
+    }
+}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/TooltipCallback.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/TooltipCallback.java
new file mode 100644
index 0000000000..eb5abcc8f9
--- /dev/null
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/TooltipCallback.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.syncope.client.console.chartjs.options;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonRawValue;
+import java.io.Serializable;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class TooltipCallback implements Serializable {
+
+    private static final long serialVersionUID = -958940262832944145L;
+
+    @JsonRawValue
+    private String label;
+
+    public String getLabel() {
+        return label;
+    }
+
+    public TooltipCallback setLabel(final String label) {
+        this.label = label;
+        return this;
+    }
+}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/TooltipOptions.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/TooltipOptions.java
new file mode 100644
index 0000000000..f4d4547c63
--- /dev/null
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/chartjs/options/TooltipOptions.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.syncope.client.console.chartjs.options;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import java.io.Serializable;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class TooltipOptions implements Serializable {
+
+    private static final long serialVersionUID = -6369563965405381630L;
+
+    private boolean enabled = true;
+
+    private TooltipCallback callbacks;
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(final boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public TooltipCallback getCallbacks() {
+        return callbacks;
+    }
+
+    public void setCallbacks(final TooltipCallback callbacks) {
+        this.callbacks = callbacks;
+    }
+}
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/AnyByRealmWidget.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/AnyByRealmWidget.java
index 82f176d921..a0c8642f1f 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/AnyByRealmWidget.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/AnyByRealmWidget.java
@@ -26,10 +26,15 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.Strings;
-import org.apache.syncope.client.console.chartjs.Bar;
-import org.apache.syncope.client.console.chartjs.BarDataSet;
+import org.apache.syncope.client.console.chartjs.Chart;
 import org.apache.syncope.client.console.chartjs.ChartJSPanel;
+import org.apache.syncope.client.console.chartjs.ChartType;
+import org.apache.syncope.client.console.chartjs.data.Dataset;
+import org.apache.syncope.client.console.chartjs.options.Plugins;
+import org.apache.syncope.client.console.chartjs.options.Scale;
+import org.apache.syncope.client.console.chartjs.options.Scales;
+import org.apache.syncope.client.console.chartjs.options.TooltipCallback;
+import org.apache.syncope.client.console.chartjs.options.TooltipOptions;
 import org.apache.wicket.model.Model;
 
 public class AnyByRealmWidget extends BaseWidget {
@@ -39,15 +44,12 @@ public class AnyByRealmWidget extends BaseWidget {
     private static final int MAX_REALMS = 9;
 
     private Map<String, Long> usersByRealm;
-
     private Map<String, Long> groupsByRealm;
 
     private String anyType1;
-
     private Map<String, Long> any1ByRealm;
 
     private String anyType2;
-
     private Map<String, Long> any2ByRealm;
 
     private final ChartJSPanel chart;
@@ -62,21 +64,23 @@ public class AnyByRealmWidget extends BaseWidget {
             final Map<String, Long> any2ByRealm) {
 
         super(id);
+
         this.usersByRealm = usersByRealm;
         this.groupsByRealm = groupsByRealm;
         this.anyType1 = anyType1;
         this.any1ByRealm = any1ByRealm;
         this.anyType2 = anyType2;
         this.any2ByRealm = any2ByRealm;
+
         setOutputMarkupId(true);
 
-        chart = new ChartJSPanel(
-                "chart",
+        chart = new ChartJSPanel("chart",
                 Model.of(build(usersByRealm, groupsByRealm, anyType1, 
any1ByRealm, anyType2, any2ByRealm)));
+
         add(chart);
     }
 
-    private Bar build(
+    private static Chart build(
             final Map<String, Long> usersByRealm,
             final Map<String, Long> groupsByRealm,
             final String anyType1,
@@ -84,12 +88,13 @@ public class AnyByRealmWidget extends BaseWidget {
             final String anyType2,
             final Map<String, Long> any2ByRealm) {
 
-        List<Long> userValues = new ArrayList<>();
-        List<Long> groupValues = new ArrayList<>();
-        List<Long> any1Values = new ArrayList<>();
-        List<Long> any2Values = new ArrayList<>();
+        final List<String> labels = new ArrayList<>();
+        final List<Long> userValues = new ArrayList<>();
+        final List<Long> groupValues = new ArrayList<>();
+        final List<Long> any1Values = new ArrayList<>();
+        final List<Long> any2Values = new ArrayList<>();
 
-        Set<String> realmSet = new HashSet<>();
+        final Set<String> realmSet = new HashSet<>();
         realmSet.addAll(usersByRealm.keySet());
         realmSet.addAll(groupsByRealm.keySet());
         if (any1ByRealm != null) {
@@ -101,51 +106,79 @@ public class AnyByRealmWidget extends BaseWidget {
         List<String> realms = new ArrayList<>(realmSet);
         realms.sort(Comparator.naturalOrder());
 
-        Bar bar = new Bar();
-        bar.getOptions().setBarShowStroke(true);
-        bar.getOptions().setBarStrokeWidth(2);
-        bar.getOptions().setBarValueSpacing(5);
-        bar.getOptions().setBarDatasetSpacing(1);
-        bar.getOptions().setResponsive(true);
-        bar.getOptions().setMaintainAspectRatio(true);
-        bar.getOptions().setMultiTooltipTemplate("<%= datasetLabel %> - <%= 
value %>");
-
-        for (int i = 0; i < realms.size() && i < MAX_REALMS; i++) {
-            bar.getData().getLabels().add(
-                    
Strings.CS.prependIfMissing(StringUtils.substringAfterLast(realms.get(i), "/"), 
"/"));
-
-            userValues.add(usersByRealm.get(realms.get(i)));
-            groupValues.add(groupsByRealm.get(realms.get(i)));
+        final int limit = Math.min(realms.size(), MAX_REALMS);
+
+        for (int i = 0; i < limit; i++) {
+            final String realm = realms.get(i);
+
+            labels.add(StringUtils.substringAfterLast(realm, "/"));
+
+            userValues.add(usersByRealm.getOrDefault(realm, 0L));
+            groupValues.add(groupsByRealm.getOrDefault(realm, 0L));
+
             if (any1ByRealm != null) {
-                any1Values.add(any1ByRealm.get(realms.get(i)));
+                any1Values.add(any1ByRealm.getOrDefault(realm, 0L));
             }
             if (any2ByRealm != null) {
-                any2Values.add(any2ByRealm.get(realms.get(i)));
+                any2Values.add(any2ByRealm.getOrDefault(realm, 0L));
             }
         }
 
-        BarDataSet userDataSet = new BarDataSet(userValues);
-        userDataSet.setBackgroundColor("orange");
-        userDataSet.setLabel(getString("users"));
-        bar.getData().getDatasets().add(userDataSet);
-        BarDataSet groupDataSet = new BarDataSet(groupValues);
-        groupDataSet.setBackgroundColor("red");
-        groupDataSet.setLabel(getString("groups"));
-        bar.getData().getDatasets().add(groupDataSet);
+        final Chart chart = new Chart();
+        chart.setType(ChartType.bar);
+
+        chart.getData().getLabels().addAll(labels);
+
+        chart.getOptions().setResponsive(true);
+        chart.getOptions().setMaintainAspectRatio(true);
+
+        final TooltipOptions tooltip = new TooltipOptions();
+        tooltip.setEnabled(true);
+
+        final TooltipCallback callbacks = new TooltipCallback();
+        callbacks.setLabel("function(context) {return context.dataset.label + 
': ' + context.formattedValue;}");
+
+        tooltip.setCallbacks(callbacks);
+
+        final Plugins plugins = new Plugins();
+        plugins.setTooltip(tooltip);
+
+        chart.getOptions().setPlugins(plugins);
+
+        final Scale x = new Scale();
+        x.setDisplay(true);
+
+        final Scale y = new Scale();
+        y.setDisplay(true);
+        y.setMin(0);
+
+        final Scales scales = new Scales();
+        scales.setX(x);
+        scales.setY(y);
+
+        chart.getOptions().setScales(scales);
+
+        chart.getData().getDatasets().add(dataset("Users", "orange", 
userValues));
+        chart.getData().getDatasets().add(dataset("Groups", "red", 
groupValues));
+
         if (anyType1 != null) {
-            BarDataSet any1DataSet = new BarDataSet(any1Values);
-            any1DataSet.setBackgroundColor("green");
-            any1DataSet.setLabel(anyType1);
-            bar.getData().getDatasets().add(any1DataSet);
+            chart.getData().getDatasets().add(dataset(anyType1, "green", 
any1Values));
         }
         if (anyType2 != null) {
-            BarDataSet any2DataSet = new BarDataSet(any2Values);
-            any2DataSet.setBackgroundColor("aqua");
-            any2DataSet.setLabel(anyType2);
-            bar.getData().getDatasets().add(any2DataSet);
+            chart.getData().getDatasets().add(dataset(anyType2, "aqua", 
any2Values));
         }
 
-        return bar;
+        return chart;
+    }
+
+    private static Dataset dataset(final String label, final String color, 
final List<Long> values) {
+        final Dataset ds = new Dataset() {
+        };
+        ds.getLabel().add(label);
+        ds.getBackgroundColor().add(color);
+        ds.getBorderColor().add(color);
+        ds.getData().addAll(values);
+        return ds;
     }
 
     public boolean refresh(
@@ -156,12 +189,12 @@ public class AnyByRealmWidget extends BaseWidget {
             final String anyType2,
             final Map<String, Long> any2ByRealm) {
 
-        if (!this.usersByRealm.equals(usersByRealm)
-                || !this.groupsByRealm.equals(groupsByRealm)
-                || (!(this.anyType1 == null && anyType1 == null) && 
!Objects.equals(this.anyType1, anyType1))
-                || !this.any1ByRealm.equals(any1ByRealm)
-                || (!(this.anyType2 == null && anyType2 == null) && 
!Objects.equals(this.anyType2, anyType2))
-                || !this.any2ByRealm.equals(any2ByRealm)) {
+        if (!Objects.equals(this.usersByRealm, usersByRealm)
+                || !Objects.equals(this.groupsByRealm, groupsByRealm)
+                || !Objects.equals(this.anyType1, anyType1)
+                || !Objects.equals(this.any1ByRealm, any1ByRealm)
+                || !Objects.equals(this.anyType2, anyType2)
+                || !Objects.equals(this.any2ByRealm, any2ByRealm)) {
 
             this.usersByRealm = usersByRealm;
             this.groupsByRealm = groupsByRealm;
@@ -175,6 +208,7 @@ public class AnyByRealmWidget extends BaseWidget {
 
             return true;
         }
+
         return false;
     }
 }
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/CompletenessWidget.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/CompletenessWidget.java
index 655a275bd2..181f13adde 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/CompletenessWidget.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/CompletenessWidget.java
@@ -22,9 +22,13 @@ import java.util.Map;
 import org.apache.commons.lang3.BooleanUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.BookmarkablePageLinkBuilder;
+import org.apache.syncope.client.console.chartjs.Chart;
 import org.apache.syncope.client.console.chartjs.ChartJSPanel;
-import org.apache.syncope.client.console.chartjs.Doughnut;
-import org.apache.syncope.client.console.chartjs.DoughnutAndPieChartData;
+import org.apache.syncope.client.console.chartjs.ChartType;
+import org.apache.syncope.client.console.chartjs.data.Dataset;
+import org.apache.syncope.client.console.chartjs.options.Plugins;
+import org.apache.syncope.client.console.chartjs.options.TooltipCallback;
+import org.apache.syncope.client.console.chartjs.options.TooltipOptions;
 import org.apache.syncope.client.console.pages.Notifications;
 import org.apache.syncope.client.console.pages.Policies;
 import org.apache.syncope.client.console.pages.Security;
@@ -62,7 +66,7 @@ public class CompletenessWidget extends BaseWidget {
         this.confCompleteness = confCompleteness;
         setOutputMarkupId(true);
 
-        Pair<Doughnut, Integer> built = build(confCompleteness);
+        Pair<Chart, Long> built = build(confCompleteness);
 
         chart = new ChartJSPanel("chart", Model.of(built.getLeft()));
         add(chart);
@@ -70,97 +74,110 @@ public class CompletenessWidget extends BaseWidget {
         actions = new WebMarkupContainer("actions");
         actions.setOutputMarkupPlaceholderTag(true);
         actions.setVisible(built.getRight() > 0);
-
         add(actions);
 
         policies = BookmarkablePageLinkBuilder.build("policies", 
Policies.class);
-        policies.setOutputMarkupPlaceholderTag(true);
         MetaDataRoleAuthorizationStrategy.authorize(policies, WebPage.ENABLE, 
IdRepoEntitlement.POLICY_LIST);
         actions.add(policies);
-        policies.setVisible(
-                
!confCompleteness.get(NumbersInfo.ConfItem.ACCOUNT_POLICY.name())
-                || 
!confCompleteness.get(NumbersInfo.ConfItem.PASSWORD_POLICY.name()));
 
         notifications = BookmarkablePageLinkBuilder.build("notifications", 
Notifications.class);
-        notifications.setOutputMarkupPlaceholderTag(true);
-        MetaDataRoleAuthorizationStrategy.authorize(
-                notifications, WebPage.ENABLE, 
IdRepoEntitlement.NOTIFICATION_LIST);
+        MetaDataRoleAuthorizationStrategy.authorize(notifications, 
WebPage.ENABLE, IdRepoEntitlement.NOTIFICATION_LIST);
         actions.add(notifications);
-        
notifications.setVisible(!confCompleteness.get(NumbersInfo.ConfItem.NOTIFICATION.name()));
 
         types = BookmarkablePageLinkBuilder.build("types", Types.class);
-        types.setOutputMarkupPlaceholderTag(true);
         MetaDataRoleAuthorizationStrategy.authorize(types, WebPage.ENABLE, 
IdRepoEntitlement.ANYTYPECLASS_LIST);
         actions.add(types);
-        
types.setVisible(!confCompleteness.get(NumbersInfo.ConfItem.ANY_TYPE.name()));
 
         securityquestions = 
BookmarkablePageLinkBuilder.build("securityquestions", Security.class);
-        securityquestions.setOutputMarkupPlaceholderTag(true);
         actions.add(securityquestions);
-        
securityquestions.setVisible(!confCompleteness.get(NumbersInfo.ConfItem.SECURITY_QUESTION.name()));
 
         roles = BookmarkablePageLinkBuilder.build("roles", Security.class);
-        roles.setOutputMarkupPlaceholderTag(true);
         MetaDataRoleAuthorizationStrategy.authorize(roles, WebPage.ENABLE, 
IdRepoEntitlement.ROLE_LIST);
         actions.add(roles);
-        
roles.setVisible(!confCompleteness.get(NumbersInfo.ConfItem.ROLE.name()));
+
+        
notifications.setVisible(!Boolean.TRUE.equals(confCompleteness.get(NumbersInfo.ConfItem.NOTIFICATION.name())));
+        
types.setVisible(!Boolean.TRUE.equals(confCompleteness.get(NumbersInfo.ConfItem.ANY_TYPE.name())));
+        securityquestions.setVisible(!Boolean.TRUE.equals(confCompleteness.get(
+                NumbersInfo.ConfItem.SECURITY_QUESTION.name())));
+        
roles.setVisible(!Boolean.TRUE.equals(confCompleteness.get(NumbersInfo.ConfItem.ROLE.name())));
+        
policies.setVisible(!Boolean.TRUE.equals(confCompleteness.get(NumbersInfo.ConfItem.ACCOUNT_POLICY.name()))
+                || 
!Boolean.TRUE.equals(confCompleteness.get(NumbersInfo.ConfItem.PASSWORD_POLICY.name())));
     }
 
-    private Pair<Doughnut, Integer> build(final Map<String, Boolean> 
confCompleteness) {
-        Doughnut doughnut = new Doughnut();
-        doughnut.getOptions().setResponsive(true);
-        doughnut.getOptions().setMaintainAspectRatio(true);
-        doughnut.getOptions().setTooltipTemplate("<%= label %>");
-
-        int done = 0;
-        int todo = 0;
-        for (Map.Entry<String, Boolean> entry : confCompleteness.entrySet()) {
-            if (BooleanUtils.isTrue(entry.getValue())) {
-                done += NumbersInfo.ConfItem.getScore(entry.getKey());
-            } else {
-                todo++;
+    private static Pair<Long, Long> buildWeights(final Map<String, Boolean> 
confCompleteness) {
+        long done = 0;
+        long total = 0;
+        for (NumbersInfo.ConfItem item : NumbersInfo.ConfItem.values()) {
+            long score = NumbersInfo.ConfItem.getScore(item);
+            if (score <= 0) {
+                continue;
+            }
+            total += score;
+            if (BooleanUtils.isTrue(confCompleteness.get(item.name()))) {
+                done += score;
             }
         }
+        return Pair.of(done, total);
+    }
 
-        DoughnutAndPieChartData data = new DoughnutAndPieChartData();
-        doughnut.setData(data);
-
-        DoughnutAndPieChartData.DataSet dataset = new 
DoughnutAndPieChartData.DataSet();
-        data.getDatasets().add(dataset);
-
-        dataset.getData().add(done);
-        dataset.getData().add(100 - done);
-
-        dataset.getBackgroundColor().add("green");
-        dataset.getBackgroundColor().add("red");
-
-        data.getLabels().add(getString("done"));
-        data.getLabels().add(getString("todo") + ": " + todo);
-
-        return Pair.of(doughnut, todo);
+    private Pair<Chart, Long> build(final Map<String, Boolean> 
confCompleteness) {
+        Pair<Long, Long> weights = buildWeights(confCompleteness);
+        long done = weights.getLeft();
+        long total = weights.getRight();
+        long todo = Math.max(0, total - done);
+        long donePercentage = total == 0 ? 0 : Math.round((double) done * 100 
/ total);
+        long todoPercentage = total == 0 ? 0 : 100 - donePercentage;
+
+        final Chart resultChart = new Chart();
+        resultChart.setType(ChartType.doughnut);
+        resultChart.getOptions().setResponsive(true);
+        resultChart.getOptions().setMaintainAspectRatio(true);
+
+        final TooltipOptions tooltip = new TooltipOptions();
+        tooltip.setEnabled(true);
+
+        final TooltipCallback callbacks = new TooltipCallback();
+        callbacks.setLabel("function(context) {return context.label;}");
+
+        tooltip.setCallbacks(callbacks);
+
+        final Plugins plugins = new Plugins();
+        plugins.setTooltip(tooltip);
+        resultChart.getOptions().setPlugins(plugins);
+
+        final Dataset ds = new Dataset() {
+        };
+        ds.getBackgroundColor().add("green");
+        ds.getBackgroundColor().add("red");
+        ds.getBorderColor().add("green");
+        ds.getBorderColor().add("red");
+        ds.getData().add(done);
+        ds.getData().add(todo);
+
+        resultChart.getData().getLabels().add(getString("done") + " (" + 
donePercentage + "%)");
+        resultChart.getData().getLabels().add(getString("todo") + " (" + 
todoPercentage + "%)");
+        resultChart.getData().getDatasets().add(ds);
+        return Pair.of(resultChart, todo);
     }
 
     public boolean refresh(final Map<String, Boolean> confCompleteness) {
+
         if (!this.confCompleteness.equals(confCompleteness)) {
             this.confCompleteness = confCompleteness;
 
-            Pair<Doughnut, Integer> built = build(confCompleteness);
+            Pair<Chart, Long> built = build(confCompleteness);
 
             chart.setDefaultModelObject(built.getLeft());
-
             actions.setVisible(built.getRight() > 0);
 
-            policies.setVisible(
-                    
!confCompleteness.get(NumbersInfo.ConfItem.ACCOUNT_POLICY.name())
-                    || 
!confCompleteness.get(NumbersInfo.ConfItem.PASSWORD_POLICY.name()));
-
-            
notifications.setVisible(!confCompleteness.get(NumbersInfo.ConfItem.NOTIFICATION.name()));
-
-            
types.setVisible(!confCompleteness.get(NumbersInfo.ConfItem.ANY_TYPE.name()));
-
-            
securityquestions.setVisible(!confCompleteness.get(NumbersInfo.ConfItem.SECURITY_QUESTION.name()));
-
-            
roles.setVisible(!confCompleteness.get(NumbersInfo.ConfItem.ROLE.name()));
+            notifications.setVisible(
+                    
!Boolean.TRUE.equals(confCompleteness.get(NumbersInfo.ConfItem.NOTIFICATION.name())));
+            
types.setVisible(!Boolean.TRUE.equals(confCompleteness.get(NumbersInfo.ConfItem.ANY_TYPE.name())));
+            
securityquestions.setVisible(!Boolean.TRUE.equals(confCompleteness.get(
+                    NumbersInfo.ConfItem.SECURITY_QUESTION.name())));
+            
roles.setVisible(!Boolean.TRUE.equals(confCompleteness.get(NumbersInfo.ConfItem.ROLE.name())));
+            
policies.setVisible(!Boolean.TRUE.equals(confCompleteness.get(NumbersInfo.ConfItem.ACCOUNT_POLICY.name()))
+                    || 
!Boolean.TRUE.equals(confCompleteness.get(NumbersInfo.ConfItem.PASSWORD_POLICY.name())));
 
             return true;
         }
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/LoadWidget.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/LoadWidget.java
index 3f60c65b2b..a5b0956923 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/LoadWidget.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/LoadWidget.java
@@ -21,10 +21,17 @@ package org.apache.syncope.client.console.widgets;
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.commons.lang3.time.DateFormatUtils;
+import org.apache.syncope.client.console.chartjs.Chart;
 import org.apache.syncope.client.console.chartjs.ChartJSPanel;
-import org.apache.syncope.client.console.chartjs.ChartOptions;
-import org.apache.syncope.client.console.chartjs.Line;
-import org.apache.syncope.client.console.chartjs.LineDataSet;
+import org.apache.syncope.client.console.chartjs.ChartType;
+import org.apache.syncope.client.console.chartjs.data.ChartData;
+import org.apache.syncope.client.console.chartjs.data.Dataset;
+import org.apache.syncope.client.console.chartjs.options.ChartOptions;
+import org.apache.syncope.client.console.chartjs.options.Plugins;
+import org.apache.syncope.client.console.chartjs.options.Scale;
+import org.apache.syncope.client.console.chartjs.options.Scales;
+import org.apache.syncope.client.console.chartjs.options.TooltipCallback;
+import org.apache.syncope.client.console.chartjs.options.TooltipOptions;
 import org.apache.syncope.common.lib.info.SystemInfo;
 import org.apache.wicket.model.Model;
 
@@ -42,49 +49,72 @@ public class LoadWidget extends BaseWidget {
         add(chart);
     }
 
-    private static Line build(final SystemInfo systeminfo) {
-        List<Double> cpuValues = new ArrayList<>();
-        List<Long> memValues = new ArrayList<>();
+    private static Chart build(final SystemInfo systeminfo) {
 
-        Line line = new Line();
-        line.getOptions().setPointDot(false);
-        line.getOptions().setDatasetFill(false);
-        line.getOptions().setResponsive(true);
-        line.getOptions().setMaintainAspectRatio(true);
-        line.getOptions().setTension(0.4);
-        line.getOptions().setMultiTooltipTemplate("<%= datasetLabel %>");
-
-        ChartOptions.Axis x = new ChartOptions.Axis();
-        x.setDisplay(false);
-        ChartOptions.Axis y = new ChartOptions.Axis();
-        y.setDisplay(false);
-        ChartOptions.Scales scales = new ChartOptions.Scales();
-        scales.setX(x);
-        scales.setY(y);
-        line.getOptions().setScales(scales);
+        final List<Double> cpuValues = new ArrayList<>();
+        final List<Long> memValues = new ArrayList<>();
+        final List<String> labels = new ArrayList<>();
 
         systeminfo.load().forEach(instant -> {
-            line.getData().getLabels().add(
-                    DateFormatUtils.ISO_8601_EXTENDED_DATETIME_FORMAT.format(
-                            systeminfo.startTime() + instant.uptime()));
+
+            
labels.add(DateFormatUtils.ISO_8601_EXTENDED_DATETIME_FORMAT.format(
+                    systeminfo.startTime() + instant.uptime()
+            ));
 
             cpuValues.add(instant.systemLoadAverage() * 1000);
             memValues.add(instant.totalMemory());
         });
 
-        LineDataSet cpuDataSet = new LineDataSet(cpuValues);
-        cpuDataSet.setLabel("CPU");
-        cpuDataSet.setPointColor("purple");
-        cpuDataSet.setBorderColor("purple");
-        line.getData().getDatasets().add(cpuDataSet);
+        Dataset cpu = new Dataset() {
+        };
+        cpu.getLabel().add("CPU");
+        cpu.getData().addAll(cpuValues);
+        cpu.getBorderColor().add("purple");
+        cpu.getBackgroundColor().add("purple");
+        cpu.setTension(0.4);
+
+        Dataset mem = new Dataset() {
+        };
+        mem.getLabel().add("MEM");
+        mem.getData().addAll(memValues);
+        mem.getBorderColor().add("grey");
+        mem.getBackgroundColor().add("grey");
+        mem.setTension(0.4);
+
+        ChartData<Dataset> data = new ChartData<>();
+        data.getLabels().addAll(labels);
+        data.getDatasets().addAll(List.of(cpu, mem));
+
+        TooltipOptions tooltip = new TooltipOptions();
+        tooltip.setEnabled(true);
+        tooltip.setCallbacks(new TooltipCallback().setLabel(
+                "function(context) {return context.dataset.label + ': ' + 
context.formattedValue;}"));
+
+        Plugins plugins = new Plugins();
+        plugins.setTooltip(tooltip);
+
+        Scale x = new Scale();
+        x.setDisplay(false);
+
+        Scale y = new Scale();
+        y.setDisplay(false);
+
+        Scales scales = new Scales();
+        scales.setX(x);
+        scales.setY(y);
+
+        ChartOptions options = new ChartOptions();
+        options.setResponsive(true);
+        options.setMaintainAspectRatio(true);
+        options.setPlugins(plugins);
+        options.setScales(scales);
 
-        LineDataSet memDataSet = new LineDataSet(memValues);
-        memDataSet.setLabel("MEM");
-        memDataSet.setPointColor("grey");
-        memDataSet.setBorderColor("grey");
-        line.getData().getDatasets().add(memDataSet);
+        Chart chart = new Chart();
+        chart.setType(ChartType.line);
+        chart.setData(data);
+        chart.setOptions(options);
 
-        return line;
+        return chart;
     }
 
     public void refresh(final SystemInfo systeminfo) {
diff --git 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/UsersByStatusWidget.java
 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/UsersByStatusWidget.java
index b0242e399b..fc7e0bcd34 100644
--- 
a/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/UsersByStatusWidget.java
+++ 
b/client/idrepo/console/src/main/java/org/apache/syncope/client/console/widgets/UsersByStatusWidget.java
@@ -18,10 +18,14 @@
  */
 package org.apache.syncope.client.console.widgets;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
+import org.apache.syncope.client.console.chartjs.Chart;
 import org.apache.syncope.client.console.chartjs.ChartJSPanel;
-import org.apache.syncope.client.console.chartjs.Doughnut;
-import org.apache.syncope.client.console.chartjs.DoughnutAndPieChartData;
+import org.apache.syncope.client.console.chartjs.ChartType;
+import org.apache.syncope.client.console.chartjs.data.ChartData;
+import org.apache.syncope.client.console.chartjs.data.Dataset;
 import org.apache.wicket.model.Model;
 
 public class UsersByStatusWidget extends BaseWidget {
@@ -43,27 +47,38 @@ public class UsersByStatusWidget extends BaseWidget {
         add(chart);
     }
 
-    private static Doughnut build(final Map<String, Long> usersByStatus) {
-        Doughnut doughnut = new Doughnut();
-        doughnut.getOptions().setResponsive(true);
-        doughnut.getOptions().setMaintainAspectRatio(true);
+    private static Chart build(final Map<String, Long> usersByStatus) {
+        final List<String> labels = new ArrayList<>();
+        final List<Long> values = new ArrayList<>();
 
-        DoughnutAndPieChartData data = new DoughnutAndPieChartData();
-        doughnut.setData(data);
-
-        DoughnutAndPieChartData.DataSet dataset = new 
DoughnutAndPieChartData.DataSet();
-        data.getDatasets().add(dataset);
-
-        int i = 0;
         for (Map.Entry<String, Long> entry : usersByStatus.entrySet()) {
-            dataset.getData().add(entry.getValue());
-            dataset.getBackgroundColor().add(COLORS[i % 5]);
-            data.getLabels().add(entry.getKey());
+            labels.add(entry.getKey());
+            values.add(entry.getValue());
+        }
 
-            i++;
+        final List<String> colors = new ArrayList<>();
+        for (int i = 0; i < values.size(); i++) {
+            colors.add(COLORS[i % COLORS.length]);
         }
 
-        return doughnut;
+        Dataset dataset = new Dataset() {
+        };
+        dataset.getData().addAll(values);
+        dataset.getBackgroundColor().addAll(colors);
+        dataset.getBorderColor().addAll(colors);
+
+        List<Dataset> datasets = new ArrayList<>();
+        datasets.add(dataset);
+
+        ChartData<Dataset> data = new ChartData<>();
+        data.getLabels().addAll(labels);
+        data.getDatasets().addAll(datasets);
+
+        Chart chart = new Chart();
+        chart.setType(ChartType.doughnut);
+        chart.setData(data);
+
+        return chart;
     }
 
     public boolean refresh(final Map<String, Long> usersByStatus) {
diff --git 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/info/NumbersInfo.java
 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/info/NumbersInfo.java
index 7d2ed8b900..3f29dabf8c 100644
--- 
a/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/info/NumbersInfo.java
+++ 
b/common/idrepo/lib/src/main/java/org/apache/syncope/common/lib/info/NumbersInfo.java
@@ -56,14 +56,8 @@ public record NumbersInfo(
             this.score = score;
         }
 
-        public static int getScore(final String name) {
-            int score = 0;
-            for (ConfItem value : values()) {
-                if (value.name().equals(name)) {
-                    score = value.score;
-                }
-            }
-            return score;
+        public static int getScore(final ConfItem item) {
+            return item == null ? 0 : item.score;
         }
     }
 }
diff --git a/pom.xml b/pom.xml
index f2e3a17046..ba830b5f81 100644
--- a/pom.xml
+++ b/pom.xml
@@ -482,7 +482,7 @@ under the License.
     <codemirror.version>5.62.2</codemirror.version>
     <googlediffmatchpath.version>20121119-1</googlediffmatchpath.version>
     <jsplumb.version>2.0.7</jsplumb.version>
-    <chartjs.version>4.4.3</chartjs.version>
+    <chartjs.version>4.5.1</chartjs.version>
 
     <wicket.version>10.9.1</wicket.version>
     <wicketstuff.version>10.9.2</wicketstuff.version>

Reply via email to