Commit 4cbd3ae2 authored by James Long's avatar James Long Committed by Commit Bot

[Lorenz] Update UI to use Material design

This change brings in the vue-material package and updates the UI to use
its Material design components. All the graph controls are now in a
sidebar, and the graph canvas is responsive to fit the size of the page.

Bug: 1102546
Change-Id: If47d8319337a9700bd921ba3938d3fe3da7b67b9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2347407Reviewed-by: default avatarMohamed Heikal <mheikal@chromium.org>
Reviewed-by: default avatarSamuel Huang <huangs@chromium.org>
Commit-Queue: James Long <yjlong@google.com>
Cr-Commit-Position: refs/heads/master@{#796945}
parent 3ab681ee
...@@ -11,7 +11,8 @@ ...@@ -11,7 +11,8 @@
"dependencies": { "dependencies": {
"@trevoreyre/autocomplete-vue": "^2.2.0", "@trevoreyre/autocomplete-vue": "^2.2.0",
"d3": "^5.16.0", "d3": "^5.16.0",
"vue": "^2.6.11" "vue": "^2.6.11",
"vue-material": "^1.0.0-beta-14"
}, },
"devDependencies": { "devDependencies": {
"copy-webpack-plugin": "^6.0.3", "copy-webpack-plugin": "^6.0.3",
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
<head> <head>
<link rel="icon" type="image/png" <link rel="icon" type="image/png"
href="https://fonts.gstatic.com/s/i/googlematerialicons/account_tree/v6/gm_blue-48dp/1x/gm_account_tree_gm_blue_48dp.png"> href="https://fonts.gstatic.com/s/i/googlematerialicons/account_tree/v6/gm_blue-48dp/1x/gm_account_tree_gm_blue_48dp.png">
<link rel="stylesheet"
href="//fonts.googleapis.com/css?family=Roboto:400,500,700,400italic|Material+Icons">
</head> </head>
<body> <body>
<div id="class-graph-page"></div> <div id="class-graph-page"></div>
......
...@@ -2,13 +2,39 @@ ...@@ -2,13 +2,39 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import Vue from 'vue';
import ClassGraphPage from './vue_components/class_graph_page.vue'; import ClassGraphPage from './vue_components/class_graph_page.vue';
import {loadGraph} from './load_graph.js'; import {loadGraph} from './load_graph.js';
import * as d3 from 'd3';
import Vue from 'vue';
import {
MdButton,
MdCheckbox,
MdDivider,
MdField,
MdIcon,
MdList,
// MdMenu is a dependency of MdField's MdSelect, see
// https://github.com/vuematerial/vue-material/issues/1974
MdMenu,
MdRadio,
MdSubheader,
} from 'vue-material/dist/components';
import 'vue-material/dist/vue-material.min.css';
import 'vue-material/dist/theme/default.css';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
loadGraph().then(data => { loadGraph().then(data => {
Vue.use(MdButton);
Vue.use(MdCheckbox);
Vue.use(MdDivider);
Vue.use(MdField);
Vue.use(MdIcon);
Vue.use(MdList);
Vue.use(MdMenu);
Vue.use(MdRadio);
Vue.use(MdSubheader);
new Vue({ new Vue({
el: '#class-graph-page', el: '#class-graph-page',
render: createElement => createElement( render: createElement => createElement(
...@@ -21,6 +47,6 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -21,6 +47,6 @@ document.addEventListener('DOMContentLoaded', () => {
), ),
}); });
}).catch(e => { }).catch(e => {
document.write("Error loading graph."); document.write('Error loading graph.');
}); });
}); });
...@@ -350,9 +350,10 @@ class GraphView { ...@@ -350,9 +350,10 @@ class GraphView {
.classed('graph-labels', true) .classed('graph-labels', true)
.attr('pointer-events', 'none'); .attr('pointer-events', 'none');
// TODO(yjlong): SVG should be resizable & these values updated. // Using .style() instead of .attr() gets px-based measurements of
const width = +svg.attr('width'); // percentage-based widths and heights.
const height = +svg.attr('height'); const width = parseInt(svg.style('width'), 10);
const height = parseInt(svg.style('height'), 10);
const centeringStrengthY = 0.1; const centeringStrengthY = 0.1;
const centeringStrengthX = centeringStrengthY * (height / width); const centeringStrengthX = centeringStrengthY * (height / width);
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
<head> <head>
<link rel="icon" type="image/png" <link rel="icon" type="image/png"
href="https://fonts.gstatic.com/s/i/googlematerialicons/account_tree/v6/gm_blue-48dp/1x/gm_account_tree_gm_blue_48dp.png"> href="https://fonts.gstatic.com/s/i/googlematerialicons/account_tree/v6/gm_blue-48dp/1x/gm_account_tree_gm_blue_48dp.png">
<link rel="stylesheet"
href="//fonts.googleapis.com/css?family=Roboto:400,500,700,400italic|Material+Icons">
</head> </head>
<body> <body>
<div id="package-graph-page"></div> <div id="package-graph-page"></div>
......
...@@ -2,13 +2,39 @@ ...@@ -2,13 +2,39 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import Vue from 'vue';
import PackageGraphPage from './vue_components/package_graph_page.vue'; import PackageGraphPage from './vue_components/package_graph_page.vue';
import {loadGraph} from './load_graph.js'; import {loadGraph} from './load_graph.js';
import * as d3 from 'd3';
import Vue from 'vue';
import {
MdButton,
MdCheckbox,
MdDivider,
MdField,
MdIcon,
MdList,
// MdMenu is a dependency of MdField's MdSelect, see
// https://github.com/vuematerial/vue-material/issues/1974
MdMenu,
MdRadio,
MdSubheader,
} from 'vue-material/dist/components';
import 'vue-material/dist/vue-material.min.css';
import 'vue-material/dist/theme/default.css';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
loadGraph().then(data => { loadGraph().then(data => {
Vue.use(MdButton);
Vue.use(MdCheckbox);
Vue.use(MdDivider);
Vue.use(MdField);
Vue.use(MdIcon);
Vue.use(MdList);
Vue.use(MdMenu);
Vue.use(MdRadio);
Vue.use(MdSubheader);
new Vue({ new Vue({
el: '#package-graph-page', el: '#package-graph-page',
render: createElement => createElement( render: createElement => createElement(
...@@ -21,6 +47,6 @@ document.addEventListener('DOMContentLoaded', () => { ...@@ -21,6 +47,6 @@ document.addEventListener('DOMContentLoaded', () => {
), ),
}); });
}).catch(e => { }).catch(e => {
document.write("Error loading graph."); document.write('Error loading graph.');
}); });
}); });
...@@ -9,15 +9,15 @@ ...@@ -9,15 +9,15 @@
v-for="hullDisplay in HullDisplay" v-for="hullDisplay in HullDisplay"
:key="hullDisplay" :key="hullDisplay"
@change="displayOptionChanged"> @change="displayOptionChanged">
<input <MdRadio
:id="hullDisplay" :id="hullDisplay"
v-model="internalSelectedHullDisplay" v-model="internalSelectedHullDisplay"
class="md-primary hull-settings-option"
type="radio" type="radio"
name="hullDisplayRadioButtons" name="hullDisplayRadioButtons"
:value="hullDisplay"> :value="hullDisplay">
<label :for="hullDisplay">
{{ hullDisplay }} {{ hullDisplay }}
</label> </MdRadio>
</div> </div>
</div> </div>
</template> </template>
...@@ -58,4 +58,8 @@ export default ClassGraphHullSettings; ...@@ -58,4 +58,8 @@ export default ClassGraphHullSettings;
flex-direction: column; flex-direction: column;
margin-bottom: 10px; margin-bottom: 10px;
} }
.hull-settings-option {
margin: 0;
}
</style> </style>
...@@ -4,31 +4,12 @@ ...@@ -4,31 +4,12 @@
<template> <template>
<div id="page-container"> <div id="page-container">
<div id="page-controls"> <div id="title-and-graph-container">
<GraphFilterInput <div
:node-ids="pageModel.getNodeIds()" id="title"
:nodes-already-in-filter=" class="md-headline">
displaySettingsData.nodeFilterData.filterList" Clank Dependency Viewer - Class Graph
:shorten-name="filterShortenName" </div>
@[CUSTOM_EVENTS.FILTER_SUBMITTED]="filterAddOrCheckNode"/>
<GraphFilterItems
:node-filter-data="displaySettingsData.nodeFilterData"
:shorten-name="filterShortenName"
@[CUSTOM_EVENTS.FILTER_REMOVE]="filterRemoveNode"
@[CUSTOM_EVENTS.FILTER_CHECK_ALL]="filterCheckAll"
@[CUSTOM_EVENTS.FILTER_UNCHECK_ALL]="filterUncheckAll"/>
<NumericInput
description="Change inbound (blue) depth:"
input-id="inbound-input"
:input-value.sync="displaySettingsData.inboundDepth"
:min-value="0"/>
<NumericInput
description="Change outbound (yellow) depth:"
input-id="outbound-input"
:input-value.sync="displaySettingsData.outboundDepth"
:min-value="0"/>
</div>
<div id="graph-and-node-details-container">
<GraphVisualization <GraphVisualization
:graph-update-triggers="[ :graph-update-triggers="[
getNodeGroup, getNodeGroup,
...@@ -39,25 +20,61 @@ ...@@ -39,25 +20,61 @@
:get-node-group="getNodeGroup" :get-node-group="getNodeGroup"
@[CUSTOM_EVENTS.NODE_CLICKED]="graphNodeClicked" @[CUSTOM_EVENTS.NODE_CLICKED]="graphNodeClicked"
@[CUSTOM_EVENTS.NODE_DOUBLE_CLICKED]="graphNodeDoubleClicked"/> @[CUSTOM_EVENTS.NODE_DOUBLE_CLICKED]="graphNodeDoubleClicked"/>
<div id="node-details-container"> </div>
<GraphDisplayPanel <div
:display-settings-data="displaySettingsData" id="page-sidebar"
:display-settings-preset.sync=" class="md-elevation-3">
displaySettingsData.displaySettingsPreset"> <MdSubheader class="sidebar-subheader">
<GraphDisplaySettings Node Filter
:display-settings-data="displaySettingsData" </MdSubheader>
@[CUSTOM_EVENTS.DISPLAY_OPTION_CHANGED]="displayOptionChanged"/> <GraphFilterItems
<ClassGraphHullSettings id="graph-filter-items"
:selected-hull-display.sync="displaySettingsData.hullDisplay" :node-filter-data="displaySettingsData.nodeFilterData"
@[CUSTOM_EVENTS.DISPLAY_OPTION_CHANGED]="displayOptionChanged"/> :shorten-name="filterShortenName"
</GraphDisplayPanel> @[CUSTOM_EVENTS.FILTER_REMOVE]="filterRemoveNode"
<GraphSelectedNodeDetails @[CUSTOM_EVENTS.FILTER_CHECK_ALL]="filterCheckAll"
:selected-node-details-data="pageModel.selectedNodeDetailsData" @[CUSTOM_EVENTS.FILTER_UNCHECK_ALL]="filterUncheckAll"/>
@[CUSTOM_EVENTS.DETAILS_CHECK_NODE]="filterAddOrCheckNode" <GraphFilterInput
@[CUSTOM_EVENTS.DETAILS_UNCHECK_NODE]="filterUncheckNode"/> :node-ids="pageModel.getNodeIds()"
<ClassDetailsPanel :nodes-already-in-filter="
:selected-class="pageModel.selectedNodeDetailsData.selectedNode"/> displaySettingsData.nodeFilterData.filterList"
:shorten-name="filterShortenName"
@[CUSTOM_EVENTS.FILTER_SUBMITTED]="filterAddOrCheckNode"/>
<MdSubheader class="sidebar-subheader">
Display Options
</MdSubheader>
<div id="inbound-outbound-depth-inputs">
<NumericInput
description="Inbound Depth"
input-id="inbound-input"
:input-value.sync="displaySettingsData.inboundDepth"
:min-value="0"/>
<NumericInput
description="Outbound Depth"
input-id="outbound-input"
:input-value.sync="displaySettingsData.outboundDepth"
:min-value="0"/>
</div> </div>
<GraphDisplayPanel
:display-settings-data="displaySettingsData"
:display-settings-preset.sync="
displaySettingsData.displaySettingsPreset">
<GraphDisplaySettings
:display-settings-data="displaySettingsData"
@[CUSTOM_EVENTS.DISPLAY_OPTION_CHANGED]="displayOptionChanged"/>
<ClassGraphHullSettings
:selected-hull-display.sync="displaySettingsData.hullDisplay"
@[CUSTOM_EVENTS.DISPLAY_OPTION_CHANGED]="displayOptionChanged"/>
</GraphDisplayPanel>
<MdSubheader class="sidebar-subheader">
Node Details
</MdSubheader>
<GraphSelectedNodeDetails
:selected-node-details-data="pageModel.selectedNodeDetailsData"
@[CUSTOM_EVENTS.DETAILS_CHECK_NODE]="filterAddOrCheckNode"
@[CUSTOM_EVENTS.DETAILS_UNCHECK_NODE]="filterUncheckNode"/>
<ClassDetailsPanel
:selected-class="pageModel.selectedNodeDetailsData.selectedNode"/>
</div> </div>
</div> </div>
</template> </template>
...@@ -247,19 +264,48 @@ export default ClassGraphPage; ...@@ -247,19 +264,48 @@ export default ClassGraphPage;
</style> </style>
<style scoped> <style scoped>
#title {
padding: 10px;
}
#page-container { #page-container {
display: flex;
flex-direction: row;
height: 100vh;
width: 100vw;
}
#title-and-graph-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex-grow: 1;
} }
#page-controls { #page-sidebar {
display: flex;
flex-direction: column;
flex-grow: 0;
overflow-y: scroll;
padding: 0 20px;
width: 30vw;
}
.sidebar-subheader {
padding: 0;
}
#graph-filter-items {
margin-bottom: 10px;
}
#inbound-outbound-depth-inputs {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
height: 15vh;
} }
#graph-and-node-details-container { #page-controls {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
height: 15vh;
} }
</style> </style>
...@@ -5,21 +5,31 @@ ...@@ -5,21 +5,31 @@
<template> <template>
<div id="display-panel"> <div id="display-panel">
<div id="preset-container"> <div id="preset-container">
<select <MdField id="preset-select-container">
v-model="internalDisplaySettingsPreset" <label for="preset-select">Display Preset</label>
@change="applySelectedPreset"> <MdSelect
<option id="preset-select"
v-for="presetName in DisplaySettingsPreset" v-model="internalDisplaySettingsPreset"
:key="presetName" @md-selected="applySelectedPreset">
:value="presetName"> <MdOption
{{ presetName }} v-for="presetName in DisplaySettingsPreset"
</option> :key="presetName"
</select> :value="presetName">
<button @click="settingsExpanded = !settingsExpanded"> {{ presetName }}
{{ settingsExpanded ? 'Collapse' : 'Expand' }} Advanced Settings </MdOption>
</button> </MdSelect>
</MdField>
<MdButton
class="md-primary md-raised md-dense"
@click="settingsExpanded = !settingsExpanded">
{{ settingsExpanded ? 'Hide' : 'Show' }} Advanced
</MdButton>
</div>
<div
v-if="settingsExpanded"
id="advanced-panel">
<slot/>
</div> </div>
<slot v-if="settingsExpanded"/>
</div> </div>
</template> </template>
...@@ -63,8 +73,19 @@ export default GraphDisplaySettings; ...@@ -63,8 +73,19 @@ export default GraphDisplaySettings;
<style scoped> <style scoped>
#preset-container { #preset-container {
align-items: baseline;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between;
}
#preset-select-container {
margin-bottom: 0;
width: 60%;
}
#advanced-panel {
margin: 0 20px;
} }
#display-panel { #display-panel {
......
...@@ -4,34 +4,36 @@ ...@@ -4,34 +4,36 @@
<template> <template>
<div id="display-settings"> <div id="display-settings">
<div> <MdField class="display-settings-option">
<input <label for="graph-edge-color">Graph edge color scheme:</label>
id="curve-edges" <MdSelect
v-model="displaySettingsData.curveEdges" id="graph-edge-color"
type="checkbox" v-model="displaySettingsData.graphEdgeColor"
@change="displayOptionChanged"> @md-selected="displayOptionChanged">
<label for="curve-edges">Curve graph edges</label> <MdOption
</div> v-for="edgeColor in GraphEdgeColor"
<div> :key="edgeColor"
<input :value="edgeColor">
id="color-on-hover" {{ edgeColor }}
v-model="displaySettingsData.colorOnlyOnHover" </MdOption>
type="checkbox" </MdSelect>
@change="displayOptionChanged"> </MdField>
<label for="color-on-hover">Color graph edges only on node hover</label> <MdCheckbox
</div> id="curve-edges"
<label for="graph-edge-color">Graph edge color scheme:</label> v-model="displaySettingsData.curveEdges"
<select class="md-primary display-settings-option"
id="graph-edge-color" type="checkbox"
v-model="displaySettingsData.graphEdgeColor"
@change="displayOptionChanged"> @change="displayOptionChanged">
<option Curve graph edges
v-for="edgeColor in GraphEdgeColor" </MdCheckbox>
:key="edgeColor" <MdCheckbox
:value="edgeColor"> id="color-on-hover"
{{ edgeColor }} v-model="displaySettingsData.colorOnlyOnHover"
</option> class="md-primary display-settings-option"
</select> type="checkbox"
@change="displayOptionChanged">
Color graph edges only on node hover
</MdCheckbox>
</div> </div>
</template> </template>
...@@ -63,4 +65,8 @@ export default GraphDisplaySettings; ...@@ -63,4 +65,8 @@ export default GraphDisplaySettings;
flex-direction: column; flex-direction: column;
margin-bottom: 10px; margin-bottom: 10px;
} }
.display-settings-option {
margin: 5px 0;
}
</style> </style>
...@@ -4,7 +4,11 @@ ...@@ -4,7 +4,11 @@
<template> <template>
<div class="user-input-group"> <div class="user-input-group">
<label for="filter-input">Add node to filter (exact name):</label> <label
class="md-subheading"
for="filter-input">
Add Node
</label>
<Autocomplete <Autocomplete
id="filter-input" id="filter-input"
ref="autocomplete" ref="autocomplete"
...@@ -76,16 +80,23 @@ export default GraphFilterInput; ...@@ -76,16 +80,23 @@ export default GraphFilterInput;
<style> <style>
#filter-input { #filter-input {
width: 500px; width: 100%;
} }
.autocomplete-result-list { .autocomplete-result-list {
background: #fff; background: #fff;
box-sizing: content-box; box-sizing: content-box;
list-style: none; list-style: none;
max-height: 600px; margin: 0;
max-height: 40vh;
overflow-y: auto; overflow-y: auto;
padding: 0; padding: 0;
/* !important since Autocomplete hard-codes z-index into its HTML template */
z-index: 10 !important;
}
.autocomplete-result {
word-wrap: break-word;
} }
.autocomplete-result:hover, .autocomplete-result:hover,
......
...@@ -5,28 +5,36 @@ ...@@ -5,28 +5,36 @@
<template> <template>
<div id="filter-items-container"> <div id="filter-items-container">
<div id="controls"> <div id="controls">
<button @click="checkAll"> <MdButton
class="md-primary md-raised md-dense"
@click="checkAll">
Check All Check All
</button> </MdButton>
<button @click="uncheckAll"> <MdButton
class="md-primary md-raised md-dense"
@click="uncheckAll">
Uncheck All Uncheck All
</button> </MdButton>
</div> </div>
<ul id="filter-list"> <MdList
<li id="filter-list"
class="md-scrollbar">
<MdListItem
v-for="node in filterList" v-for="node in filterList"
:key="node.name"> :key="node.name">
<div class="filter-list-item"> <MdButton
<div @click="removeFromFilter(node.name)"> class="numeric-input-button md-icon-button md-dense"
x @click="removeFromFilter(node.name)">
</div> <MdIcon>clear</MdIcon>
<input </MdButton>
v-model="node.checked" <MdCheckbox
type="checkbox"> v-model="node.checked"
<div>{{ shortenName(node.name) }}</div> class="md-primary"/>
<div class="filter-items-text md-list-item-text">
{{ shortenName(node.name) }}
</div> </div>
</li> </MdListItem>
</ul> </MdList>
</div> </div>
</template> </template>
...@@ -58,6 +66,13 @@ const GraphFilterItems = { ...@@ -58,6 +66,13 @@ const GraphFilterItems = {
export default GraphFilterItems; export default GraphFilterItems;
</script> </script>
<style>
#filter-list .md-list-item-content {
min-height: 0;
padding: 0;
}
</style>
<style scoped> <style scoped>
ul { ul {
list-style-type: none; list-style-type: none;
...@@ -70,20 +85,21 @@ ul { ...@@ -70,20 +85,21 @@ ul {
min-width: 100px; min-width: 100px;
} }
.filter-items-text{
display: inline-block;
margin-left: 15px;
white-space: normal;
width: 100%;
word-wrap: break-word;
}
#filter-list { #filter-list {
margin: 0; max-height: 30vh;
overflow-x: hidden;
overflow-y: scroll; overflow-y: scroll;
padding: 0;
} }
#controls { #controls {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
} }
.filter-list-item {
display: flex;
flex-direction: row;
}
</style> </style>
...@@ -5,28 +5,39 @@ ...@@ -5,28 +5,39 @@
<template> <template>
<div class="selected-node-details"> <div class="selected-node-details">
<template v-if="selectedNode !== null"> <template v-if="selectedNode !== null">
<ul> <MdList class="md-double-line">
<li>Name: {{ selectedNode.id }}</li> <MdListItem>
<li>Display Name: {{ selectedNode.displayName }}</li> <div class="md-list-item-text">
<li <span class="selected-node-details-text">
v-for="(value, key) in selectedNode.visualizationState" {{ selectedNode.id }}
:key="key"> </span>
{{ key }}: {{ value }} <span>Name</span>
</li> </div>
</ul> </MdListItem>
<button <MdListItem>
<div class="md-list-item-text">
<span class="selected-node-details-text">
{{ selectedNode.displayName }}
</span>
<span>Display Name</span>
</div>
</MdListItem>
</MdList>
<MdButton
v-if="selectedNode.visualizationState.selectedByFilter" v-if="selectedNode.visualizationState.selectedByFilter"
class="md-primary md-raised md-dense"
@click="uncheckNodeInFilter"> @click="uncheckNodeInFilter">
Uncheck in filter Uncheck in filter
</button> </MdButton>
<button <MdButton
v-else v-else
class="md-primary md-raised md-dense"
@click="checkNodeInFilter"> @click="checkNodeInFilter">
Add/check in filter Add/check in filter
</button> </MdButton>
</template> </template>
<div v-else> <div v-else>
Click a node for more details. (Click a node for more details.)
</div> </div>
</div> </div>
</template> </template>
...@@ -59,6 +70,12 @@ export default GraphSelectedNodeDetails; ...@@ -59,6 +70,12 @@ export default GraphSelectedNodeDetails;
.selected-node-details { .selected-node-details {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
min-width: 400px; }
.selected-node-details-text{
display: inline-block;
white-space: normal;
width: 100%;
word-wrap: break-word;
} }
</style> </style>
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
<template> <template>
<svg <svg
id="graph-svg" id="graph-svg"
width="960" width="100%"
height="600"/> height="100%"/>
</template> </template>
<script> <script>
...@@ -72,9 +72,12 @@ export default GraphVisualization; ...@@ -72,9 +72,12 @@ export default GraphVisualization;
</script> </script>
<style> <style>
svg text {
font-family: Roboto;
}
.graph-hull-labels text { .graph-hull-labels text {
dominant-baseline: baseline; dominant-baseline: baseline;
font-family: sans-serif;
font-size: 10px; font-size: 10px;
font-weight: bold; font-weight: bold;
text-anchor: middle; text-anchor: middle;
...@@ -89,7 +92,6 @@ export default GraphVisualization; ...@@ -89,7 +92,6 @@ export default GraphVisualization;
} }
.graph-labels text { .graph-labels text {
font-family: sans-serif;
font-size: 12px; font-size: 12px;
} }
......
...@@ -4,20 +4,26 @@ ...@@ -4,20 +4,26 @@
<template> <template>
<div class="numeric-input-container"> <div class="numeric-input-container">
<label :for="inputId">{{ description }}</label> <MdField
<div class="input-and-button-container"> class="input-field">
<input <label :for="inputId">{{ description }}</label>
<MdInput
:id="inputId" :id="inputId"
v-model="internalInputValue" v-model="internalInputValue"
type="number"> class="numeric-input-value"
<div class="button-group"> type="number"/>
<button @click="internalInputValue++"> </MdField>
+ <div class="button-group">
</button> <MdButton
<button @click="internalInputValue--"> class="numeric-input-button md-icon-button md-dense"
- @click="internalInputValue++">
</button> <MdIcon>expand_less</MdIcon>
</div> </MdButton>
<MdButton
class="numeric-input-button md-icon-button md-dense"
@click="internalInputValue--">
<MdIcon>expand_more</MdIcon>
</MdButton>
</div> </div>
</div> </div>
</template> </template>
...@@ -57,25 +63,28 @@ export default NumericInput; ...@@ -57,25 +63,28 @@ export default NumericInput;
<style scoped> <style scoped>
.numeric-input-container { .numeric-input-container {
display: flex;
flex-direction: column;
max-width: 150px;
}
.input-and-button-container {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
} }
.button-group { .button-group {
align-items: center;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
input { .numeric-input-button {
margin: 0;
}
.numeric-input-value {
width: 100%; width: 100%;
} }
.input-field {
width: 50%;
}
input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button { input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none; -webkit-appearance: none;
......
...@@ -58,8 +58,9 @@ export default PackageDetailsPanel; ...@@ -58,8 +58,9 @@ export default PackageDetailsPanel;
<style scoped> <style scoped>
.package-details-panel { .package-details-panel {
max-height: 300px; max-height: 400px;
overflow: hidden; min-height: 200px;
overflow-y: scroll; overflow-y: scroll;
overflow-x: hidden;
} }
</style> </style>
...@@ -4,31 +4,12 @@ ...@@ -4,31 +4,12 @@
<template> <template>
<div id="page-container"> <div id="page-container">
<div id="page-controls"> <div id="title-and-graph-container">
<GraphFilterInput <div
:node-ids="pageModel.getNodeIds()" id="title"
:nodes-already-in-filter=" class="md-headline">
displaySettingsData.nodeFilterData.filterList" Clank Dependency Viewer - Package Graph
:shorten-name="filterShortenName" </div>
@[CUSTOM_EVENTS.FILTER_SUBMITTED]="filterAddOrCheckNode"/>
<GraphFilterItems
:node-filter-data="displaySettingsData.nodeFilterData"
:shorten-name="filterShortenName"
@[CUSTOM_EVENTS.FILTER_REMOVE]="filterRemoveNode"
@[CUSTOM_EVENTS.FILTER_CHECK_ALL]="filterCheckAll"
@[CUSTOM_EVENTS.FILTER_UNCHECK_ALL]="filterUncheckAll"/>
<NumericInput
description="Change inbound (blue) depth:"
input-id="inbound-input"
:input-value.sync="displaySettingsData.inboundDepth"
:min-value="0"/>
<NumericInput
description="Change outbound (yellow) depth:"
input-id="outbound-input"
:input-value.sync="displaySettingsData.outboundDepth"
:min-value="0"/>
</div>
<div id="graph-and-node-details-container">
<GraphVisualization <GraphVisualization
:graph-update-triggers="[ :graph-update-triggers="[
displaySettingsData, displaySettingsData,
...@@ -37,22 +18,58 @@ ...@@ -37,22 +18,58 @@
:display-settings-data="displaySettingsData" :display-settings-data="displaySettingsData"
@[CUSTOM_EVENTS.NODE_CLICKED]="graphNodeClicked" @[CUSTOM_EVENTS.NODE_CLICKED]="graphNodeClicked"
@[CUSTOM_EVENTS.NODE_DOUBLE_CLICKED]="graphNodeDoubleClicked"/> @[CUSTOM_EVENTS.NODE_DOUBLE_CLICKED]="graphNodeDoubleClicked"/>
<div id="node-details-container"> </div>
<GraphDisplayPanel <div
:display-settings-data="displaySettingsData" id="page-sidebar"
:display-settings-preset.sync=" class="md-elevation-3">
displaySettingsData.displaySettingsPreset"> <MdSubheader class="sidebar-subheader">
<GraphDisplaySettings Node Filter
:display-settings-data="displaySettingsData" </MdSubheader>
@[CUSTOM_EVENTS.DISPLAY_OPTION_CHANGED]="displayOptionChanged"/> <GraphFilterItems
</GraphDisplayPanel> id="graph-filter-items"
<GraphSelectedNodeDetails :node-filter-data="displaySettingsData.nodeFilterData"
:selected-node-details-data="pageModel.selectedNodeDetailsData" :shorten-name="filterShortenName"
@[CUSTOM_EVENTS.DETAILS_CHECK_NODE]="filterAddOrCheckNode" @[CUSTOM_EVENTS.FILTER_REMOVE]="filterRemoveNode"
@[CUSTOM_EVENTS.DETAILS_UNCHECK_NODE]="filterUncheckNode"/> @[CUSTOM_EVENTS.FILTER_CHECK_ALL]="filterCheckAll"
<PackageDetailsPanel @[CUSTOM_EVENTS.FILTER_UNCHECK_ALL]="filterUncheckAll"/>
:selected-package="pageModel.selectedNodeDetailsData.selectedNode"/> <GraphFilterInput
:node-ids="pageModel.getNodeIds()"
:nodes-already-in-filter="
displaySettingsData.nodeFilterData.filterList"
:shorten-name="filterShortenName"
@[CUSTOM_EVENTS.FILTER_SUBMITTED]="filterAddOrCheckNode"/>
<MdSubheader class="sidebar-subheader">
Display Options
</MdSubheader>
<div id="inbound-outbound-depth-inputs">
<NumericInput
description="Inbound Depth"
input-id="inbound-input"
:input-value.sync="displaySettingsData.inboundDepth"
:min-value="0"/>
<NumericInput
description="Outbound Depth"
input-id="outbound-input"
:input-value.sync="displaySettingsData.outboundDepth"
:min-value="0"/>
</div> </div>
<GraphDisplayPanel
:display-settings-data="displaySettingsData"
:display-settings-preset.sync="
displaySettingsData.displaySettingsPreset">
<GraphDisplaySettings
:display-settings-data="displaySettingsData"
@[CUSTOM_EVENTS.DISPLAY_OPTION_CHANGED]="displayOptionChanged"/>
</GraphDisplayPanel>
<MdSubheader class="sidebar-subheader">
Node Details
</MdSubheader>
<GraphSelectedNodeDetails
:selected-node-details-data="pageModel.selectedNodeDetailsData"
@[CUSTOM_EVENTS.DETAILS_CHECK_NODE]="filterAddOrCheckNode"
@[CUSTOM_EVENTS.DETAILS_UNCHECK_NODE]="filterUncheckNode"/>
<PackageDetailsPanel
:selected-package="pageModel.selectedNodeDetailsData.selectedNode"/>
</div> </div>
</div> </div>
</template> </template>
...@@ -221,24 +238,48 @@ export default PackageGraphPage; ...@@ -221,24 +238,48 @@ export default PackageGraphPage;
</style> </style>
<style scoped> <style scoped>
#title {
padding: 10px;
}
#page-container { #page-container {
display: flex;
flex-direction: row;
height: 100vh;
width: 100vw;
}
#title-and-graph-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex-grow: 1;
} }
#page-controls { #page-sidebar {
display: flex; display: flex;
flex-direction: row; flex-direction: column;
height: 15vh; flex-grow: 0;
overflow-y: scroll;
padding: 0 20px;
width: 30vw;
}
.sidebar-subheader {
padding: 0;
} }
#graph-and-node-details-container { #graph-filter-items {
margin-bottom: 10px;
}
#inbound-outbound-depth-inputs {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
} }
#node-details-container { #page-controls {
display: flex; display: flex;
flex-direction: column; flex-direction: row;
height: 15vh;
} }
</style> </style>
...@@ -59,7 +59,6 @@ module.exports = { ...@@ -59,7 +59,6 @@ module.exports = {
}, },
{ {
test: /\.css$/, test: /\.css$/,
include: path.resolve(__dirname, 'src'),
use: ['vue-style-loader', 'style-loader', 'css-loader'], use: ['vue-style-loader', 'style-loader', 'css-loader'],
}, },
], ],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment