Skip to content

Commit

Permalink
Merge pull request #17691 from hashicorp/f/missing-chart-stories
Browse files Browse the repository at this point in the history
[UI] Missing chart stories
  • Loading branch information
DingoEatingFuzz authored Jun 23, 2023
2 parents ced6c58 + 2e2e396 commit ed51605
Show file tree
Hide file tree
Showing 2 changed files with 311 additions and 0 deletions.
116 changes: 116 additions & 0 deletions ui/stories/charts/recommendation-chart.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/

import hbs from 'htmlbars-inline-precompile';
import DelayedTruth from '../utils/delayed-truth';
import {
withKnobs,
optionsKnob,
number,
boolean,
} from '@storybook/addon-knobs';

export default {
title: 'Charts/Recomendation Chart',
decorators: [withKnobs],
};

export let Configurable = () => {
return {
template: hbs`
<SvgPatterns />
{{#if delayedTruth.complete}}
<Das::RecommendationChart
@resource={{resource}}
@currentValue={{current}}
@recommendedValue={{recommendedValue}}
@stats={{stats}}
@disabled={{disabled}}
/>
{{/if}}
`,
context: contextFactory(),
};
};

export let Standard = () => {
return {
template: hbs`
<SvgPatterns />
<div style="max-width: 500px">
{{#if delayedTruth.complete}}
<Das::RecommendationChart
@resource="CPU"
@currentValue={{cpu.current}}
@recommendedValue={{cpu.recommendedValue}}
@stats={{cpu.stats}}
/>
<Das::RecommendationChart
@resource="MemoryMB"
@currentValue={{mem.current}}
@recommendedValue={{mem.recommendedValue}}
@stats={{mem.stats}}
/>
<hr/>
<Das::RecommendationChart
@resource="CPU"
@currentValue={{cpu.current}}
@recommendedValue={{cpu.recommendedValue}}
@stats={{cpu.stats}}
@disabled={{true}}
/>
<Das::RecommendationChart
@resource="MemoryMB"
@currentValue={{mem.current}}
@recommendedValue={{mem.recommendedValue}}
@stats={{mem.stats}}
/>
{{/if}}
</div>
`,
context: {
delayedTruth: DelayedTruth.create(),
cpu: {
current: 100,
recommendedValue: 600,
stats: {
mean: 300,
p99: 500,
max: 525,
},
},
mem: {
current: 2048,
recommendedValue: 256,
stats: {
mean: 140,
p99: 215,
max: 225,
},
},
},
};
};

function contextFactory() {
const numberConfig = { range: true, min: 0, max: 1000, step: 1 };
return {
delayedTruth: DelayedTruth.create(),
resource: optionsKnob(
'Resource',
{ Cpu: 'CPU', Memory: 'MemoryMB' },
'CPU',
{ display: 'inline-radio' }
),
current: number('Current', 100, numberConfig),
recommendedValue: number('Recommendation', 300, numberConfig),
stats: {
mean: number('Stat: mean', 150, numberConfig),
p99: number('Stat: p99', 600, numberConfig),
max: number('Stat: max', 650, numberConfig),
},
disabled: boolean('Disabled', false),
};
}
195 changes: 195 additions & 0 deletions ui/stories/charts/topo-viz.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/

import hbs from 'htmlbars-inline-precompile';
import DelayedTruth from '../utils/delayed-truth';
import { withKnobs, boolean } from '@storybook/addon-knobs';
import { getOwner } from '@ember/application';
import { tracked } from '@glimmer/tracking';
import { scaleLinear } from 'd3-scale';
import faker from 'faker';

export default {
title: 'Charts/Topo Viz',
decorators: [withKnobs],
};

const nodeGen = (name, datacenter, memory, cpu, allocations = []) => ({
datacenter,
memory,
cpu,
node: { name, isEligible: true, isDraining: false },
allocations: allocations.map((alloc) => ({
memory: alloc.memory,
cpu: alloc.cpu,
memoryPercent: alloc.memory / memory,
cpuPercent: alloc.cpu / cpu,
allocation: {
id: faker.random.uuid(),
isScheduled: true,
clientStatus: alloc.clientStatus,
},
})),
});

const nodeModelGen = (datacenter, id, name, resources = '2000/1000') => {
const [cpu, memory] = resources.split('/');
return {
datacenter,
id,
name,
isEligible: true,
isDraining: false,
resources: { cpu, memory },
};
};

