Chromium Code Reviews| Index: runtime/observatory/lib/src/elements/cpu_profile.html |
| diff --git a/runtime/observatory/lib/src/elements/cpu_profile.html b/runtime/observatory/lib/src/elements/cpu_profile.html |
| index 3d837d553031aff4e39e1aa92274b242d75d91f5..a89f825707074d264d5ff7b9ad39e7e3d13c5c70 100644 |
| --- a/runtime/observatory/lib/src/elements/cpu_profile.html |
| +++ b/runtime/observatory/lib/src/elements/cpu_profile.html |
| @@ -17,152 +17,186 @@ |
| <nav-control></nav-control> |
| </nav-bar> |
| <style> |
| + .tableWell { |
| + background-color: #ECECEC; |
| + padding: 0.2em; |
| + } |
| + |
| .table { |
| - border-collapse: collapse!important; |
| + border-spacing: 0px; |
| width: 100%; |
| margin-bottom: 20px |
| - table-layout: fixed; |
| - } |
| - .table thead > tr > th, |
| - .table tbody > tr > th, |
| - .table tfoot > tr > th, |
| - .table thead > tr > td, |
| - .table tbody > tr > td, |
| - .table tfoot > tr > td { |
| - padding: 8px; |
| - vertical-align: top; |
| - } |
| - .table thead > tr > th { |
| - vertical-align: bottom; |
| - text-align: left; |
| - border-bottom:2px solid #ddd; |
| + vertical-align: middle; |
| } |
| - tr:hover > td { |
| - background-color: #FFF3E3; |
| - } |
| - .rowColor0 { |
| - background-color: #FFE9CC; |
| - } |
| - .rowColor1 { |
| - background-color: #FFDEB2; |
| - } |
| - .rowColor2 { |
| - background-color: #FFD399; |
| + tr { |
| + background-color: #FFFFFF; |
| } |
| - .rowColor3 { |
| - background-color: #FFC87F; |
| - } |
| - .rowColor4 { |
| - background-color: #FFBD66; |
| - } |
| - .rowColor5 { |
| - background-color: #FFB24C; |
| - } |
| - .rowColor6 { |
| - background-color: #FFA733; |
| + |
| + tbody tr { |
| + animation: fadeIn 0.5s; |
| + -moz-animation: fadeIn 0.5s; |
| + -webkit-animation: fadeIn 0.5s; |
| } |
| - .rowColor7 { |
| - background-color: #FF9C19; |
| + |
| + tbody tr:hover { |
| + background-color: #FAFAFA; |
| } |
| - .rowColor8 { |
| - background-color: #FF9100; |
| + |
| + tr td:first-child, |
| + tr th:first-child { |
| + width: 100%; |
| } |
| - .tooltip { |
| - display: block; |
| - position: absolute; |
| - visibility: hidden; |
| - opacity: 0; |
| - transition: visibility 0s linear 0.5s; |
| - transition: opacity .4s ease-in-out; |
| + .table thead > tr > th { |
| + padding: 8px; |
| + vertical-align: bottom; |
| + text-align: left; |
| + border-bottom: 1px solid #ddd; |
| } |
| - tr:hover .tooltip { |
| - display: block; |
| + .infoBox { |
| position: absolute; |
| top: 100%; |
| - right: 100%; |
| - visibility: visible; |
| + left: 0%; |
| z-index: 999; |
| - width: 400px; |
| - color: #ffffff; |
| - background-color: #0489c3; |
| - border-top-right-radius: 8px; |
| - border-top-left-radius: 8px; |
| - border-bottom-right-radius: 8px; |
| - border-bottom-left-radius: 8px; |
| - transition: visibility 0s linear 0.5s; |
| - transition: opacity .4s ease-in-out; |
| opacity: 1; |
| + padding: 1em; |
| + background-color: #ffffff; |
| + border-left: solid 2px #ECECEC; |
| + border-bottom: solid 2px #ECECEC; |
| + border-right: solid 2px #ECECEC; |
| + } |
| + |
| + .statusMessage { |
| + font-size: 150%; |
| + font-weight: bold; |
| } |
| - .white { |
| - color: #ffffff; |
| + .statusBox { |
| + height: 100%; |
| + padding: 1em; |
| + } |
| + |
| + .center { |
| + align-items: center; |
| + justify-content: center; |
| + } |
| + |
| + .notice { |
| + background-color: #fcf8e3; |
| + } |
| + |
| + .red { |
| + background-color: #f2dede; |
| } |
| </style> |
| - <div class="content"> |
| + <div class="content-centered-big"> |
| <h1>Sampled CPU profile</h1> |
| - <div class="memberList"> |
| - <div class="memberItem"> |
| - <div class="memberName">Timestamp</div> |
| - <div class="memberValue">{{ refreshTime }}</div> |
| - </div> |
| - <div class="memberItem"> |
| - <div class="memberName">Time span</div> |
| - <div class="memberValue">{{ timeSpan }}</div> |
| - </div> |
| - <div class="memberItem"> |
| - <div class="memberName">Sample count</div> |
| - <div class="memberValue">{{ sampleCount }}</div> |
| + <hr> |
| + <template if="{{ state == 'Requested' }}"> |
| + <div class="statusBox shadow center"> |
| + <div class="statusMessage">Fetching profile from VM...</div> |
| </div> |
| - <div class="memberItem"> |
| - <div class="memberName">Sample rate</div> |
| - <div class="memberValue">{{ sampleRate }} Hz</div> |
| + </template> |
| + <template if="{{ state == 'Loading' }}"> |
| + <div class="statusBox shadow center"> |
| + <div class="statusMessage">Loading profile...</div> |
| </div> |
| - <div class="memberItem"> |
| - <div class="memberName">Stack depth</div> |
| - <div class="memberValue">{{ stackDepth }} stack frames</div> |
| + </template> |
| + <template if="{{ state == 'Exception' }}"> |
| + <div class="statusBox shadow center"> |
| + <div class="statusMessage"> |
| + <h1>Exception:</h1> |
| + <br> |
| + <pre>{{ exception.toString() }}</pre> |
| + <br> |
| + <h1>Stack trace:</h1> |
| + <br> |
| + <pre>{{ stackTrace.toString() }}</pre> |
| + </div> |
| </div> |
| - <div class="memberItem"> |
| - <div class="memberName">Display cutoff</div> |
| - <div class="memberValue">{{ displayCutoff }}</div> |
| + </template> |
| + <template if="{{ state == 'Loaded' }}"> |
| + <div class="memberList"> |
| + <div class="memberItem"> |
| + <div class="memberName">Refreshed at </div> |
| + <div class="memberValue">{{ refreshTime }} (fetched in {{ fetchTime }}) (loaded in {{ loadTime }})</div> |
|
rmacnak
2015/03/02 22:25:26
units: fetched in XX seconds, loaded in XX seconds
Cutch
2015/03/02 22:48:19
These are formatted with formatTime which adds uni
|
| + </div> |
| + <div class="memberItem"> |
| + <div class="memberName">Profile contains</div> |
| + <div class="memberValue">{{ sampleCount }} samples (spanning {{ timeSpan }})</div> |
| + </div> |
| + <div class="memberItem"> |
| + <div class="memberName">Sampling</div> |
| + <div class="memberValue">{{ stackDepth }} stack frames @ {{ sampleRate }} Hz</div> |
| + </div> |
| + <div class="memberItem"> |
| + <div class="memberName">Mode</div> |
| + <div class="memberValue"> |
| + <select value="{{modeSelector}}"> |
| + <option value="Code">Code</option> |
| + <option value="Function">Function</option> |
| + </select> |
| + </div> |
| + </div> |
| + <div class="memberItem"> |
| + <div class="memberName">Tag Order</div> |
| + <div class="memberValue"> |
| + <select value="{{tagSelector}}"> |
| + <option value="UserVM">User > VM</option> |
| + <option value="UserOnly">User</option> |
| + <option value="VMUser">VM > User</option> |
| + <option value="VMOnly">VM</option> |
| + <option value="None">None</option> |
| + </select> |
| + </div> |
| + </div> |
| + <div class="memberItem"> |
| + <div class="memberName">Call Tree Direction</div> |
| + <div class="memberValue"> |
| + <select value="{{directionSelector}}"> |
| + <option value="Down">Top down</option> |
| + <option value="Up">Bottom up</option> |
| + </select> |
| + </div> |
| + </div> |
| </div> |
| - <div class="memberItem"> |
| - <div class="memberName">Tags</div> |
| - <div class="memberValue"> |
| - <select value="{{tagSelector}}"> |
| - <option value="UserVM">User > VM</option> |
| - <option value="UserOnly">User</option> |
| - <option value="VMUser">VM > User</option> |
| - <option value="VMOnly">VM</option> |
| - <option value="None">None</option> |
| - </select> |
| - </div> |
| + </template> |
| + <template if="{{ state == 'Loaded' && directionSelector == 'Down' }}"> |
| + <br> |
| + <div class="statusBox shadow"> |
| + <div>Tree is rooted at main.</div> |
| + <br> |
| + <div>Child nodes are callees.</div> |
| + <br> |
| + <div class="notice">To get the most out of this mode you may need to launch Dart with a higher --profile-depth flag value.</div> |
| + <div class="notice">Try 16, 32, ... up to 256 until each sample captures the entire call stack.</div> |
| + <div class="red">NOTE: Higher values will impact performance</div> |
| </div> |
| - <div class="memberItem"> |
| - <div class="memberName">Mode</div> |
| - <div class="memberValue"> |
| - <select value="{{modeSelector}}"> |
| - <option value="Code">Code</option> |
| - <option value="Function">Function</option> |
| - </select> |
| - </div> |
| + </template> |
| + <template if="{{ state == 'Loaded' && directionSelector == 'Up' }}"> |
| + <br> |
| + <div class="statusBox shadow"> |
| + <div>Tree is rooted at executing function / code.</div> |
| + <br> |
| + <div>Child nodes are callers.</div> |
| </div> |
| + </template> |
| + <br><br> |
| + <div class="tableWell shadow"> |
| + <table class="table"> |
| + <thead id="treeHeader"> |
| + <tr> |
| + <th>Method</th> |
| + <th>Self</th> |
| + </tr> |
| + </thead> |
| + <tbody id="treeBody"> |
| + </tbody> |
| + </table> |
| </div> |
| - <hr> |
| - <table class="table"> |
| - <thead id="treeHeader"> |
| - <tr> |
| - <th>Method</th> |
| - <th>Self</th> |
| - </tr> |
| - </thead> |
| - <tbody id="treeBody"> |
| - </tbody> |
| - </table> |
| - <hr> |
| </div> |
| </template> |
| </polymer-element> |