Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a total table footer on bottom of distribution area #31

Merged
merged 1 commit into from
Sep 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions src/main/java/io/jenkins/plugins/reporter/ItemViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import hudson.model.ModelObject;
import hudson.model.Run;
import hudson.util.RunList;
import io.jenkins.plugins.datatables.DefaultAsyncTableContentProvider;
import io.jenkins.plugins.datatables.TableModel;
import io.jenkins.plugins.reporter.charts.ItemSeriesBuilder;
import io.jenkins.plugins.reporter.charts.TrendChart;
import io.jenkins.plugins.reporter.model.Item;
Expand All @@ -28,7 +26,7 @@
*
* @author Simon Symhoven
*/
public class ItemViewModel extends DefaultAsyncTableContentProvider implements ModelObject {
public class ItemViewModel implements ModelObject {

private static final JacksonFacade JACKSON_FACADE = new JacksonFacade();

Expand Down Expand Up @@ -127,9 +125,8 @@ public String getBuildTrend(final String configuration) {
new ItemSeriesBuilder(item), colorProvider));
}

@Override
@SuppressWarnings("unused") // Called by jelly view
public TableModel getTableModel(String id) {
public ItemTableModel getTableModel(String id) {
return new ItemTableModel(item, colorProvider);
}

Expand Down
149 changes: 18 additions & 131 deletions src/main/java/io/jenkins/plugins/reporter/model/ItemTableModel.java
Original file line number Diff line number Diff line change
@@ -1,31 +1,21 @@
package io.jenkins.plugins.reporter.model;

import com.fasterxml.jackson.annotation.JsonAnyGetter;
import io.jenkins.plugins.datatables.DetailedCell;
import io.jenkins.plugins.datatables.TableColumn;
import io.jenkins.plugins.datatables.TableModel;
import io.jenkins.plugins.prism.Sanitizer;
import io.jenkins.plugins.reporter.ColorProvider;
import io.jenkins.plugins.reporter.ItemViewModel;
import j2html.tags.ContainerTag;
import org.apache.commons.text.CaseUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static j2html.TagCreator.div;
import static j2html.TagCreator.span;

/**
* Provides the model for the item table. The model displays the distribution for the subitems and the id column is
* linked to the {@link ItemViewModel} of the selected subitem.
*
* @author Simon Symhoven
*/
public class ItemTableModel extends TableModel {
public class ItemTableModel {

private final Item item;
private final ColorProvider colorProvider;
Expand All @@ -45,84 +35,40 @@ public ItemTableModel(Item item, ColorProvider colorProvider) {
this.colorProvider = colorProvider;
}

@Override
public String getId() {
return item.getId();
}

@Override
public Item getItem() {
return item;
}

public List<TableColumn> getColumns() {
List<TableColumn> columns = new ArrayList<>();

columns.add(createIdColumn());
columns.add(createNameColumn());

item.getResult().keySet().forEach(property -> {
columns.add(createResultAbsoluteColumn(property));
columns.add(createResultRelativeColumn(property));
});

columns.add(createDistributionColumn());

item.getResult().keySet().forEach(property -> columns.add(createResultAbsoluteColumn(property)));
return columns;
}

@Override
public List<Object> getRows() {

public List<ItemRow> getRows() {
return item.getItems()
.stream()
.map(item -> new ItemRow(item, colorProvider))
.collect(Collectors.toList());
}

protected TableColumn createIdColumn() {
return new TableColumn.ColumnBuilder()
.withDataPropertyKey("id")
.withHeaderLabel("ID")
.withHeaderClass(TableColumn.ColumnCss.HIDDEN)
.build();
}

protected TableColumn createNameColumn() {
return new TableColumn.ColumnBuilder()
.withDataPropertyKey("name")
.withHeaderLabel("Name")
.withHeaderClass(TableColumn.ColumnCss.NONE)
.build();
}

protected TableColumn createResultAbsoluteColumn(String property) {
return new TableColumn.ColumnBuilder()
.withDataPropertyKey(String.format("%s-absolute", property))
.withHeaderLabel(String.format("# %s", CaseUtils.toCamelCase(property, true)))
.withHeaderLabel(CaseUtils.toCamelCase(property, true))
.withHeaderClass(TableColumn.ColumnCss.NUMBER)
.build();
}

protected TableColumn createResultRelativeColumn(String property) {
return new TableColumn.ColumnBuilder()
.withDataPropertyKey(String.format("%s-relative", property))
.withHeaderLabel(String.format("%s (in %%)", CaseUtils.toCamelCase(property, true)))
.withHeaderClass(TableColumn.ColumnCss.PERCENTAGE)
.build();
}

protected TableColumn createDistributionColumn() {
return new TableColumn.ColumnBuilder()
.withDataPropertyKey("distribution")
.withHeaderLabel("Distribution")
.withHeaderClass(TableColumn.ColumnCss.NO_SORT)
.withDetailedCell()
.build();
}

/**
* A table row that shows the properties of an item.
*/
public static class ItemRow {

private static final Sanitizer SANITIZER = new Sanitizer();

private final Item item;
private final ColorProvider colorProvider;

Expand All @@ -140,82 +86,23 @@ public static class ItemRow {
}

public String getId() {
return render(item.getId());
return item.getId();
}

public String getName() {
return formatProperty(item.getId(), item.getName());
return item.getName();
}

public DetailedCell<String> getDistribution() {
return createColoredResultColumn(item);
}

/**
* Used to get a Getter for each property of the dynamic result of the item.
*
* @return the result.
*/
@JsonAnyGetter
public Map<String, Number> getResult() {
Map<String, Number> result = new HashMap<>();

item.getResult().forEach((String key, Integer value) -> {
result.put(String.format("%s-absolute", key), value);
result.put(String.format("%s-relative", key), (value / (double) item.getTotal()));
});

return result;
public Item getItem() {
return item;
}

protected DetailedCell<String> createColoredResultColumn(final Item item) {
List<ContainerTag> spans = new ArrayList<>();

for (Map.Entry<String, String> color : colorProvider.getColorMapping().entrySet()) {
String id = color.getKey();
String hex = color.getValue();

int val = item.getResult().get(id);
double percentage = (val / (double) item.getTotal()) * 100;

spans.add(span()
.withTitle(String.format("%s: %.2f%%", id, percentage))
.withClass("distribution")
.withStyle(String.format("width: %.2f%%; background-color: %s", percentage, hex))
.withText(item.getId())
.attr("data-bs-toggle", "tooltip")
.attr("data-bs-placement", "left"));
}

return new DetailedCell<>(div().with(spans).render(), null);
public ColorProvider getColorProvider() {
return colorProvider;
}


/**
* Formats the text of the specified property column. The text actually is a link to the UI representation of
* the property.
*
* @param link
* the property to use as link
* @param value
* the value of the property to be shown
*
* @return the formatted column
*/
protected String formatProperty(final String link, final String value) {
return String.format("<a href=\"%d/\">%s</a>", link.hashCode(), render(value));
}

/**
* Renders the specified HTML code. Removes unsafe HTML constructs.
*
* @param html
* the HTML to render
*
* @return safe HTML
*/
protected final String render(final String html) {
return SANITIZER.render(html);

public String tooltip(String id, double percentage) {
return String.format("%s: %.2f%%", id, percentage);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:c="/charts" xmlns:dt="/data-tables"
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:c="/charts"
xmlns:bs="/bootstrap5" xmlns:fa="/font-awesome">

<st:header name="Content-Type" value="text/html;charset=UTF-8"/>

<bs:page it="${it}">

<link rel="stylesheet" href="${resURL}/plugin/nested-data-reporting/css/custom-style.css"/>


<st:adjunct includes="io.jenkins.plugins.jquery3"/>
<st:adjunct includes="io.jenkins.plugins.data-tables"/>

<div class="row py-3 flex-nowrap">

<div class="col-5">
Expand Down Expand Up @@ -39,9 +42,77 @@
<div class="col-12">

<bs:card class="h-100" bodyClass="pd-20" title="${%Distribution}" fontAwesomeIcon="bars-progress">

<dt:table model="${it.getTableModel(it.item.id)}"/>

<j:set var="t" value="${it.getTableModel(it.item.id)}"/>
<j:set var="rows" value="${t.rows}"/>
<j:set var="columns" value="${t.columns}"/>

<div class="table-responsive">
<table class="table table-hover table-striped display item-table" id="${t.id}" isLoaded="true">
<colgroup>
<col class="col-width-5"/>

<j:forEach var="column" items="${columns}">
<col class="col-width-1 text-end" />
</j:forEach>

<col class="col-width-5"/>
</colgroup>
<thead>
<tr>
<th>${%Name}</th>

<j:forEach var="column" items="${columns}">
<th class="text-end">${column.headerLabel}</th>
</j:forEach>

<th class="no-sort">${%Distribution}</th>
</tr>
</thead>
<tbody>
<j:forEach var="row" items="${rows}">
<tr>
<td>
<a href="${row.id.hashCode()}/"
data-bs-toggle="tooltip" data-bs-placement="left" title="${row.name}">
${row.name}</a>
</td>

<j:forEach var="i" items="${row.item.result}">
<td class="text-end">${i.value}</td>
</j:forEach>

<td>
<div>
<j:forEach var="color" items="${row.colorProvider.colorMapping}">
<j:set var="id" value="${color.key}"/>
<j:set var="hex" value="${color.value}"/>
<j:set var="val" value="${row.item.result.get(id)}"/>
<j:set var="percentage" value="${val / row.item.total * 100}"/>

<span class="distribution" style="width: ${percentage}%; background-color: ${hex}"
data-bs-toggle="tooltip" data-bs-placement="left"
title="${row.tooltip(id, percentage)}">.</span>

</j:forEach>
</div>
</td>
</tr>
</j:forEach>
<tfoot>
<tr>
<td>${%Total}</td>
<j:forEach var="i" items="${t.item.result}">
<td class="text-end">${i.value}</td>
</j:forEach>

<td/>
</tr>
</tfoot>
</tbody>
</table>
</div>

</bs:card>

</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
history=Historie
distribution=Verteilung
overview=�bersicht
previous=Zur�ck
previous=Zur�ck
total=Summe
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
history=History
distribution=Distribution
overview=Overview
previous=Previous
previous=Previous
total=Total
4 changes: 4 additions & 0 deletions src/main/webapp/css/custom-style.css
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,8 @@

.distribution:hover {
filter: brightness(110%);
}

tfoot {
font-weight: bold;
}
Loading