const allocModelGen = (
id,
taskGroupName,
clientStatus,
nodeId,
jobId,
resources = '100/100'
) => {
const [cpu, memory] = resources.split('/');
return {
id,
taskGroupName,
clientStatus,
isScheduled: true,
allocatedResources: { cpu, memory },
belongsTo(t) {
return {
id() {
return t === 'node' ? nodeId : jobId;
},
};
},
};
};

export let Node = () => ({
template: hbs`
<SvgPatterns />
{{#if delayedTruth.complete}}
<TopoViz::Node
@node={{node}}
@isDense={{isDense}}
@heightScale={{heightScale}}
/>
{{/if}}
`,
context: {
delayedTruth: DelayedTruth.create(),
isDense: boolean('isDense', false),
heightScale: scaleLinear().range([15, 40]).domain([100, 1000]),
node: nodeGen('Node One', 'dc1', 1000, 1000, [
{ memory: 100, cpu: 100, clientStatus: 'pending' },
{ memory: 250, cpu: 300, clientStatus: 'running' },
{ memory: 300, cpu: 200, clientStatus: 'running' },
]),
},
});

export let Datacenter = () => ({
template: hbs`
<SvgPatterns />
{{#if delayedTruth.complete}}
<TopoViz::Datacenter
@datacenter={{dc}}
@isSingleColumn={{isSingleColumn}}
@isDense={{isDense}}
@heightScale={{heightScale}}
/>
{{/if}}
`,
context: {
delayedTruth: DelayedTruth.create(),
isSingleColumn: boolean('isSingleColumn', false),
isDense: boolean('isDense', false),
heightScale: scaleLinear().range([15, 40]).domain([100, 1000]),
dc: {
name: 'dc1',
nodes: [
nodeGen('Node One', 'dc1', 1000, 1000, [
{ memory: 100, cpu: 100, clientStatus: 'pending' },
{ memory: 250, cpu: 300, clientStatus: 'running' },
{ memory: 300, cpu: 200, clientStatus: 'running' },
]),
nodeGen('And Two', 'dc1', 500, 1000, [
{ memory: 100, cpu: 100, clientStatus: 'pending' },
{ memory: 250, cpu: 300, clientStatus: 'running' },
{ memory: 100, cpu: 100, clientStatus: 'running' },
{ memory: 100, cpu: 100, clientStatus: 'running' },
{ memory: 100, cpu: 100, clientStatus: 'running' },
]),
nodeGen('Three', 'dc1', 500, 500, [
{ memory: 100, cpu: 300, clientStatus: 'running' },
{ memory: 300, cpu: 200, clientStatus: 'pending' },
]),
],
},
},
});

export let FullViz = () => ({
template: hbs`
{{#if delayedTruth.complete}}
<TopoViz
@nodes={{nodes}}
@allocations={{allocations}}
/>
{{/if}}
`,
context: {
delayedTruth: DelayedTruth.create(),
nodes: [
nodeModelGen('dc1', '1', 'pdx-1', '2000/1000'),
nodeModelGen('dc1', '2', 'pdx-2', '2000/1000'),
nodeModelGen('dc1', '3', 'pdx-3', '2000/3000'),
nodeModelGen('dc2', '4', 'yyz-1', '2000/1000'),
nodeModelGen('dc2', '5', 'yyz-2', '2000/2000'),
],
allocations: [
allocModelGen('1', 'name', 'running', '1', 'job-1', '200/500'),
allocModelGen('1', 'name', 'running', '5', 'job-1', '200/500'),
],
},
});

export let EmberData = () => ({
template: hbs`
<div class="notification is-info">
<h3 class='title is-4'>This visualization uses data from mirage.</h3>
<p>Change the mirage scenario to see different cluster states visualized.</p>
</div>
{{#if (and delayedTruth.complete nodes allocations)}}
<TopoViz
@nodes={{nodes}}
@allocations={{allocations}}
/>
{{/if}}
`,
context: {
delayedTruth: DelayedTruth.create(),
nodes: tracked([]),
allocations: tracked([]),

async init() {
this._super(...arguments);

const owner = getOwner(this);
const store = owner.lookup('service:store');

this.nodes = await store.query('node', { resources: true });
this.allocations = await store.query('allocation', {
resources: true,
task_states: false,
namespace: '*',
});
},
},
});

0 comments on commit ed51605

Please sign in to comment.