Skip to content
This repository was archived by the owner on Apr 6, 2024. It is now read-only.

Commit 83476b7

Browse files
committed
(GH-34) Add report using DevExtreme PivotGrid
1 parent c80ff62 commit 83476b7

File tree

5 files changed

+158
-1
lines changed

5 files changed

+158
-1
lines changed

src/Cake.Issues.Reporting.Generic.Tests/GenericIssueReportGeneratorTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public sealed class TheInternalCreateReportMethod
4343
[InlineData(GenericIssueReportTemplate.HtmlDiagnostic)]
4444
[InlineData(GenericIssueReportTemplate.HtmlDataTable)]
4545
[InlineData(GenericIssueReportTemplate.HtmlDxDataGrid)]
46+
[InlineData(GenericIssueReportTemplate.HtmlDxPivotGrid)]
4647
public void Should_Generate_Report_From_Embedded_Template(GenericIssueReportTemplate template)
4748
{
4849
// Given

src/Cake.Issues.Reporting.Generic/Cake.Issues.Reporting.Generic.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
<None Include="packages.config" />
8888
<EmbeddedResource Include="Templates\DataTable.cshtml" />
8989
<EmbeddedResource Include="Templates\DxDataGrid.cshtml" />
90+
<EmbeddedResource Include="Templates\DxPivotGrid.cshtml" />
9091
</ItemGroup>
9192
<ItemGroup>
9293
<Analyzer Include="..\packages\Microsoft.CodeQuality.Analyzers.2.6.0\analyzers\dotnet\cs\Microsoft.CodeQuality.Analyzers.dll" />

src/Cake.Issues.Reporting.Generic/GenericIssueReportTemplate.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ public enum GenericIssueReportTemplate
1818
/// <summary>
1919
/// Template for a HTML report containing a rich data grid with sorting, filtering, grouping and search capabilities.
2020
/// </summary>
21-
HtmlDxDataGrid
21+
HtmlDxDataGrid,
22+
23+
/// <summary>
24+
/// Template for a HTML report containing a pivot grid showing number of errors, warnings, suggestions and hints,
25+
/// with a detail drill down view and an overview chart.
26+
/// </summary>
27+
HtmlDxPivotGrid
2228
}
2329
}

