Commit 85c6c8ce authored by Michael Lippautz's avatar Michael Lippautz Committed by Commit Bot

[object-stats] Enable ungrouping in visualizer

No-try: true
Bug: v8:7266
Change-Id: I981ac5b4be6117bcc46383d033d639cc3b30b617
Reviewed-on: https://chromium-review.googlesource.com/867371Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50591}
parent a0ab7d45
...@@ -9,5 +9,5 @@ The tool consumes log files produced by d8 (or Chromium) by passing ...@@ -9,5 +9,5 @@ The tool consumes log files produced by d8 (or Chromium) by passing
Hosting requires a web server, e.g.: Hosting requires a web server, e.g.:
cd tools/heap/stats cd tools/heap-stats
python -m SimpleHTTPServer 8000 python -m SimpleHTTPServer 8000
...@@ -140,8 +140,8 @@ const CATEGORIES = new Map([ ...@@ -140,8 +140,8 @@ const CATEGORIES = new Map([
// Maps category to description text that is shown in html. // Maps category to description text that is shown in html.
const CATEGORY_NAMES = new Map([ const CATEGORY_NAMES = new Map([
['user', 'User'], ['user', 'JS'],
['system', 'System'], ['system', 'Metadata'],
['code', 'Code'], ['code', 'Code'],
['unclassified', 'Unclassified'], ['unclassified', 'Unclassified'],
]); ]);
......
...@@ -39,18 +39,32 @@ span { ...@@ -39,18 +39,32 @@ span {
margin-top: 10px; margin-top: 10px;
} }
</style> </style>
<label for="isolate-select"> <ul>
Isolate <li>
</label> <label for="isolate-select">
<select id="isolate-select"> Isolate
<option>No data</option> </label>
</select> <select id="isolate-select">
<label for="dataset-select"> <option>No data</option>
Data set </select>
</label> </li>
<select id="dataset-select"> <li>
<option>No data</option> <label for="dataset-select">
</select> Data set
</label>
<select id="dataset-select">
<option>No data</option>
</select>
</li>
<li>
<input type="checkbox" id="merge-categories" checked=checked />
<label for="merge-categories">
Merge categories
</label>
</li>
</ul>
<div id="categories"></div> <div id="categories"></div>
</template> </template>
<script type="text/javascript" src="categories.js"></script> <script type="text/javascript" src="categories.js"></script>
......
...@@ -17,6 +17,8 @@ class DetailsSelection extends HTMLElement { ...@@ -17,6 +17,8 @@ class DetailsSelection extends HTMLElement {
'change', e => this.handleIsolateChange(e)); 'change', e => this.handleIsolateChange(e));
this.datasetSelect.addEventListener( this.datasetSelect.addEventListener(
'change', e => this.notifySelectionChanged(e)); 'change', e => this.notifySelectionChanged(e));
this.$('#merge-categories')
.addEventListener('change', e => this.notifySelectionChanged(e));
} }
connectedCallback() { connectedCallback() {
...@@ -90,11 +92,15 @@ class DetailsSelection extends HTMLElement { ...@@ -90,11 +92,15 @@ class DetailsSelection extends HTMLElement {
notifySelectionChanged(e) { notifySelectionChanged(e) {
if (!this.selection.isolate) return; if (!this.selection.isolate) return;
this.selection.categories = {};
for (let category of CATEGORIES.keys()) { for (let category of CATEGORIES.keys()) {
this.selection.categories[category] = this.selectedInCategory(category); const selected = this.selectedInCategory(category);
if (selected.length > 0) this.selection.categories[category] = selected;
} }
this.selection.category_names = CATEGORY_NAMES; this.selection.category_names = CATEGORY_NAMES;
this.selection.data_set = this.datasetSelect.value; this.selection.data_set = this.datasetSelect.value;
this.selection.merge_categories = this.$('#merge-categories').checked;
this.dispatchEvent(new CustomEvent( this.dispatchEvent(new CustomEvent(
'change', {bubbles: true, composed: true, detail: this.selection})); 'change', {bubbles: true, composed: true, detail: this.selection}));
} }
......
...@@ -18,6 +18,10 @@ class GlobalTimeline extends HTMLElement { ...@@ -18,6 +18,10 @@ class GlobalTimeline extends HTMLElement {
shadowRoot.appendChild(global_timeline_template.content.cloneNode(true)); shadowRoot.appendChild(global_timeline_template.content.cloneNode(true));
} }
$(id) {
return this.shadowRoot.querySelector(id);
}
set data(value) { set data(value) {
this._data = value; this._data = value;
this.stateChanged(); this.stateChanged();
...@@ -44,31 +48,59 @@ class GlobalTimeline extends HTMLElement { ...@@ -44,31 +48,59 @@ class GlobalTimeline extends HTMLElement {
if (this.isValid()) this.drawChart(); if (this.isValid()) this.drawChart();
} }
drawChart() { getCategoryData() {
console.assert(this.data, 'invalid data');
console.assert(this.selection, 'invalid selection');
const categories = Object.keys(this.selection.categories) const categories = Object.keys(this.selection.categories)
.map(k => this.selection.category_names.get(k)); .map(k => this.selection.category_names.get(k));
const labels = ['Time', ...categories]; const labels = ['Time', ...categories];
const chart_data = [labels]; const chart_data = [labels];
const isolate_data = this.data[this.selection.isolate]; const isolate_data = this.data[this.selection.isolate];
for (let k of Object.keys(isolate_data.gcs)) { Object.keys(isolate_data.gcs).forEach(gc_key => {
const gc_data = isolate_data.gcs[k]; const gc_data = isolate_data.gcs[gc_key];
const data_set = gc_data[this.selection.data_set].instance_type_data; const data_set = gc_data[this.selection.data_set].instance_type_data;
const data = []; const data = [];
data.push(gc_data.time); data.push(gc_data.time);
for (let [category, instance_types] of Object.entries( Object.values(this.selection.categories).forEach(instance_types => {
this.selection.categories)) { data.push(
let overall = 0; instance_types
for (let instance_type of instance_types) { .map(instance_type => {
overall += data_set[instance_type].overall; return data_set[instance_type].overall;
} })
data.push(overall / KB); .reduce((accu, current) => accu + current, 0) /
} KB);
});
chart_data.push(data); chart_data.push(data);
} });
return chart_data;
}
getInstanceTypeData() {
const categories = Object.keys(this.selection.categories);
const instance_types =
Object.values(this.selection.categories)
.reduce((accu, current) => accu.concat(current), []);
const labels = ['Time', ...instance_types];
const chart_data = [labels];
const isolate_data = this.data[this.selection.isolate];
Object.keys(isolate_data.gcs).forEach(gc_key => {
const gc_data = isolate_data.gcs[gc_key];
const data_set = gc_data[this.selection.data_set].instance_type_data;
const data = [];
data.push(gc_data.time);
instance_types.forEach(instance_type => {
data.push(data_set[instance_type].overall / KB);
});
chart_data.push(data);
});
return chart_data;
}
drawChart() {
console.assert(this.data, 'invalid data');
console.assert(this.selection, 'invalid selection');
const chart_data = (this.selection.merge_categories) ?
this.getCategoryData() :
this.getInstanceTypeData();
const data = google.visualization.arrayToDataTable(chart_data); const data = google.visualization.arrayToDataTable(chart_data);
const options = { const options = {
isStacked: true, isStacked: true,
...@@ -76,14 +108,14 @@ class GlobalTimeline extends HTMLElement { ...@@ -76,14 +108,14 @@ class GlobalTimeline extends HTMLElement {
title: 'Time [ms]', title: 'Time [ms]',
}, },
vAxis: {title: 'Memory consumption [KBytes]'}, vAxis: {title: 'Memory consumption [KBytes]'},
chartArea: {width: '85%', height: '80%'}, chartArea: {width: '85%', height: '70%'},
legend: {position: 'top', maxLines: '1'}, legend: {position: 'top', maxLines: '1'},
pointsVisible: true, pointsVisible: true,
pointSize: 5, pointSize: 5,
explorer: {},
}; };
const chart = new google.visualization.AreaChart( const chart = new google.visualization.AreaChart(this.$('#chart'));
this.shadowRoot.querySelector('#chart')); this.$('#container').style.display = 'block';
this.shadowRoot.querySelector('#container').style.display = 'block';
chart.draw(data, google.charts.Line.convertOptions(options)); chart.draw(data, google.charts.Line.convertOptions(options));
} }
} }
......
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