open-nomad/ui/app/templates/components/topo-viz/node.hbs
Michael Lange 0ab6b31cab Refactor topo viz to do as much computation upfront & use faster data structures
Now all data loading happens in the TopoViz component as well as
computation of resource proportions.

Allocation selection state is also managed centrally uses a dedicated
structure indexed by group key (job id and task group name). This way
allocations don't need to be scanned at the node level, which is O(n) at
the best (assuming no ember overhead on recomputes).
2020-10-15 02:54:14 -07:00

103 lines
5 KiB
Handlebars

<div class="chart topo-viz-node {{unless this.allocations.length "is-empty"}}" {{did-insert this.reloadNode}}>
<p>
<strong>{{@node.node.name}}</strong>
<span class="bumper-left">{{this.count}} Allocs</span>
<span class="bumper-left is-faded">{{@node.memory}} MiB, {{@node.cpu}} Mhz</span>
</p>
<svg class="chart" height="{{this.totalHeight}}px" {{did-insert this.render}} {{did-update this.updateRender}} {{window-resize this.render}}>
<defs>
<clipPath id="{{this.maskId}}">
<rect class="mask" x="0" y="0" width="{{this.dimensionsWidth}}px" height="{{this.maskHeight}}px" rx="2px" ry="2px" />
</clipPath>
</defs>
<rect class="node-background" width="100%" height="{{this.totalHeight}}px" rx="2px" ry="2px" />
{{#if this.allocations.length}}
<g
class="dimensions {{if this.activeAllocation "is-active"}}"
transform="translate({{this.paddingLeft}},{{this.padding}})"
width="{{this.dimensionsWidth}}px"
height="{{this.maskHeight}}px"
pointer-events="all"
{{on "mouseout" this.clearHighlight}}
>
<g class="memory">
{{#if this.data.memoryLabel}}
<text class="label" aria-label="Memory" transform="translate({{this.data.memoryLabel.x}},{{this.data.memoryLabel.y}})">M</text>
{{/if}}
{{#if this.data.memoryRemainder}}
<rect
class="dimension-background"
x="{{this.data.memoryRemainder.x}}px"
width="{{this.data.memoryRemainder.width}}px"
height="{{this.height}}px" />
{{/if}}
{{#each this.data.memory key="allocation.id" as |memory|}}
<g
class="bar {{memory.className}} {{if (eq this.activeAllocation memory.allocation) "is-active"}} {{if memory.allocation.isSelected "is-selected"}}"
clip-path="url(#{{this.maskId}})"
data-allocation-id="{{memory.allocation.allocation.id}}"
{{on "mouseenter" (fn this.highlightAllocation memory.allocation)}}
{{on "click" (fn this.selectAllocation memory.allocation)}}>
<rect
width="{{memory.width}}px"
height="{{if memory.allocation.isSelected this.selectedHeight this.height}}px"
x="{{memory.x}}px"
y="{{if memory.allocation.isSelected 0.5 0}}px"
class="layer-0" />
{{#if (or (eq memory.className "starting") (eq memory.className "pending"))}}
<rect
width="{{memory.width}}px"
height="{{if memory.allocation.isSelected this.selectedHeight this.height}}px"
x="{{memory.x}}px"
y="{{if memory.allocation.isSelected 0.5 0}}px"
class="layer-1" />
{{/if}}
</g>
{{/each}}
</g>
<g class="cpu">
{{#if this.data.cpuLabel}}
<text class="label" aria-label="CPU" transform="translate({{this.data.cpuLabel.x}},{{this.data.cpuLabel.y}})">C</text>
{{/if}}
{{#if this.data.cpuRemainder}}
<rect
class="dimension-background"
x="{{this.data.cpuRemainder.x}}px"
y="{{this.yOffset}}px"
width="{{this.data.cpuRemainder.width}}px"
height="{{this.height}}px" />
{{/if}}
{{#each this.data.cpu key="allocation.id" as |cpu|}}
<g
class="bar {{cpu.className}} {{if (eq this.activeAllocation cpu.allocation) "is-active"}} {{if cpu.allocation.isSelected "is-selected"}}"
clip-path="url(#{{this.maskId}})"
data-allocation-id="{{cpu.allocation.allocation.id}}"
{{on "mouseenter" (fn this.highlightAllocation cpu.allocation)}}
{{on "click" (fn this.selectAllocation cpu.allocation)}}>
<rect
width="{{cpu.width}}px"
height="{{if cpu.allocation.isSelected this.selectedHeight this.height}}px"
x="{{cpu.x}}px"
y="{{if cpu.allocation.isSelected this.selectedYOffset this.yOffset}}px"
class="layer-0" />
{{#if (or (eq cpu.className "starting") (eq cpu.className "pending"))}}
<rect
width="{{cpu.width}}px"
height="{{if cpu.allocation.isSelected this.selectedHeight this.height}}px"
x="{{cpu.x}}px"
y="{{if cpu.allocation.isSelected this.selectedYOffset this.yOffset}}px"
class="layer-1" />
{{/if}}
</g>
{{/each}}
</g>
</g>
{{/if}}
</svg>
<div class="chart-tooltip {{if this.isActive "active" "inactive"}}" style={{this.tooltipStyle}}>
<LinkTo @route="allocations.allocation" @model={{this.activeAllocation}}>{{this.activeAllocation.name}} {{this.activeAllocation.shortId}}</LinkTo>
({{this.activeAllocation.resources.memory}} MiB, {{this.activeAllocation.resources.cpu}} Mhz)
</div>
</div>