mirror of
https://github.com/zaphar/Heracles.git
synced 2025-07-23 12:39:50 -04:00
dev: Encapsulate the graphing bits in a web component
This commit is contained in:
parent
08267f7727
commit
9e52ac341b
@ -3,15 +3,15 @@
|
|||||||
graphs:
|
graphs:
|
||||||
- title: Node cpu
|
- title: Node cpu
|
||||||
source: http://heimdall:9001
|
source: http://heimdall:9001
|
||||||
query: 'node_cpu_seconds_total{job="nodestats"}'
|
query: 'sum by (instance)(irate(node_cpu_seconds_total{mode="system",job="nodestats"}[5m])) * 100'
|
||||||
- title: Node memory
|
- title: Node memory
|
||||||
source: http://heimdall:9001
|
source: http://heimdall:9001
|
||||||
query: 'node_memory_MemFree_bytes{instance="andrew:9002",job="nodestats"}'
|
query: 'node_memory_MemFree_bytes{job="nodestats"}'
|
||||||
- title: Test Dasbboard 2
|
- title: Test Dasbboard 2
|
||||||
graphs:
|
graphs:
|
||||||
- title: Node cpu
|
- title: Node cpu
|
||||||
source: http://heimdall:9001
|
source: http://heimdall:9001
|
||||||
query: 'node_cpu_seconds_total{job="nodestats"}'
|
query: 'sum by (instance)(irate(node_cpu_seconds_total{mode="system",job="nodestats"}[5m])) * 100'
|
||||||
- title: Node memory
|
- title: Node memory
|
||||||
source: http://heimdall:9001
|
source: http://heimdall:9001
|
||||||
query: 'node_memory_MemFree_bytes{instance="andrew:9002",job="nodestats"}'
|
query: 'node_memory_MemFree_bytes{,job="nodestats"}'
|
||||||
|
@ -64,21 +64,10 @@ pub fn mk_api_routes(config: Arc<Vec<Dashboard>>) -> Router<Config> {
|
|||||||
pub fn graph_component(dash_idx: usize, graph_idx: usize, graph: &Graph) -> Markup {
|
pub fn graph_component(dash_idx: usize, graph_idx: usize, graph: &Graph) -> Markup {
|
||||||
let graph_id = format!("graph-{}-{}", dash_idx, graph_idx);
|
let graph_id = format!("graph-{}-{}", dash_idx, graph_idx);
|
||||||
let graph_data_uri = format!("/api/dash/{}/graph/{}", dash_idx, graph_idx);
|
let graph_data_uri = format!("/api/dash/{}/graph/{}", dash_idx, graph_idx);
|
||||||
// initialize the plot with Plotly.react
|
|
||||||
// Update plot with Plotly.react which is more efficient
|
|
||||||
let script = format!(
|
|
||||||
"var graph{graph_idx} = new Timeseries('{uri}', '{graph_id}'); graph{graph_idx}.updateGraph();",
|
|
||||||
uri = graph_data_uri,
|
|
||||||
graph_id = graph_id,
|
|
||||||
graph_idx = graph_idx,
|
|
||||||
);
|
|
||||||
html!(
|
html!(
|
||||||
div {
|
div {
|
||||||
h2 { (graph.title) }
|
h2 { (graph.title) }
|
||||||
script {
|
timeseries-graph uri=(graph_data_uri) id=(graph_id) { }
|
||||||
(script)
|
|
||||||
}
|
|
||||||
div id=(graph_id) { }
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -134,6 +123,9 @@ pub async fn index(State(config): State<Config>) -> Markup {
|
|||||||
script src="/js/plotly.js" { }
|
script src="/js/plotly.js" { }
|
||||||
script src="/js/htmx.js" { }
|
script src="/js/htmx.js" { }
|
||||||
script src="/js/lib.js" { }
|
script src="/js/lib.js" { }
|
||||||
|
template id="timeseries_template" {
|
||||||
|
div;
|
||||||
|
}
|
||||||
(app(State(config.clone())).await)
|
(app(State(config.clone())).await)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,59 @@
|
|||||||
|
class TimeseriesGraph extends HTMLElement {
|
||||||
class Timeseries {
|
|
||||||
#uri;
|
#uri;
|
||||||
#title;
|
#width;
|
||||||
#targetEl;
|
#height;
|
||||||
//#width;
|
constructor() {
|
||||||
//#height;
|
super();
|
||||||
|
const root = this.attachShadow({ mode: "open" });
|
||||||
|
var template = document.getElementById("timeseries_template");
|
||||||
|
this.#width = 1000;
|
||||||
|
this.height = 500;
|
||||||
|
root.appendChild(template.content.cloneNode(true));
|
||||||
|
}
|
||||||
|
|
||||||
constructor(uri, targetEl, /** width, height **/) {
|
static observedAttributes = ['uri', 'width', 'height'];
|
||||||
this.#uri = uri;
|
|
||||||
this.#targetEl = targetEl;
|
attributeChanged(name, _oldValue, newValue) {
|
||||||
//this.#width = width;
|
switch (name) {
|
||||||
//this.#height = height;
|
case 'uri':
|
||||||
|
this.#uri = newValue;
|
||||||
|
break;
|
||||||
|
case 'width':
|
||||||
|
this.#width = newValue;
|
||||||
|
break;
|
||||||
|
case 'height':
|
||||||
|
this.#height = newValue;
|
||||||
|
break;
|
||||||
|
default: // do nothing;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.updateGraph();
|
||||||
|
// TODO(zaphar): reset update timer as well
|
||||||
|
}
|
||||||
|
|
||||||
|
getTargetNode() {
|
||||||
|
console.log("shadowroot: ", this.shadowRoot);
|
||||||
|
return this.shadowRoot.firstChild;
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
// TODO(zaphar): Set up the timer loop to update graph data.
|
||||||
|
this.#uri = this.getAttribute('uri');
|
||||||
|
if (this.#uri) {
|
||||||
|
this.updateGraph();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
// TODO(zaphar): Turn off the timer loop to update graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
static elementName = "timeseries-graph";
|
||||||
|
|
||||||
|
static registerElement() {
|
||||||
|
if (!customElements.get(TimeseriesGraph.elementName)) {
|
||||||
|
customElements.define(TimeseriesGraph.elementName, TimeseriesGraph);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchData() {
|
async fetchData() {
|
||||||
@ -39,9 +82,11 @@ class Timeseries {
|
|||||||
traces.push(trace);
|
traces.push(trace);
|
||||||
}
|
}
|
||||||
console.log("Traces: ", traces);
|
console.log("Traces: ", traces);
|
||||||
Plotly.react(this.#targetEl, traces, { width: 500, height: 500 });
|
Plotly.react(this.getTargetNode(), traces, { width: this.#width, height: this.#height });
|
||||||
} else if (data.Scalar) {
|
} else if (data.Scalar) {
|
||||||
// The graph should be a single value
|
// The graph should be a single value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TimeseriesGraph.registerElement();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user