Merge pull request #64 from hjacobs/ui-theme

Common color palette
This commit is contained in:
Henning Jacobs
2016-12-23 20:59:17 +01:00
committed by GitHub
10 changed files with 88 additions and 61 deletions

7
app.py
View File

@@ -130,8 +130,8 @@ def generate_mock_pod(index, i, j):
labels = {}
phase = pod_phases[hash_int((index + 1) * (i + 1) * (j + 1)) % len(pod_phases)]
containers = []
for k in range(1):
containers.append({'name': 'myapp', 'image': 'foo/bar/{}'.format(j), 'resources': {'requests': {'cpu': '100m', 'memory': '100Mi'}}})
for k in range(1 + j % 2):
containers.append({'name': 'myapp', 'image': 'foo/bar/{}'.format(j), 'resources': {'requests': {'cpu': '100m', 'memory': '100Mi'}, 'limits': {}}})
status = {'phase': phase}
if phase == 'Running':
if j % 13 == 0:
@@ -139,6 +139,9 @@ def generate_mock_pod(index, i, j):
elif j % 7 == 0:
status['containerStatuses'] = [{'ready': True, 'state': {'running': {}}, 'restartCount': 3}]
pod = {'name': '{}-{}-{}'.format(names[hash_int((i + 1) * (j + 1)) % len(names)], i, j), 'namespace': 'kube-system' if j < 3 else 'default', 'labels': labels, 'status': status, 'containers': containers}
if phase == 'Running' and j % 17 == 0:
pod['deleted'] = 123
return pod

View File