src/Cake.Issues.Reporting.Generic/GenericIssueReportTemplateExtensions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ public static string GetTemplateResourceName(this GenericIssueReportTemplate tem
2525
case GenericIssueReportTemplate.HtmlDxDataGrid:
2626
return "DxDataGrid.cshtml";
2727

28+
case GenericIssueReportTemplate.HtmlDxPivotGrid:
29+
return "DxPivotGrid.cshtml";
30+
2831
default:
2932
throw new ArgumentOutOfRangeException(nameof(template));
3033
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
@model IEnumerable<Cake.Issues.IIssue>
2+
3+
<!DOCTYPE html>
4+
5+
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
6+
<head>
7+
<meta charset="utf-8" />
8+
<title>Issues Report</title>
9+
10+
@* DevExtreme dependencies *@
11+
<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.1.0.min.js"></script>
12+
@* DevExtreme themes *@
13+
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/18.1.3/css/dx.common.css" />
14+
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/18.1.3/css/dx.light.css" />
15+
@* DevExtreme library *@
16+
<script type="text/javascript" src="https://cdn3.devexpress.com/jslib/18.1.3/js/dx.all.js"></script>
17+
</head>
18+
<body class="dx-viewport">
19+
<h1>Issues Report</h1>
20+
21+
<div class="container">
22+
<div id="pivotgrid-chart"></div>
23+
<div id="pivotgrid"></div>
24+
<div id="pivotgrid-popup"></div>
25+
</div>
26+
27+
<script type="text/javascript">
28+
var issues = [];
29+
@foreach (var issue in Model)
30+
{
31+
@:issues.push({ProviderName: "@issue.ProviderName", ProviderType: "@issue.ProviderType", Priority: "@issue.Priority", PriorityName: "@issue.PriorityName", Project: "@issue.Project", Path: "@if (issue.AffectedFileRelativePath != null) { @issue.AffectedFileRelativePath.GetDirectory() }", File: "@if (issue.AffectedFileRelativePath != null) { @issue.AffectedFileRelativePath.GetFilename() }", Line: "@issue.Line", Rule: "@issue.Rule", RuleUrl: "@issue.RuleUrl", Message: "@issue.Message"});
32+
}
33+
</script>
34+
<script type="text/javascript">
35+
$(function(){
36+
var pivotGridChart = $("#pivotgrid-chart").dxChart({
37+
commonSeriesSettings: {
38+
type: "bar"
39+
},
40+
tooltip: {
41+
enabled: true,
42+
customizeTooltip: function(args) {
43+
return {
44+
html: "Total " + args.seriesName + ": " + args.valueText
45+
};
46+
}
47+
},
48+
size: {
49+
height: 200
50+
},
51+
adaptiveLayout: {
52+
width: 450
53+
}
54+
}).dxChart("instance");
55+
56+
var pivotGrid = $("#pivotgrid").dxPivotGrid({
57+
height: "calc(100% - 200px)",
58+
allowFiltering: true,
59+
fieldPanel: {
60+
showColumnFields: false,
61+
showDataFields: false,
62+
showFilterFields: true,
63+
showRowFields: false,
64+
allowFieldDragging: true,
65+
visible: true
66+
},
67+
onCellClick: function(e) {
68+
if (e.area == "data") {
69+
var pivotGridDataSource = e.component.getDataSource(),
70+
rowPathLength = e.cell.rowPath.length,
71+
rowPathName = e.cell.rowPath[rowPathLength - 1],
72+
popupTitle = (rowPathName ? rowPathName : "Total") + " issues";
73+
74+
drillDownDataSource = pivotGridDataSource.createDrillDownDataSource(e.cell);
75+
pivotgridPopup.option("title", popupTitle);
76+
pivotgridPopup.show();
77+
}
78+
},
79+
dataSource: {
80+
fields: [
81+
{
82+
caption: "Project",
83+
dataField: "Project",
84+
area: "row"
85+
},
86+
{
87+
caption: "Path",
88+
dataField: "Path",
89+
area: "row"
90+
},
91+
{
92+
caption: "File",
93+
dataField: "File",
94+
area: "row"
95+
},
96+
{
97+
caption: "PriorityName",
98+
dataField: "PriorityName",
99+
area: "column"
100+
},
101+
{
102+
caption: "Provider",
103+
dataField: "ProviderName",
104+
area: "filter"
105+
},
106+
{
107+
caption: "Count",
108+
dataField: "Rule",
109+
area: "data"
110+
}
111+
],
112+
store: issues
113+
}
114+
}).dxPivotGrid("instance");
115+
116+
pivotGrid.bindChart(
117+
pivotGridChart, {
118+
inverted: true,
119+
dataFieldsDisplayMode: "splitPanes",
120+
alternateDataFields: false
121+
});
122+
123+
var pivotgridPopup = $("#pivotgrid-popup").dxPopup({
124+
width: 600,
125+
height: 400,
126+
resizeEnabled: true,
127+
contentTemplate: function(contentElement) {
128+
$("<div />")
129+
.addClass("drill-down")
130+
.dxDataGrid({
131+
width: "100%",
132+
height: "100%",
133+
columns: ["Project", "Path", "File", "Line", "Rule", "Message"]
134+
})
135+
.appendTo(contentElement);
136+
},
137+
onShowing: function() {
138+
$(".drill-down")
139+
.dxDataGrid("instance")
140+
.option("dataSource", drillDownDataSource);
141+
}
142+
}).dxPopup("instance");
143+
});
144+
</script>
145+
</body>
146+
</html>

0 commit comments

Comments
 (0)