/******************************************************************************* | |
* Copyright (c) 2016 Parasoft. | |
* | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Eclipse Public License v2.0 | |
* which accompanies this distribution, and is available at | |
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html | |
* | |
* SPDX-License-Identifier: EPL-2.0 | |
* | |
* Contributors: | |
* Janusz Studzizba - initial API and implementation | |
* Dariusz Oszczedlowski - initial API and implementation | |
* Magdalena Gniewek - initial API and implementation | |
* Michal Wlodarczyk - initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.opencert.webapp.reports.view.metrics; | |
import java.awt.Color; | |
import java.awt.Font; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.HashMap; | |
import java.util.List; | |
import com.vaadin.annotations.Theme; | |
import com.vaadin.data.Container.Hierarchical; | |
import com.vaadin.ui.Component; | |
import com.vaadin.ui.CustomComponent; | |
import com.vaadin.ui.TreeTable; | |
import com.vaadin.ui.VerticalLayout; | |
import org.eclipse.opencert.webapp.reports.manager.BaselineManager; | |
import org.eclipse.opencert.webapp.reports.util.SpringContextHelper; | |
import org.eclipse.opencert.webapp.reports.view.metrics.JFreeChartWrapper; | |
import org.jfree.chart.ChartFactory; | |
import org.jfree.chart.ChartUtilities; | |
import org.jfree.chart.JFreeChart; | |
import org.jfree.chart.axis.NumberAxis; | |
import org.jfree.chart.labels.ItemLabelAnchor; | |
import org.jfree.chart.labels.ItemLabelPosition; | |
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; | |
import org.jfree.chart.plot.CategoryPlot; | |
import org.jfree.chart.plot.PlotOrientation; | |
import org.jfree.chart.renderer.category.BarRenderer; | |
import org.jfree.chart.renderer.category.StandardBarPainter; | |
import org.jfree.data.category.CategoryDataset; | |
import org.jfree.data.category.DefaultCategoryDataset; | |
import org.jfree.ui.TextAnchor; | |
import org.eclipse.opencert.apm.baseline.baseline.BaseApplicability; | |
import org.eclipse.opencert.apm.baseline.baseline.BaseApplicabilityLevel; | |
import org.eclipse.opencert.apm.baseline.baseline.BaseCriticalityApplicability; | |
import org.eclipse.opencert.apm.baseline.baseline.BaseCriticalityLevel; | |
import org.eclipse.opencert.apm.baseline.baseline.BaseRequirement; | |
@Theme("opencerttheme") | |
public class BaselineChartsMetrics | |
extends CustomComponent | |
{ | |
private static final long serialVersionUID = -8906969281431198342L; | |
private static final String BASE_ASSET_CHART_TITLE = "Base Asset Types"; | |
private static final String BASE_REQUIREMENTS_CHART_TITLE = "Number of Applicability and Criticality Levels"; | |
private static final String NO_DATA_AVAILABLE = "No Data Available"; | |
private HashMap<String,Integer> levels; | |
private List<String> criticLevels; | |
private List<String> appLevels; | |
private byte[] applicabilityCriticalityChart; | |
private byte[] assetsChart; | |
private Hierarchical dataDescription; | |
public BaselineChartsMetrics(long baselineFrameworkID) | |
{ | |
VerticalLayout mainPanel = new VerticalLayout(); | |
mainPanel.setStyleName("chartsSpacing"); | |
mainPanel.setSpacing(true); | |
BaselineManager baselineManager = (BaselineManager)SpringContextHelper.getBeanFromWebappContext(BaselineManager.SPRING_NAME); | |
int nRequirements = baselineManager.getBaseRequirements(baselineFrameworkID,true,true).size(); | |
int nArtefact = baselineManager.getBaseArtefacts(baselineFrameworkID,true).size(); | |
int nRole = baselineManager.getBaseRoles(baselineFrameworkID,true).size(); | |
int nTechnique = baselineManager.getBaseTechniques(baselineFrameworkID,true).size(); | |
int nActivity = baselineManager.getBaseActivities(baselineFrameworkID,true,true).size(); | |
levels = new HashMap<String,Integer>(); | |
criticLevels = new ArrayList<String>(); | |
appLevels = new ArrayList<String>(); | |
//countLevels(baselineManager.getBaseRequirements(baselineFrameworkID,true)); | |
Component c = addMoreData(baselineManager.getBaseRequirements(baselineFrameworkID,true,true)); | |
mainPanel.addComponent(baseRequirementsLevelsChart()); | |
mainPanel.addComponent(c); | |
mainPanel.addComponent(baseAssetTypeChart(nRequirements, nActivity, nTechnique, nRole, nArtefact)); | |
//add mainPanel component | |
setCompositionRoot(mainPanel); | |
setSizeFull(); | |
} | |
private Component addMoreData(List<BaseRequirement> baseRequirementsList) { | |
final TreeTable treetable = new TreeTable(); | |
treetable.setWidth("100%"); | |
treetable.addStyleName("resourceEfficiencyTable"); | |
// Define two columns for the built-in container | |
treetable.addContainerProperty("Requirements", String.class, ""); | |
treetable.addContainerProperty("Description", String.class, ""); | |
if(!baseRequirementsList.isEmpty()){ | |
for (BaseRequirement baseRequirement : baseRequirementsList){ | |
List<BaseApplicability> baseApplicabilityList = baseRequirement.getApplicability(); | |
if (!baseApplicabilityList.isEmpty()){ | |
Object requirement = treetable.addItem(new Object[]{"Requirement ID: "+baseRequirement.getId(), baseRequirement.getName()},null); | |
//get Requirement Info -- 2nd Level | |
Object reference = treetable.addItem(new Object[]{"Reference:", baseRequirement.getReference()},null); | |
Object assumptions = treetable.addItem(new Object[]{"Assumptions:", baseRequirement.getAssumptions()},null); | |
Object rationale = treetable.addItem(new Object[]{"Rationale:", baseRequirement.getRationale()},null); | |
Object image = treetable.addItem(new Object[]{"Image:", baseRequirement.getImage()},null); | |
Object annotations = treetable.addItem(new Object[]{"Annotations:", baseRequirement.getAnnotations()},null); | |
Object basAppl = treetable.addItem(new Object[]{"Base Applicability", ""},null); | |
//set hierarchy | |
treetable.setParent(reference,requirement); | |
treetable.setParent(assumptions,requirement); | |
treetable.setParent(rationale,requirement); | |
treetable.setParent(image,requirement); | |
treetable.setParent(annotations,requirement); | |
treetable.setParent(basAppl,requirement); | |
//expand all | |
treetable.setCollapsed(requirement, false); | |
// Disallow children from leaves | |
treetable.setChildrenAllowed(reference, false); | |
treetable.setChildrenAllowed(assumptions, false); | |
treetable.setChildrenAllowed(rationale, false); | |
treetable.setChildrenAllowed(image, false); | |
treetable.setChildrenAllowed(annotations, false); | |
treetable.setCollapsed(basAppl, false); | |
for (BaseApplicability baseApplicability : baseApplicabilityList){ | |
//Creating the 3rd level with a list of BaseApplicability | |
Object applicability = treetable.addItem(new Object[]{"ID: "+baseApplicability.getId() + " Name: " + baseApplicability.getName(), baseApplicability.getComments()},null); | |
//set parent requirement | |
treetable.setParent(applicability,basAppl); | |
//expand it | |
treetable.setCollapsed(applicability,false); | |
List<BaseCriticalityApplicability> baseCriticalityApplicabilityList = baseApplicability.getApplicCritic(); | |
if (!baseCriticalityApplicabilityList.isEmpty()){ | |
for (BaseCriticalityApplicability baseCriticalityApplicability : baseCriticalityApplicabilityList){ | |
BaseCriticalityLevel c = baseCriticalityApplicability.getCriticLevel(); | |
BaseApplicabilityLevel a = baseCriticalityApplicability.getApplicLevel(); | |
String key = c.getName() + " " + a.getName(); | |
//Creating 4th level | |
Object criticApp = treetable.addItem(new Object[]{key, baseCriticalityApplicability.getComment()},null); | |
//set parent requirement | |
treetable.setParent(criticApp,applicability); | |
// Disallow children from leaves | |
treetable.setChildrenAllowed(criticApp, false); | |
//count data for next chart | |
if(!criticLevels.contains(c.getName())) criticLevels.add(c.getName()); | |
if(!appLevels.contains(a.getName())) appLevels.add(a.getName()); | |
if(!levels.containsKey(key)){ | |
levels.put(key,1); | |
} | |
else levels.put(key, (levels.get(key))+1); | |
} | |
} | |
} | |
} | |
} | |
criticLevels.sort(null); | |
appLevels.sort(null); | |
} | |
dataDescription = treetable.getContainerDataSource(); | |
return treetable; | |
} | |
private Component baseRequirementsLevelsChart() { | |
final JFreeChart chart = ChartFactory.createBarChart( | |
BASE_REQUIREMENTS_CHART_TITLE, // chart title | |
"Levels", // domain axis label | |
"Number of Requirements", // range axis label | |
populateWithData(), // data | |
PlotOrientation.VERTICAL, // orientation | |
true, // include legend | |
true, // tooltips | |
false // urls | |
); | |
// get a reference to the plot for further customisation... | |
final CategoryPlot plot = chart.getCategoryPlot(); | |
plot.setNoDataMessage(NO_DATA_AVAILABLE); | |
plot.setNoDataMessageFont(new Font("Arial",Font.BOLD,14)); | |
plot.setNoDataMessagePaint(Color.RED); | |
plot.setBackgroundPaint(Color.white); | |
plot.setDomainGridlinePaint(Color.black); | |
plot.setRangeGridlinePaint(Color.black); | |
((BarRenderer) plot.getRenderer()).setBarPainter(new StandardBarPainter()); | |
// set the range axis to display integers only... | |
final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); | |
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); | |
final BarRenderer renderer = (BarRenderer) plot.getRenderer(); | |
renderer.setDrawBarOutline(false); | |
renderer.setBaseItemLabelGenerator( | |
new StandardCategoryItemLabelGenerator()); | |
renderer.setBaseItemLabelsVisible(true); | |
renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition( | |
ItemLabelAnchor.CENTER, TextAnchor.CENTER)); | |
renderer.setPositiveItemLabelPositionFallback(new ItemLabelPosition( | |
ItemLabelAnchor.OUTSIDE12, TextAnchor.CENTER)); | |
chart.setBackgroundPaint(Color.white); | |
chart.setAntiAlias(true); | |
chart.setBorderVisible(false); | |
try { | |
applicabilityCriticalityChart = ChartUtilities.encodeAsPNG(chart.createBufferedImage(600, 600)); | |
} catch (IOException e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
} | |
Component baseAssetTypeWrapper = new JFreeChartWrapper(chart); | |
baseAssetTypeWrapper.setHeight("80%"); | |
baseAssetTypeWrapper.setWidth("80%"); | |
baseAssetTypeWrapper.setStyleName("leftChartsSpacing"); | |
return baseAssetTypeWrapper; | |
} | |
private CategoryDataset populateWithData() { | |
final DefaultCategoryDataset dataset = new DefaultCategoryDataset(); | |
for (String criticLevel : criticLevels){ | |
for (String appLevel : appLevels){ | |
String key = criticLevel + " " + appLevel; | |
if(levels.containsKey(key)) dataset.addValue(levels.get(key), appLevel, criticLevel); | |
else dataset.addValue(0, appLevel, criticLevel); | |
} | |
} | |
return dataset; | |
} | |
private Component baseAssetTypeChart(int nRequirement, int nActivity, int nTechnique, int nRole, int nArtefact) { | |
final DefaultCategoryDataset baseAssetTypeData = new DefaultCategoryDataset(); | |
baseAssetTypeData.setValue(nRequirement,"Base Requirement", "Types"); | |
baseAssetTypeData.setValue(nActivity, "Base Activity", "Types"); | |
baseAssetTypeData.setValue(nTechnique, "Base Technique", "Types"); | |
baseAssetTypeData.setValue(nRole, "Base Role", "Types"); | |
baseAssetTypeData.setValue(nArtefact, "Base Artefact", "Types"); | |
final JFreeChart chart = ChartFactory.createBarChart( | |
BASE_ASSET_CHART_TITLE, // chart title | |
"", // domain axis label | |
"", // range axis label | |
baseAssetTypeData, // data | |
PlotOrientation.HORIZONTAL, // orientation | |
true, // include legend | |
true, // tooltips | |
false // urls | |
); | |
// get a reference to the plot for further customisation... | |
final CategoryPlot plot = chart.getCategoryPlot(); | |
plot.setNoDataMessage(NO_DATA_AVAILABLE); | |
plot.setNoDataMessageFont(new Font("Arial",Font.BOLD,14)); | |
plot.setNoDataMessagePaint(Color.RED); | |
plot.setBackgroundPaint(Color.white); | |
plot.setDomainGridlinePaint(Color.black); | |
plot.setRangeGridlinePaint(Color.black); | |
((BarRenderer) plot.getRenderer()).setBarPainter(new StandardBarPainter()); | |
// set the range axis to display integers only... | |
final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); | |
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); | |
// disable bar outlines... | |
final BarRenderer renderer = (BarRenderer) plot.getRenderer(); | |
renderer.setDrawBarOutline(false); | |
//number in bars | |
renderer.setBaseItemLabelGenerator( | |
new StandardCategoryItemLabelGenerator()); | |
renderer.setBaseItemLabelsVisible(true); | |
renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition( | |
ItemLabelAnchor.CENTER, TextAnchor.CENTER)); | |
renderer.setPositiveItemLabelPositionFallback(new ItemLabelPosition( | |
ItemLabelAnchor.OUTSIDE12, TextAnchor.CENTER)); | |
//With this uncommented all the name is visualized but in a ugly way.. | |
/* | |
final CategoryAxis axis = plot.getDomainAxis(); | |
axis.setCategoryLabelPositions( | |
CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 180.0) | |
); | |
*/ | |
chart.setBackgroundPaint(Color.white); | |
chart.setAntiAlias(true); | |
chart.setBorderVisible(false); | |
try { | |
assetsChart = ChartUtilities.encodeAsPNG(chart.createBufferedImage(600, 600)); | |
} catch (IOException e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
} | |
Component chartWrapper = new JFreeChartWrapper(chart); | |
chartWrapper.setHeight("80%"); | |
chartWrapper.setWidth("80%"); | |
chartWrapper.setStyleName("leftChartsSpacing"); | |
return chartWrapper; | |
} | |
public byte[] getNumberOfApplicabilityAndCriticalityLevelsChart(){ | |
return applicabilityCriticalityChart; | |
} | |
public byte[] getAssetsChart(){ | |
return assetsChart; | |
} | |
public String getBaseAssetChartTitle() { | |
return BASE_ASSET_CHART_TITLE; | |
} | |
public String getBaseRequirementsChartTitle() { | |
return BASE_REQUIREMENTS_CHART_TITLE; | |
} | |
public Hierarchical getDataContainer(){ | |
return dataDescription; | |
} | |
} | |