@@ -2,7 +2,8 @@ import Tooltip from './tooltip.js'
import Cluster from './cluster.js'
import {Pod, ALL_PODS, sortByName, sortByMemory, sortByCPU, sortByAge} from './pod.js'
import SelectBox from './selectbox'
import { PRIMARY_VIOLET } from './colors.js'
import { PRIMARY_COLOR, SECONDARY_COLOR } from './colors.js'
import { DESATURATION_FILTER } from './filters.js'
const PIXI = require('pixi.js')
@@ -17,8 +18,6 @@ export default class App {
this.filterString = ''
}
this.seenPods = new Set()
this.desaturationFilter = new PIXI.filters.ColorMatrixFilter()
this.desaturationFilter.desaturate()
this.sorterFn = ''
}
@@ -30,7 +29,7 @@ export default class App {
} else {
document.location.hash = ''
}
const filter = this.desaturationFilter
const filter = DESATURATION_FILTER
for (const cluster of this.viewContainer.children) {
for (const node of cluster.children) {
const name = node.pod && node.pod.name
@@ -73,13 +72,16 @@ export default class App {
const stage = new PIXI.Container()
const menuBar = new PIXI.Graphics()
menuBar.beginFill(PRIMARY_VIOLET, 1)
menuBar.beginFill(SECONDARY_COLOR, 0.8)
menuBar.drawRect(0, 0, window.innerWidth, 28)
menuBar.lineStyle(1.5, 0x000000, 1)
menuBar.lineStyle(2, SECONDARY_COLOR, 0.8)
menuBar.moveTo(0, 28)
menuBar.lineTo(window.innerWidth, 28)
menuBar.lineStyle(1, PRIMARY_COLOR, 1)
menuBar.drawRect(20, 3, 200, 22)
stage.addChild(menuBar)
const searchPrompt = new PIXI.Text('>', {fontFamily: 'ShareTechMono', fontSize: 14})
const searchPrompt = new PIXI.Text('>', {fontFamily: 'ShareTechMono', fontSize: 14, fill: PRIMARY_COLOR})
searchPrompt.x = 26
searchPrompt.y = 8
PIXI.ticker.shared.add(function (_) {
@@ -88,7 +90,7 @@ export default class App {
})
stage.addChild(searchPrompt)
const searchText = new PIXI.Text('', {fontFamily: 'ShareTechMono', fontSize: 14})
const searchText = new PIXI.Text('', {fontFamily: 'ShareTechMono', fontSize: 14, fill: PRIMARY_COLOR})
searchText.x = 40
searchText.y = 8
stage.addChild(searchText)
@@ -150,6 +152,8 @@ export default class App {
animatePodCreation(originalPod, globalPosition) {
const pod = new Pod(originalPod.pod, null, this.tooltip)
pod.draw()
pod.blendMode = PIXI.BLEND_MODES.ADD
pod.interactive = false
const targetPosition = globalPosition
const angle = Math.random()*Math.PI*2
const cos = Math.cos(angle)
@@ -188,6 +192,7 @@ export default class App {
animatePodDeletion(originalPod, globalPosition) {
const pod = new Pod(originalPod.pod, null, this.tooltip)
pod.draw()
pod.blendMode = PIXI.BLEND_MODES.ADD
const globalCenter = new PIXI.Point(globalPosition.x + pod.width/2, globalPosition.y + pod.height/2)
const blur = new PIXI.filters.BlurFilter(4)
pod.filters = [blur]

View File

@@ -1,5 +1,5 @@
import {FACTORS, getBarColor} from './utils'
import {PRIMARY_VIOLET} from './colors'
import {PRIMARY_COLOR} from './colors'
const PIXI = require('pixi.js')
@@ -16,7 +16,7 @@ export default class Bars extends PIXI.Graphics {
const barHeight = 92
bars.beginFill(PRIMARY_VIOLET, 0.1)
bars.beginFill(PRIMARY_COLOR, 0.1)
bars.drawRect(5, 110 - barHeight, 15, barHeight)
bars.endFill()
@@ -39,7 +39,7 @@ export default class Bars extends PIXI.Graphics {
bars.drawRect(16.5, 110 - bars.resources.memory.used / scale, 2.5, bars.resources.memory.used / scale)
bars.endFill()
bars.lineStyle(1, PRIMARY_VIOLET, 1)
bars.lineStyle(1, PRIMARY_COLOR, 1)
for (var i = 0; i < bars.resources.cpu.capacity; i++) {
bars.drawRect(5, 110 - (i + 1) * cpuHeight, 5, cpuHeight)
}

View File

@@ -1,6 +1,6 @@
import Node from './node.js'
import { Pod } from './pod.js'
import { PRIMARY_VIOLET } from './colors.js'
import { PRIMARY_COLOR } from './colors.js'
const PIXI = require('pixi.js')
export default class Cluster extends PIXI.Graphics {
@@ -38,12 +38,12 @@ export default class Cluster extends PIXI.Graphics {
rows[0] += 20
}
this.lineStyle(2, PRIMARY_VIOLET, 1)
this.lineStyle(2, PRIMARY_COLOR, 1)
const width = Math.max(rows[0], rows[1])
this.drawRect(0, 0, width, nodeBox.height * 2 + 30)
var topHandle = new PIXI.Graphics()
topHandle.beginFill(PRIMARY_VIOLET, 1)
topHandle.beginFill(PRIMARY_COLOR, 1)
topHandle.drawRect(0, 0, width, 15)
topHandle.endFill()
var text = new PIXI.Text(this.cluster.api_server_url, {fontFamily: 'ShareTechMono', fontSize: 10, fill: 0x000000})

View File

@@ -1,3 +1,4 @@
const PRIMARY_VIOLET = 0xaaaaff
const PRIMARY_COLOR = 0xaaaaff
const SECONDARY_COLOR = 0x222233
export { PRIMARY_VIOLET }
export { PRIMARY_COLOR, SECONDARY_COLOR }

8
app/src/filters.js Normal file
View File

@@ -0,0 +1,8 @@
const PIXI = require('pixi.js')
const BRIGHTNESS_FILTER = new PIXI.filters.ColorMatrixFilter()
BRIGHTNESS_FILTER.brightness(1.3)
const DESATURATION_FILTER = new PIXI.filters.ColorMatrixFilter()
DESATURATION_FILTER.desaturate()
export { BRIGHTNESS_FILTER, DESATURATION_FILTER }

View File

@@ -1,7 +1,7 @@
import {Pod} from './pod.js'
import Bars from './bars.js'
import {parseResource} from './utils.js'
import {PRIMARY_VIOLET} from './colors.js'
import {PRIMARY_COLOR, SECONDARY_COLOR} from './colors.js'
import App from './app'
const PIXI = require('pixi.js')
@@ -48,25 +48,26 @@ export default class Node extends PIXI.Graphics {
draw() {
const nodeBox = this
const topHandle = new PIXI.Graphics()
topHandle.beginFill(PRIMARY_VIOLET, 1)
topHandle.beginFill(PRIMARY_COLOR, 1)
topHandle.drawRect(0, 0, 105, 15)
topHandle.endFill()
const ellipsizedNodeName = this.node.name.substring(0, 18).concat('...')
const ellipsizedNodeName = this.node.name.length > 17 ? this.node.name.substring(0, 17).concat('') : this.node.name
const text = new PIXI.Text(ellipsizedNodeName, {fontFamily: 'ShareTechMono', fontSize: 10, fill: 0x000000})
text.x = 2
text.y = 2
topHandle.addChild(text)
nodeBox.addChild(topHandle)
nodeBox.lineStyle(2, PRIMARY_VIOLET, 1)
nodeBox.beginFill(PRIMARY_VIOLET, 0.2)
nodeBox.lineStyle(2, PRIMARY_COLOR, 1)
nodeBox.beginFill(SECONDARY_COLOR, 1)
nodeBox.drawRect(0, 0, 105, 115)
nodeBox.endFill()
nodeBox.lineStyle(2, 0xaaaaaa, 1)
topHandle.interactive = true
topHandle.on('mouseover', function () {
let s = nodeBox.node.name
for (const key of Object.keys(nodeBox.node.labels)) {
s += '\n' + key + ': ' + nodeBox.node.labels[key]
s += '\nLabels:'
for (const key of Object.keys(nodeBox.node.labels).sort()) {
s += '\n ' + key + ': ' + nodeBox.node.labels[key]
}
nodeBox.tooltip.setText(s)
nodeBox.tooltip.position = nodeBox.toGlobal(new PIXI.Point(0, 15))

View File

@@ -1,5 +1,7 @@
const PIXI = require('pixi.js')
import {PRIMARY_COLOR} from './colors.js'
import {FACTORS, getBarColor, podResource} from './utils.js'
import {BRIGHTNESS_FILTER} from './filters.js'
const ALL_PODS = {}
@@ -160,14 +162,12 @@ export class Pod extends PIXI.Graphics {
const podBox = this
podBox.interactive = true
podBox.on('mouseover', function () {
const filter = new PIXI.filters.ColorMatrixFilter()
filter.brightness(1.3)
podBox.filters = [filter]
podBox.filters = [BRIGHTNESS_FILTER]
let s = this.pod.name
s += '\nStatus : ' + this.pod.status.phase + ' (' + ready + '/' + containerStatuses.length + ' ready)'
s += '\nStart Time: ' + this.pod.status.startTime
s += '\nLabels :'
for (var key of Object.keys(this.pod.labels)) {
for (var key of Object.keys(this.pod.labels).sort()) {
if (key !== 'pod-template-hash') {
s += '\n ' + key + ': ' + this.pod.labels[key]
}
@@ -201,36 +201,38 @@ export class Pod extends PIXI.Graphics {
podBox.filters = []
this.tooltip.visible = false
})
podBox.lineStyle(2, 0xaaaaaa, 1)
podBox.lineStyle(1, PRIMARY_COLOR, 1)
let i = 0
const w = 10 / this.pod.containers.length
for (const container of this.pod.containers) {
podBox.drawRect(i * w, 0, w, 10)
i++
}
let color
if (this.pod.status.phase == 'Succeeded') {
// completed Job
podBox.lineStyle(2, 0xaaaaff, 1)
color = 0xaaaaff
} else if (this.pod.status.phase == 'Running' && allReady) {
podBox.lineStyle(2, 0xaaffaa, 1)
color = 0xaaffaa
} else if (this.pod.status.phase == 'Running' && allRunning && !allReady) {
// all containers running, but some not ready (readinessProbe)
newTick = this.pulsate
podBox.lineStyle(2, 0xaaffaa, 1)
color = 0xaaffaa
} else if (this.pod.status.phase == 'Pending') {
newTick = this.pulsate
podBox.lineStyle(2, 0xffffaa, 1)
color = 0xffffaa
} else {
// CrashLoopBackOff, ImagePullBackOff or other unknown state
newTick = this.crashing
podBox.lineStyle(2, 0xff9999, 1)
color = 0xffaaaa
}
podBox.beginFill(0x999999, 0.5)
podBox.lineStyle(2, color, 1)
podBox.beginFill(color, 0.2)
podBox.drawRect(0, 0, 10, 10)
if (this.pod.deleted) {
if (!this.cross) {
const cross = new PIXI.Graphics()
cross.lineStyle(3, 0xff6666, 1)
cross.lineStyle(3, 0xff0000, 1)
cross.moveTo(0, 0)
cross.lineTo(10, 10)
cross.moveTo(10, 0)
@@ -239,13 +241,13 @@ export class Pod extends PIXI.Graphics {
cross.pivot.y = 5
cross.x = 5
cross.y = 5
cross.blendMode = PIXI.BLEND_MODES.ADD
this.addChild(cross)
this.cross = cross
}
newTick = this.terminating
}
if (restarts) {
this.lineStyle(2, 0xff9999, 1)
for (let i = 0; i < Math.min(restarts, 4); i++) {
@@ -266,19 +268,20 @@ export class Pod extends PIXI.Graphics {
this.tint = 0xffffff
}
// CPU
const cpuHeight = resources.cpu.limit !== 0 ? 8 / resources.cpu.limit : 0
podBox.lineStyle(0, 0xaaffaa, 1)
podBox.lineStyle()
podBox.beginFill(getBarColor(resources.cpu.requested, resources.cpu.limit), 1)
podBox.drawRect(1, 9 - resources.cpu.requested * cpuHeight, 1, resources.cpu.requested * cpuHeight)
podBox.beginFill(getBarColor(resources.cpu.used, resources.cpu.limit), 1)
podBox.drawRect(2, 9 - resources.cpu.used * cpuHeight, 1, resources.cpu.used * cpuHeight)
podBox.endFill()
podBox.lineStyle(1, 0xaaaaaa, 1)
// Memory
const scale = resources.memory.limit / 8
const scaledMemReq = resources.memory.requested !== 0 && scale !== 0 ? resources.memory.requested / scale : 0
const scaledMemUsed = resources.memory.used !== 0 && scale !== 0 ? resources.memory.used / scale : 0
podBox.lineStyle(0, 0xaaffaa, 1)
podBox.lineStyle()
podBox.beginFill(getBarColor(resources.memory.requested, resources.memory.limit), 1)
podBox.drawRect(3, 9 - scaledMemReq, 1, scaledMemReq)
podBox.beginFill(getBarColor(resources.memory.used, resources.memory.limit), 1)

View File

@@ -1,4 +1,4 @@
import { PRIMARY_VIOLET } from './colors.js'
import { PRIMARY_COLOR, SECONDARY_COLOR } from './colors.js'
import App from './app'
const PIXI = require('pixi.js')
@@ -11,7 +11,7 @@ export default class SelectBox extends PIXI.Graphics {
this.text = new PIXI.Text(this.items[this.count].text, {
fontFamily: 'ShareTechMono',
fontSize: 14,
fill: 0x000000,
fill: PRIMARY_COLOR,
align: 'center'
})
this.text.x = 10
@@ -48,29 +48,33 @@ export default class SelectBox extends PIXI.Graphics {
forwardArrow.interactive = true
selectBox.interactive = true
const arrowBoxWidth = 18
// draw a triangle
backArrow.lineStyle(1.5, 0x000000, 1)
backArrow.beginFill(PRIMARY_VIOLET, 0.9)
backArrow.drawRect(-22, 0, 22, 22)
backArrow.moveTo(-7, 6)
backArrow.lineTo(-16, 11)
backArrow.lineTo(-7, 16)
backArrow.lineTo(-7, 6)
backArrow.beginFill(SECONDARY_COLOR, 1)
backArrow.drawRect(-18, 0, arrowBoxWidth, 22)
backArrow.lineStyle(1, PRIMARY_COLOR, 1)
backArrow.beginFill(SECONDARY_COLOR, 1)
backArrow.moveTo(-4, 5)
backArrow.lineTo(-15, 11)
backArrow.lineTo(-4, 17)
backArrow.lineTo(-4, 5)
backArrow.endFill()
selectBox.addChild(backArrow)
selectBox.lineStyle(1.5, 0x000000, 1)
selectBox.beginFill(PRIMARY_VIOLET, 0.5)
selectBox.lineStyle(1, PRIMARY_COLOR, 1)
selectBox.beginFill(SECONDARY_COLOR, 0.5)
selectBox.drawRect(4, 0, 100, 22)
selectBox.endFill()
forwardArrow.lineStyle(1.5, 0x000000, 1)
forwardArrow.beginFill(PRIMARY_VIOLET, 0.9)
forwardArrow.drawRect(108, 0, 22, 22)
forwardArrow.moveTo(115, 6)
forwardArrow.lineTo(124, 11)
forwardArrow.lineTo(115, 16)
forwardArrow.lineTo(115, 6)
forwardArrow.beginFill(SECONDARY_COLOR, 1)
forwardArrow.drawRect(108, 0, arrowBoxWidth, 22)
forwardArrow.lineStyle(1, PRIMARY_COLOR, 1)
forwardArrow.beginFill(SECONDARY_COLOR, 1)
forwardArrow.moveTo(111, 5)
forwardArrow.lineTo(122, 11)
forwardArrow.lineTo(111, 17)
forwardArrow.lineTo(111, 5)
forwardArrow.endFill()
selectBox.addChild(forwardArrow)

View File

@@ -1,3 +1,5 @@
import {SECONDARY_COLOR} from './colors.js'
const PIXI = require('pixi.js')
export default class Tooltip extends PIXI.Graphics {
@@ -17,8 +19,8 @@ export default class Tooltip extends PIXI.Graphics {
draw () {
this.clear()
this.lineStyle(2, 0x333333, 0.8)
this.beginFill(0x333333, 0.8)
this.lineStyle(2, SECONDARY_COLOR, 0.8)
this.beginFill(SECONDARY_COLOR, 0.8)
this.drawRect(0, 0, this.text.width + 8, this.text.height + 8)
this.endFill()
}