Skip to content

Commit

Permalink
Implemented Tree Diff View, and refactored UI to fit it in
Browse files Browse the repository at this point in the history
The new Diff Root / Flat & Tree Diff View structure is analogous to the
Profile Root / Flat & Tree View structure. Will refactor to take
advantage of that and make things a lot simpler/clearer.
  • Loading branch information
arickp authored and arickp committed Jan 4, 2017
1 parent 331e5d5 commit 09a824b
Show file tree
Hide file tree
Showing 21 changed files with 1,370 additions and 122 deletions.
Expand Up @@ -62,7 +62,6 @@
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures; import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView; import javafx.scene.control.TableView;
Expand All @@ -73,7 +72,7 @@
import javafx.scene.text.Text; import javafx.scene.text.Text;
import javafx.util.Callback; import javafx.util.Callback;


public class FlatDiffViewController extends AbstractController public class FlatDiffViewController extends ProfileDiffViewController<Profile>
{ {
@FXML @FXML
private Button filterButton; private Button filterButton;
Expand All @@ -84,10 +83,6 @@ public class FlatDiffViewController extends AbstractController
@FXML @FXML
private Button quickFilterButton; private Button quickFilterButton;
@FXML @FXML
private Label baseSourceLabel;
@FXML
private Label newSourceLabel;
@FXML
private TableView<FlatEntryDiff> diffTable; private TableView<FlatEntryDiff> diffTable;
@FXML @FXML
private TableColumn<FlatEntryDiff, String> method; private TableColumn<FlatEntryDiff, String> method;
Expand Down Expand Up @@ -122,9 +117,6 @@ public class FlatDiffViewController extends AbstractController
@FXML @FXML
private TableColumn<FlatEntryDiff, Number> traceCountDiff; private TableColumn<FlatEntryDiff, Number> traceCountDiff;


private ProfileContext baseProfileContext;
private ProfileContext newProfileContext;

private FilterDialogController filterDialogController; private FilterDialogController filterDialogController;
private ObjectProperty<FilterSpecification> filterSpec; private ObjectProperty<FilterSpecification> filterSpec;


Expand All @@ -136,6 +128,8 @@ public class FlatDiffViewController extends AbstractController
@FXML @FXML
private void initialize() private void initialize()
{ {
super.initialize(profileContext -> profileContext.profileProperty());

info(filterButton, "Specify filters restricting the visible entries"); info(filterButton, "Specify filters restricting the visible entries");
info(exportButton, "Export the visible entries to a CSV file"); info(exportButton, "Export the visible entries to a CSV file");
info( info(
Expand Down Expand Up @@ -191,66 +185,53 @@ public void setApplicationContext(ApplicationContext applicationContext)
filterDialogController.setApplicationContext(appCtx()); filterDialogController.setApplicationContext(appCtx());
} }


@Override
public void setProfileContexts(ProfileContext baseContext, ProfileContext newContext) public void setProfileContexts(ProfileContext baseContext, ProfileContext newContext)
{ {
baseProfileContext = baseContext; super.setProfileContexts(baseContext, newContext);
newProfileContext = newContext;

baseSourceLabel.setText(baseContext.getName());
newSourceLabel.setText(newContext.getName());


configurePercentColumn(baseSelfTime, "baseSelfTimeShare", baseProfileContext, "Self %"); configurePercentColumn(baseSelfTime, "baseSelfTimeShare", baseContext(), "Self %");
configurePercentColumn(newSelfTime, "newSelfTimeShare", newProfileContext, "Self %"); configurePercentColumn(newSelfTime, "newSelfTimeShare", newContext(), "Self %");
configurePercentColumn(selfTimeDiff, "pctSelfChange", doubleDiffStyler, "Self % Diff"); configurePercentColumn(selfTimeDiff, "pctSelfChange", doubleDiffStyler, "Self % Diff");


configurePercentColumn(baseTotalTime, "baseTotalTimeShare", baseProfileContext, "Total %"); configurePercentColumn(baseTotalTime, "baseTotalTimeShare", baseContext(), "Total %");
configurePercentColumn(newTotalTime, "newTotalTimeShare", newProfileContext, "Total %"); configurePercentColumn(newTotalTime, "newTotalTimeShare", newContext(), "Total %");
configurePercentColumn(totalTimeDiff, "pctTotalChange", doubleDiffStyler, "Total % Diff"); configurePercentColumn(totalTimeDiff, "pctTotalChange", doubleDiffStyler, "Total % Diff");


configureCountColumn(baseSelfCount, "baseSelfCount", baseProfileContext, "Self #"); configureCountColumn(baseSelfCount, "baseSelfCount", baseContext(), "Self #");
configureCountColumn(newSelfCount, "newSelfCount", newProfileContext, "Self #"); configureCountColumn(newSelfCount, "newSelfCount", newContext(), "Self #");
configureCountDiffColumn( configureCountDiffColumn(
selfCountDiff, selfCountDiff,
data -> new ReadOnlyIntegerWrapper( data -> new ReadOnlyIntegerWrapper(
data.getValue().getNewSelfCount() - data.getValue().getBaseSelfCount()), data.getValue().getNewSelfCount() - data.getValue().getBaseSelfCount()),
intDiffStyler, intDiffStyler,
"Self # Diff"); "Self # Diff");


configureCountColumn(baseTotalCount, "baseTotalCount", baseProfileContext, "Total #"); configureCountColumn(baseTotalCount, "baseTotalCount", baseContext(), "Total #");
configureCountColumn(newTotalCount, "newTotalCount", newProfileContext, "Total #"); configureCountColumn(newTotalCount, "newTotalCount", newContext(), "Total #");
configureCountDiffColumn( configureCountDiffColumn(
totalCountDiff, totalCountDiff,
data -> new ReadOnlyIntegerWrapper( data -> new ReadOnlyIntegerWrapper(
data.getValue().getNewTotalCount() - data.getValue().getBaseTotalCount()), data.getValue().getNewTotalCount() - data.getValue().getBaseTotalCount()),
intDiffStyler, intDiffStyler,
"Total # Diff"); "Total # Diff");


configureCountColumn(baseTraceCount, "baseTraceCount", baseProfileContext, "Trace #"); configureCountColumn(baseTraceCount, "baseTraceCount", baseContext(), "Trace #");
configureCountColumn(newTraceCount, "newTraceCount", baseProfileContext, "Trace #"); configureCountColumn(newTraceCount, "newTraceCount", newContext(), "Trace #");
configureCountDiffColumn( configureCountDiffColumn(
traceCountDiff, traceCountDiff,
data -> new ReadOnlyIntegerWrapper( data -> new ReadOnlyIntegerWrapper(
data.getValue().getNewTraceCount() - data.getValue().getBaseTraceCount()), data.getValue().getNewTraceCount() - data.getValue().getBaseTraceCount()),
intDiffStyler, intDiffStyler,
"Trace # Diff"); "Trace # Diff");

updateDiff(baseContext.getProfile(), true);
updateDiff(newContext.getProfile(), false);

// diffTable.refresh();

baseProfileContext.profileProperty()
.addListener((property, oldValue, newValue) -> refresh());

newProfileContext.profileProperty()
.addListener((property, oldValue, newValue) -> refresh());
} }


private void refresh() @Override
protected void refresh()
{ {
diff.clear(); diff.clear();
updateDiff(baseProfileContext.getProfile(), true); updateDiff(getBaseTarget(), true);
updateDiff(newProfileContext.getProfile(), false); updateDiff(getNewTarget(), false);
} }


private void updateDiff(Profile profile, boolean base) private void updateDiff(Profile profile, boolean base)
Expand Down
Expand Up @@ -25,7 +25,6 @@
import static com.insightfullogic.honest_profiler.ports.javafx.util.DialogUtil.showExportDialog; import static com.insightfullogic.honest_profiler.ports.javafx.util.DialogUtil.showExportDialog;
import static com.insightfullogic.honest_profiler.ports.javafx.util.FxUtil.refreshTable; import static com.insightfullogic.honest_profiler.ports.javafx.util.FxUtil.refreshTable;
import static com.insightfullogic.honest_profiler.ports.javafx.util.report.ReportUtil.writeFlatProfileCsv; import static com.insightfullogic.honest_profiler.ports.javafx.util.report.ReportUtil.writeFlatProfileCsv;
import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.COMPARE_16;
import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.EXPORT_16; import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.EXPORT_16;
import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.FUNNEL_16; import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.FUNNEL_16;
import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.FUNNEL_ACTIVE_16; import static com.insightfullogic.honest_profiler.ports.javafx.view.Icon.FUNNEL_ACTIVE_16;
Expand Down Expand Up @@ -54,25 +53,19 @@
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.scene.control.Button; import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableColumn; import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView; import javafx.scene.control.TableView;
import javafx.scene.control.TextField; import javafx.scene.control.TextField;
import javafx.scene.control.Tooltip; import javafx.scene.control.Tooltip;
import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseEvent;


public class FlatViewController extends ProfileViewController<Profile> public class FlatViewController extends ProfileViewController<Profile>
{ {
@FXML @FXML
private Button filterButton; private Button filterButton;
@FXML @FXML
private Button compareButton;
@FXML
private Button exportButton; private Button exportButton;
@FXML @FXML
private TextField quickFilterText; private TextField quickFilterText;
Expand Down Expand Up @@ -109,7 +102,6 @@ protected void initialize()
super.initialize(profileContext -> profileContext.profileProperty()); super.initialize(profileContext -> profileContext.profileProperty());


info(filterButton, "Specify filters restricting the visible entries"); info(filterButton, "Specify filters restricting the visible entries");
info(compareButton, "Click to select another open profile to compare this profile against");
info(exportButton, "Export the visible entries to a CSV file"); info(exportButton, "Export the visible entries to a CSV file");
info( info(
quickFilterText, quickFilterText,
Expand All @@ -128,7 +120,6 @@ protected void initialize()
out -> writeFlatProfileCsv(out, flatProfile, ReportUtil.Mode.CSV) out -> writeFlatProfileCsv(out, flatProfile, ReportUtil.Mode.CSV)
)); ));


initializeComparison();
initializeFilter(); initializeFilter();
initializeTable(); initializeTable();
} }
Expand All @@ -154,30 +145,6 @@ public void setApplicationContext(ApplicationContext applicationContext)


// Initialization Helper Methods // Initialization Helper Methods


private void initializeComparison()
{
compareButton.setGraphic(viewFor(COMPARE_16));
compareButton.setTooltip(new Tooltip("Compare this profile with another open profile"));
compareButton.setOnMousePressed(new EventHandler<MouseEvent>()
{
@Override
public void handle(MouseEvent event)
{
ContextMenu ctxMenu = compareButton.getContextMenu();
if (ctxMenu == null)
{
ctxMenu = new ContextMenu();
compareButton.setContextMenu(ctxMenu);
}
refreshContextMenu(compareButton.getContextMenu());
compareButton.getContextMenu().show(
compareButton,
event.getScreenX(),
event.getScreenY());
}
});
}

private void initializeFilter() private void initializeFilter()
{ {
filterDialogController = (FilterDialogController) DialogUtil filterDialogController = (FilterDialogController) DialogUtil
Expand Down Expand Up @@ -273,26 +240,4 @@ private ProfileFilter getAdjustedProfileFilter()
return new ProfileFilter(filters); return new ProfileFilter(filters);
} }
} }

