mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-26 05:19:05 +01:00
Improve Histogram.svelte
- Add bold axis labels - Labels defined as element props xlabel and ylabel - Label offset dynamic to plot height (10 percent) - Add adjustable gaps between bars
This commit is contained in:
parent
46baa6e534
commit
d1c47f4359
@ -152,7 +152,8 @@
|
||||
<Histogram
|
||||
width={colWidth1 - 25} height={300}
|
||||
data={$mainQuery.data.topUsers.sort((a, b) => b.count - a.count).map(({ count }, idx) => ({ count, value: idx }))}
|
||||
label={(x) => x < $mainQuery.data.topUsers.length ? $mainQuery.data.topUsers[Math.floor(x)].name : '0'} />
|
||||
label={(x) => x < $mainQuery.data.topUsers.length ? $mainQuery.data.topUsers[Math.floor(x)].name : '0'}
|
||||
xlabel="User Name" ylabel="Number of Jobs" />
|
||||
{/key}
|
||||
</div>
|
||||
</Col>
|
||||
@ -173,7 +174,8 @@
|
||||
<Histogram
|
||||
width={colWidth1 - 25} height={300}
|
||||
data={$mainQuery.data.topProjects.sort((a, b) => b.count - a.count).map(({ count }, idx) => ({ count, value: idx }))}
|
||||
label={(x) => x < $mainQuery.data.topProjects.length ? $mainQuery.data.topProjects[Math.floor(x)].name : '0'} />
|
||||
label={(x) => x < $mainQuery.data.topProjects.length ? $mainQuery.data.topProjects[Math.floor(x)].name : '0'}
|
||||
xlabel="Project Code" ylabel="Number of Jobs" />
|
||||
{/key}
|
||||
</Col>
|
||||
<Col class="px-4 py-2">
|
||||
@ -192,7 +194,8 @@
|
||||
{#key $mainQuery.data.stats}
|
||||
<Histogram
|
||||
width={colWidth2 - 25} height={300}
|
||||
data={$mainQuery.data.stats[0].histDuration} />
|
||||
data={$mainQuery.data.stats[0].histDuration}
|
||||
xlabel="Current Runtime in Hours [h]" ylabel="Number of Jobs" />
|
||||
{/key}
|
||||
</div>
|
||||
</Col>
|
||||
@ -201,7 +204,8 @@
|
||||
{#key $mainQuery.data.stats}
|
||||
<Histogram
|
||||
width={colWidth2 - 25} height={300}
|
||||
data={$mainQuery.data.stats[0].histNumNodes} />
|
||||
data={$mainQuery.data.stats[0].histNumNodes}
|
||||
xlabel="Allocated Nodes" ylabel="Number of Jobs" />
|
||||
{/key}
|
||||
</Col>
|
||||
</Row>
|
||||
|
@ -20,6 +20,8 @@
|
||||
export let data
|
||||
export let width
|
||||
export let height
|
||||
export let xlabel
|
||||
export let ylabel
|
||||
export let min = null
|
||||
export let max = null
|
||||
export let label = formatNumber
|
||||
@ -72,9 +74,11 @@
|
||||
}
|
||||
|
||||
function render() {
|
||||
const h = height - paddingTop - paddingBottom
|
||||
const labelOffset = Math.floor(height * 0.1)
|
||||
const h = height - paddingTop - paddingBottom - labelOffset
|
||||
const w = width - paddingLeft - paddingRight
|
||||
const barWidth = Math.ceil(w / (maxValue + 1))
|
||||
const barGap = 5
|
||||
const barWidth = Math.ceil(w / (maxValue + 1)) - barGap
|
||||
|
||||
if (Number.isNaN(barWidth))
|
||||
return
|
||||
@ -83,9 +87,14 @@
|
||||
const getCanvasY = (count) => (h - (count / maxCount) * h) + paddingTop
|
||||
|
||||
// X Axis
|
||||
ctx.font = `${fontSize}px ${fontFamily}`
|
||||
ctx.font = `bold ${fontSize}px ${fontFamily}`
|
||||
ctx.fillStyle = 'black'
|
||||
if (xlabel != '') {
|
||||
let textWidth = ctx.measureText(xlabel).width
|
||||
ctx.fillText(xlabel, Math.floor((width / 2) - (textWidth / 2) + barGap), height - Math.floor(labelOffset / 2))
|
||||
}
|
||||
ctx.textAlign = 'center'
|
||||
ctx.font = `${fontSize}px ${fontFamily}`
|
||||
if (min != null && max != null) {
|
||||
const stepsizeX = getStepSize(max - min, w, 75)
|
||||
let startX = 0
|
||||
@ -94,19 +103,28 @@
|
||||
|
||||
for (let x = startX; x < max; x += stepsizeX) {
|
||||
let px = ((x - min) / (max - min)) * (w - barWidth) + paddingLeft + (barWidth / 2.)
|
||||
ctx.fillText(`${formatNumber(x)}`, px, height - paddingBottom + 15)
|
||||
ctx.fillText(`${formatNumber(x)}`, px, height - paddingBottom - Math.floor(labelOffset / 2))
|
||||
}
|
||||
} else {
|
||||
const stepsizeX = getStepSize(maxValue, w, 120)
|
||||
for (let x = 0; x <= maxValue; x += stepsizeX) {
|
||||
ctx.fillText(label(x), getCanvasX(x), height - paddingBottom + 15)
|
||||
ctx.fillText(label(x), getCanvasX(x), height - paddingBottom - Math.floor(labelOffset / 2))
|
||||
}
|
||||
}
|
||||
|
||||
// Y Axis
|
||||
ctx.fillStyle = 'black'
|
||||
ctx.strokeStyle = '#bbbbbb'
|
||||
ctx.font = `bold ${fontSize}px ${fontFamily}`
|
||||
if (ylabel != '') {
|
||||
ctx.save()
|
||||
ctx.translate(15, Math.floor(h / 2))
|
||||
ctx.rotate(-Math.PI / 2)
|
||||
ctx.fillText(ylabel, 0, 0)
|
||||
ctx.restore()
|
||||
}
|
||||
ctx.textAlign = 'right'
|
||||
ctx.font = `${fontSize}px ${fontFamily}`
|
||||
ctx.beginPath()
|
||||
const stepsizeY = getStepSize(maxCount, h, 50)
|
||||
for (let y = stepsizeY; y <= maxCount; y += stepsizeY) {
|
||||
@ -130,10 +148,10 @@
|
||||
// Fat lines left and below plotting area
|
||||
ctx.strokeStyle = 'black'
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(0, height - paddingBottom)
|
||||
ctx.lineTo(width, height - paddingBottom)
|
||||
ctx.moveTo(0, height - paddingBottom - labelOffset)
|
||||
ctx.lineTo(width, height - paddingBottom - labelOffset)
|
||||
ctx.moveTo(paddingLeft, 0)
|
||||
ctx.lineTo(paddingLeft, height- paddingBottom)
|
||||
ctx.lineTo(paddingLeft, height - Math.floor(labelOffset / 2))
|
||||
ctx.stroke()
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user