mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 18:17:43 +00:00
bar chart included
This commit is contained in:
parent
189580df63
commit
27f90e7e1f
@ -114,6 +114,12 @@ SizeRepresentationUtil_units_megabytes=MB
|
||||
SizeRepresentationUtil_units_petabytes=PB
|
||||
SizeRepresentationUtil_units_terabytes=TB
|
||||
TimelinePanel_earliestLabel_title=Earliest
|
||||
TimelinePanel_getExports_activityRange=Activity Range
|
||||
TimelinePanel_getExports_chartName=Last 30 Days
|
||||
TimelinePanel_getExports_dateColumnHeader=Date
|
||||
TimelinePanel_getExports_earliest=Earliest:
|
||||
TimelinePanel_getExports_latest=Latest:
|
||||
TimelinePanel_getExports_sheetName=Timeline
|
||||
TimelinePanel_latestLabel_title=Latest
|
||||
TimlinePanel_last30DaysChart_artifactEvts_title=Result Events
|
||||
TimlinePanel_last30DaysChart_fileEvts_title=File Events
|
||||
|
@ -39,6 +39,7 @@ import org.sleuthkit.autopsy.datasourcesummary.datamodel.TimelineDataSourceUtils
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.TimelineSummary;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.TimelineSummary.DailyActivityAmount;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.datamodel.TimelineSummary.TimelineSummaryData;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.BarChartExport;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.BarChartPanel;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.BarChartSeries;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.BarChartPanel.OrderedKey;
|
||||
@ -46,7 +47,12 @@ import org.sleuthkit.autopsy.datasourcesummary.uiutils.BarChartSeries.BarChartIt
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetcher;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultCellModel;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelExport;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.KeyValueItemExportable;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.TitledExportable;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.IngestRunningLabel;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.LoadableComponent;
|
||||
import org.sleuthkit.autopsy.datasourcesummary.uiutils.LoadableLabel;
|
||||
@ -70,7 +76,9 @@ public class TimelinePanel extends BaseDataSourceSummaryPanel {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(TimelinePanel.class.getName());
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final DateFormat EARLIEST_LATEST_FORMAT = getUtcFormat("MMM d, yyyy");
|
||||
|
||||
private static final String EARLIEST_LATEST_FORMAT_STR = "MMM d, yyyy";
|
||||
private static final DateFormat EARLIEST_LATEST_FORMAT = getUtcFormat(EARLIEST_LATEST_FORMAT_STR);
|
||||
private static final DateFormat CHART_FORMAT = getUtcFormat("MMM d, yyyy");
|
||||
private static final int MOST_RECENT_DAYS_COUNT = 30;
|
||||
|
||||
@ -94,6 +102,8 @@ public class TimelinePanel extends BaseDataSourceSummaryPanel {
|
||||
// all loadable components on this tab
|
||||
private final List<LoadableComponent<?>> loadableComponents = Arrays.asList(earliestLabel, latestLabel, last30DaysChart);
|
||||
|
||||
private final DataFetcher<DataSource, TimelineSummaryData> dataFetcher;
|
||||
|
||||
// actions to load data for this tab
|
||||
private final List<DataFetchComponents<DataSource, ?>> dataFetchComponents;
|
||||
|
||||
@ -107,12 +117,11 @@ public class TimelinePanel extends BaseDataSourceSummaryPanel {
|
||||
public TimelinePanel(TimelineSummary timelineData) {
|
||||
super(timelineData);
|
||||
|
||||
dataFetcher = (dataSource) -> timelineData.getData(dataSource, MOST_RECENT_DAYS_COUNT);
|
||||
|
||||
// set up data acquisition methods
|
||||
dataFetchComponents = Arrays.asList(
|
||||
new DataFetchWorker.DataFetchComponents<>(
|
||||
(dataSource) -> timelineData.getData(dataSource, MOST_RECENT_DAYS_COUNT),
|
||||
(result) -> handleResult(result))
|
||||
);
|
||||
new DataFetchWorker.DataFetchComponents<>(dataFetcher, (result) -> handleResult(result)));
|
||||
|
||||
initComponents();
|
||||
}
|
||||
@ -282,11 +291,36 @@ public class TimelinePanel extends BaseDataSourceSummaryPanel {
|
||||
super.close();
|
||||
}
|
||||
|
||||
private static DefaultCellModel<?> getEarliestLatestCell(Date date) {
|
||||
return new DefaultCellModel<>(date, (dt) -> dt == null ? "" : EARLIEST_LATEST_FORMAT.format(dt), EARLIEST_LATEST_FORMAT_STR);
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"TimelinePanel_getExports_sheetName=Timeline",
|
||||
"TimelinePanel_getExports_activityRange=Activity Range",
|
||||
"TimelinePanel_getExports_earliest=Earliest:",
|
||||
"TimelinePanel_getExports_latest=Latest:",
|
||||
"TimelinePanel_getExports_dateColumnHeader=Date",
|
||||
"TimelinePanel_getExports_chartName=Last 30 Days",})
|
||||
@Override
|
||||
List<ExcelExport.ExcelSheetExport> getExports(DataSource dataSource) {
|
||||
TimelineSummaryData summaryData = getFetchResult(dataFetcher, "Timeline", dataSource);
|
||||
if (summaryData == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return Arrays.asList(
|
||||
new ExcelSpecialFormatExport(Bundle.TimelinePanel_getExports_sheetName(),
|
||||
Arrays.asList(
|
||||
new TitledExportable(Bundle.TimelinePanel_getExports_activityRange(), Collections.emptyList()),
|
||||
new KeyValueItemExportable(Bundle.TimelinePanel_getExports_earliest(), getEarliestLatestCell(summaryData.getMinDate())),
|
||||
new KeyValueItemExportable(Bundle.TimelinePanel_getExports_latest(), getEarliestLatestCell(summaryData.getMaxDate())),
|
||||
new BarChartExport(Bundle.TimelinePanel_getExports_dateColumnHeader(),
|
||||
"#,###",
|
||||
Bundle.TimelinePanel_getExports_chartName(),
|
||||
parseChartData(summaryData.getMostRecentDaysActivity())))));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
|
@ -5,13 +5,13 @@
|
||||
*/
|
||||
package org.sleuthkit.autopsy.datasourcesummary.uiutils;
|
||||
|
||||
import com.google.cloud.Tuple;
|
||||
import java.awt.Color;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
@ -31,8 +31,6 @@ import org.apache.poi.xddf.usermodel.chart.XDDFChartData;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFChartLegend;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFDataSource;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFDataSourcesFactory;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFNumericalDataSource;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFPieChartData;
|
||||
import org.apache.poi.xddf.usermodel.chart.XDDFValueAxis;
|
||||
import org.apache.poi.xssf.usermodel.XSSFChart;
|
||||
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
|
||||
@ -48,7 +46,8 @@ import org.sleuthkit.autopsy.datasourcesummary.uiutils.ExcelSpecialFormatExport.
|
||||
* @author gregd
|
||||
*/
|
||||
public class BarChartExport implements ExcelItemExportable, ExcelSheetExport {
|
||||
private final ExcelTableExport<BarChartSeries, ? extends ExcelCellModel> tableExport;
|
||||
|
||||
private final ExcelTableExport<Pair<Object, List<Double>>, ? extends ExcelCellModel> tableExport;
|
||||
private final int colOffset;
|
||||
private final int rowPadding;
|
||||
private final int colSize;
|
||||
@ -72,33 +71,53 @@ public class BarChartExport implements ExcelItemExportable, ExcelSheetExport {
|
||||
|
||||
this.keyColumnHeader = keyColumnHeader;
|
||||
|
||||
List<BarChartSeries> categoryKeys = categories.stream()
|
||||
.filter(cat -> cat != null && cat.getKey() != null)
|
||||
.sorted((c1, c2) -> c1.getKey().compareTo(c2.getKey()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<Comparable<?>> rowKeys = categories.stream()
|
||||
List<? extends Object> rowKeys = categories.stream()
|
||||
.filter(cat -> cat != null && cat.getItems() != null)
|
||||
.flatMap(cat -> cat.getItems().stream().map(item -> item.getKey()))
|
||||
.filter(i -> i != null)
|
||||
.distinct()
|
||||
.sorted()
|
||||
.map(cat -> cat.getItems())
|
||||
.max((items1, items2) -> Integer.compare(items1.size(), items2.size()))
|
||||
.orElse(Collections.emptyList())
|
||||
.stream()
|
||||
.map((barChartItem) -> barChartItem.getKey())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Map<Tuple<Comparable<?>, Comparable<?>>, Double> valueMap = categories.stream()
|
||||
.flatMap((cat) -> cat.getItems().stream().map((item) -> Tuple.of(Tuple.of(cat.getKey(), item.getKey()), item.getValue())))
|
||||
// map of (category, item) -> value
|
||||
Map<Pair<Integer, Integer>, Double> valueMap = IntStream.range(0, categories.size())
|
||||
.mapToObj(idx -> Pair.of(idx, categories.get(idx)))
|
||||
.filter(pair -> pair.getValue() != null && pair.getValue().getItems() != null)
|
||||
.flatMap(categoryPair -> {
|
||||
return IntStream.range(0, categoryPair.getValue().getItems().size())
|
||||
.mapToObj(idx -> Pair.of(idx, categoryPair.getValue().getItems().get(idx)))
|
||||
.map(itemPair -> Pair.of(
|
||||
Pair.of(categoryPair.getKey(), itemPair.getKey()),
|
||||
itemPair.getValue() == null ? null : itemPair.getValue().getValue()));
|
||||
})
|
||||
.collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue(), (v1, v2) -> v1));
|
||||
|
||||
List<Pair<Comparable<?>, List<Double>>> values = rowKeys.stream()
|
||||
.map((rowValue))
|
||||
List<Pair<Object, List<Double>>> values = IntStream.range(0, rowKeys.size())
|
||||
.mapToObj(idx -> Pair.of(idx, rowKeys.get(idx)))
|
||||
.map((rowPair) -> {
|
||||
List<Double> items = IntStream.range(0, categories.size())
|
||||
.mapToObj(idx -> valueMap.get(Pair.of(idx, rowPair.getKey())))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return Pair.of(rowPair.getValue(), items);
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
ColumnModel<Pair<Object, List<Double>>, DefaultCellModel> categoryColumn = new ColumnModel<>(keyColumnHeader, (row) -> new DefaultCellModel<>(row.getKey()));
|
||||
|
||||
Stream<ColumnModel<Pair<Object, List<Double>>, DefaultCellModel>> dataColumns = IntStream.range(0, categories.size())
|
||||
.mapToObj(idx -> new ColumnModel<>(
|
||||
categories.get(idx).getKey().toString(),
|
||||
(row) -> new DefaultCellModel<>(row.getValue().get(idx))));
|
||||
|
||||
this.tableExport = new ExcelTableExport<Pair<Object, List<Double>>, DefaultCellModel>(
|
||||
chartTitle,
|
||||
Stream.concat(Stream.of(categoryColumn), dataColumns)
|
||||
.collect(Collectors.toList()),
|
||||
values
|
||||
);
|
||||
|
||||
this.tableExport = new ExcelTableExport<>(chartTitle,
|
||||
Stream.concat(Stream.of(new ColumnModel<>(keyColumnHeader, (category) -> new DefaultCellModel<>(category.getLabel()))), )
|
||||
Arrays.asList(
|
||||
,
|
||||
new ColumnModel<>(valueColumnHeader, (category) -> new DefaultCellModel<>(category.getValue(), null, valueFormatString))
|
||||
),
|
||||
categories);
|
||||
this.colOffset = colOffset;
|
||||
this.rowPadding = rowPadding;
|
||||
this.colSize = colSize;
|
||||
@ -108,8 +127,6 @@ public class BarChartExport implements ExcelItemExportable, ExcelSheetExport {
|
||||
this.categories = categories;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getSheetName() {
|
||||
return sheetName;
|
||||
@ -133,7 +150,7 @@ public class BarChartExport implements ExcelItemExportable, ExcelSheetExport {
|
||||
|
||||
XSSFDrawing drawing = xssfSheet.createDrawingPatriarch();
|
||||
|
||||
int chartColStart = colStart + 2 + colOffset;
|
||||
int chartColStart = colStart + categories.size() + 1 + colOffset;
|
||||
|
||||
//createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2);
|
||||
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, chartColStart, rowStart + rowPadding, chartColStart + colSize, rowStart + rowSize);
|
||||
@ -144,7 +161,6 @@ public class BarChartExport implements ExcelItemExportable, ExcelSheetExport {
|
||||
XDDFChartLegend legend = chart.getOrAddLegend();
|
||||
legend.setPosition(LegendPosition.BOTTOM);
|
||||
|
||||
|
||||
// Use a category axis for the bottom axis.
|
||||
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
|
||||
bottomAxis.setTitle(keyColumnHeader);
|
||||
@ -156,13 +172,19 @@ public class BarChartExport implements ExcelItemExportable, ExcelSheetExport {
|
||||
XDDFBarChartData data = (XDDFBarChartData) chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
|
||||
data.setBarGrouping(BarGrouping.STACKED);
|
||||
|
||||
XDDFDataSource<String> headerSource = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(1, keyVals.size(), 0, 0));
|
||||
XDDFDataSource<String> headerSource = XDDFDataSourcesFactory.fromStringCellRange(xssfSheet,
|
||||
new CellRangeAddress(tableDimensions.getRowStart() + 1, tableDimensions.getRowEnd(),
|
||||
tableDimensions.getColStart(), tableDimensions.getColStart()));
|
||||
|
||||
data.setBarDirection(BarDirection.COL);
|
||||
|
||||
for (int i = 0; i < categories.size(); i++) {
|
||||
XDDFChartData.Series series = data.addSeries(headerSource,
|
||||
XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, keyVals.size(), i + 1, i + 1)));
|
||||
series.setTitle(categories.size() > i && categories.get(i).getIdentifier() != null ? categories.get(i).getIdentifier() : "", null);
|
||||
XDDFDataSourcesFactory.fromNumericCellRange(xssfSheet,
|
||||
new CellRangeAddress(tableDimensions.getRowStart() + 1, tableDimensions.getRowEnd(),
|
||||
tableDimensions.getColStart() + 1 + i, tableDimensions.getColStart() + 1 + i)));
|
||||
|
||||
series.setTitle(categories.size() > i && categories.get(i).getKey() != null ? categories.get(i).getKey().toString() : "", null);
|
||||
if (categories.get(i).getColor() != null) {
|
||||
Color color = categories.get(i).getColor();
|
||||
byte[] colorArrARGB = ByteBuffer.allocate(4).putInt(color.getRGB()).array();
|
||||
@ -182,6 +204,4 @@ public class BarChartExport implements ExcelItemExportable, ExcelSheetExport {
|
||||
return new ItemDimensions(rowStart, colStart, Math.max(tableDimensions.getRowEnd(), rowStart + rowSize) + rowPadding, chartColStart + colSize);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user