// Compare Helper Methods

private void refreshContextMenu(ContextMenu menu)
{
menu.getItems().clear();

List<String> profileNames = appCtx().getOpenProfileNames();

profileNames.forEach(name ->
{
if (name.equals(prContext().getName()))
{
return;
}

MenuItem item = new MenuItem(name);
item.setOnAction(
event -> appCtx().createDiffView(prContext().getName(), name));
menu.getItems().add(item);
});
}
} }
@@ -0,0 +1,106 @@
/**
* Copyright (c) 2014 Richard Warburton (richard.warburton@gmail.com)
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* <p>
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
**/
package com.insightfullogic.honest_profiler.ports.javafx.controller;

import static com.insightfullogic.honest_profiler.ports.javafx.ViewType.FLAT;
import static com.insightfullogic.honest_profiler.ports.javafx.ViewType.TREE;
import static com.insightfullogic.honest_profiler.ports.javafx.util.ConversionUtil.getStringConverterForType;

import com.insightfullogic.honest_profiler.ports.javafx.ViewType;
import com.insightfullogic.honest_profiler.ports.javafx.model.ApplicationContext;
import com.insightfullogic.honest_profiler.ports.javafx.model.ProfileContext;

import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;

public class ProfileDiffRootController extends AbstractController
{
@FXML
private ChoiceBox<ViewType> viewChoice;
@FXML
private Label baseSourceLabel;
@FXML
private Label newSourceLabel;
@FXML
private AnchorPane content;
@FXML
private FlatDiffViewController flatController;
@FXML
private TreeDiffViewController treeController;

protected void initialize()
{
info(
viewChoice,
"Select the View : Flat View lists all methods as a list; Tree View shows the stack trees per thread; Flame View shows the Flame Graph");
}

// Instance Accessors

@Override
public void setApplicationContext(ApplicationContext applicationContext)
{
super.setApplicationContext(applicationContext);
flatController.setApplicationContext(applicationContext);
treeController.setApplicationContext(applicationContext);
}

public void setProfileContexts(ProfileContext baseContext, ProfileContext newContext)
{
baseSourceLabel.setText(baseContext.getName());
newSourceLabel.setText(newContext.getName());

flatController.setProfileContexts(baseContext, newContext);
treeController.setProfileContexts(baseContext, newContext);

viewChoice.setConverter(getStringConverterForType(ViewType.class));
viewChoice.getItems().addAll(FLAT, TREE);
viewChoice.getSelectionModel().selectedItemProperty()
.addListener((property, oldValue, newValue) -> show(newValue));
viewChoice.getSelectionModel().select(FLAT);
}

// View Switch

private void show(ViewType viewType)
{
for (int i = 0; i < viewChoice.getItems().size(); i++)
{
Node child = content.getChildren().get(i);
child.setManaged(viewType.ordinal() == i);
child.setVisible(viewType.ordinal() == i);
}

switch (viewType)
{
case FLAT:
treeController.deactivate();
flatController.activate();
break;
case TREE:
flatController.deactivate();
treeController.activate();
break;
default:
}
}
}

0 comments on commit 09a824b

Please sign in to comment.