Toolbar changes

This commit is contained in:
Jamie Wong
2018-01-07 16:18:41 -08:00
parent 61ca86f60e
commit ebb1627f76
3 changed files with 110 additions and 14 deletions

View File

@@ -23,10 +23,46 @@ interface ApplicationState {
sortOrder: SortOrder
}
export class Toolbar extends ReloadableComponent<{}, ApplicationState> {
interface ToolbarProps extends ApplicationState {
setSortOrder(order: SortOrder): void
}
export class Toolbar extends ReloadableComponent<ToolbarProps, void> {
setTimeOrder = () => {
this.props.setSortOrder(SortOrder.CHRONO)
}
setLeftHeavyOrder = () => {
this.props.setSortOrder(SortOrder.LEFT_HEAVY)
}
render() {
const help = (
<div className={css(style.toolbarTab)}>
<a href="https://github.com/jlfwong/speedscope#usage" className={css(style.noLinkStyle)} target="_blank">
<span className={css(style.emoji)}></span>Help
</a>
</div>
)
if (!this.props.profile) {
return <div className={css(style.toolbar)}>
<div className={css(style.toolbarLeft)}>{help}</div>
🔬speedscope
</div>
}
return <div className={css(style.toolbar)}>
speedscope
<div className={css(style.toolbarLeft)}>
<div className={css(style.toolbarTab, this.props.sortOrder === SortOrder.CHRONO && style.toolbarTabActive)} onClick={this.setTimeOrder}>
<span className={css(style.emoji)}>🕰</span>Time Order
</div>
<div className={css(style.toolbarTab, this.props.sortOrder === SortOrder.LEFT_HEAVY && style.toolbarTabActive)} onClick={this.setLeftHeavyOrder}>
<span className={css(style.emoji)}></span>Left Heavy
</div>
{help}
</div>
{this.props.profile.getName()}
<div className={css(style.toolbarRight)}>🔬speedscope</div>
</div>
}
}
@@ -53,6 +89,8 @@ export class Application extends ReloadableComponent<{}, ApplicationState> {
loadFromString(fileName: string, contents: string) {
console.time('import')
const profile = fileName.endsWith('json') ? this.importJSON(JSON.parse(contents)) : importFromBGFlameGraph(contents)
profile.setName(fileName)
document.title = `${fileName} - speedscope`
const flamechart = new Flamechart(profile)
const sortedFlamechart = new Flamechart({
getTotalWeight: profile.getTotalNonIdleWeight.bind(profile),
@@ -145,12 +183,16 @@ export class Application extends ReloadableComponent<{}, ApplicationState> {
</div>
}
setSortOrder = (sortOrder: SortOrder) => {
this.setState({ sortOrder })
}
render() {
const {flamechart, sortedFlamechart, sortOrder} = this.state
const {profile, flamechart, sortedFlamechart, sortOrder} = this.state
const flamechartToView = sortOrder == SortOrder.CHRONO ? flamechart : sortedFlamechart
return <div onDrop={this.onDrop} onDragOver={this.onDragOver} className={css(style.root)}>
<Toolbar />
<Toolbar setSortOrder={this.setSortOrder} {...this.state} />
{flamechartToView ?
<FlamechartView ref={this.flamechartRef} flamechart={flamechartToView} /> :
this.renderLanding()}
@@ -168,16 +210,6 @@ const style = StyleSheet.create({
position: 'relative',
fontFamily: FontFamily.MONOSPACE
},
toolbar: {
height: 18,
background: 'black',
color: 'white',
textAlign: 'center',
fontFamily: FontFamily.MONOSPACE,
fontSize: FontSize.TITLE,
lineHeight: '18px',
userSelect: 'none'
},
landingContainer: {
display: 'flex',
alignItems: 'center',
@@ -214,6 +246,64 @@ const style = StyleSheet.create({
color: Colors.LIGHT_BLUE,
cursor: 'pointer',
textDecoration: 'none'
},
toolbar: {
height: 18,
background: 'black',
color: 'white',
textAlign: 'center',
fontFamily: FontFamily.MONOSPACE,
fontSize: FontSize.TITLE,
lineHeight: '18px',
userSelect: 'none'
},
toolbarLeft: {
position: 'absolute',
height: 18,
overflow: 'hidden',
top: 0,
left: 0,
marginRight: 2,
textAlign: 'left',
},
toolbarRight: {
height: 18,
overflow: 'hidden',
position: 'absolute',
top: 0,
right: 0,
marginRight: 2,
textAlign: 'right',
},
toolbarTab: {
background: Colors.DARK_GRAY,
marginTop: 2,
height: 16,
lineHeight: '16px',
paddingLeft: 2,
paddingRight: 8,
display: 'inline-block',
marginLeft: 2,
':hover': {
background: Colors.GRAY,
cursor: 'pointer'
}
},
toolbarTabActive: {
background: Colors.LIGHT_BLUE,
':hover': {
background: Colors.LIGHT_BLUE
}
},
noLinkStyle: {
textDecoration: 'none',
color: 'inherit'
},
emoji: {
display: 'inline-block',
verticalAlign: 'middle',
paddingTop: '0px',
marginRight: '0.3em'
}
})

View File

@@ -102,6 +102,8 @@ export class TimeFormatter implements ValueFormatter {
}
export class Profile {
private name: string
private totalWeight: number
private frames = new Map<string | number, Frame>()
@@ -122,6 +124,9 @@ export class Profile {
formatValue(v: number) { return this.valueFormatter.format(v) }
setValueFormatter(f: ValueFormatter) { this.valueFormatter = f }
getName() { return this.name }
setName(name: string) { this.name = name }
getTotalWeight() { return this.totalWeight }
getTotalNonIdleWeight() {
return this.groupedCalltreeRoot.children.reduce((n, c) => n + c.getTotalWeight(), 0)

View File

@@ -12,6 +12,7 @@ export enum Colors {
LIGHT_GRAY = "#C4C4C4",
MEDIUM_GRAY = "#BDBDBD",
GRAY = '#666666',
DARK_GRAY = '#333333',
LIGHT_BLUE = '#56CCF2',
DARK_BLUE = '#2F80ED'
}