Public
Edited
Jan 2, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
const definition = chartDefinition(panel, 3);
definition.data = data;
return definition;
}
Insert cell
randomize = {
button;
mutable initializer = randomValues(3);
}
Insert cell
function chartDefinition(panel, numberOfSeries) {

const definition = {
title: panel.title,
format: panel.format,
legendValues: panel.legendValues,
series: []
}

if (panel.yMin) {
definition.yMin = panel.yMinValue;
}
if (panel.yMax) {
definition.yMax = panel.yMaxValue;
}

let cnt = 0;

for (let i=1; i<=numberOfSeries; i++) {

const prefix = `s${i}-`;

if (panel[prefix + "metric"] !== "disabled") {

definition.series.push(
{
label: panel[prefix + "label"],
metric: panel[prefix + "metric"],
legend: panel[prefix + "legend"],
tooltip: panel[prefix + "tooltip"],
negativeY: panel[prefix + "negativeY"]
}
);

if (panel[prefix + "line"]) {
definition.series[cnt].lineColor = panel[prefix + "lineColor"]
+ panel[prefix + "lineAlpha"].toString(16).padStart(2, "0");
}

if (panel[prefix + "fill"] !== "disabled") {

definition.series[cnt].fillColor = panel[prefix + "fillColor"]
+ panel[prefix + "fillAlpha"].toString(16).padStart(2, "0");

if (panel[prefix + "fill"] === "zero") {
definition.series[cnt].fillToZero = true;
}
else if (panel[prefix + "fill"] !== "bottom") {
definition.series[cnt].fillToMetric = panel[prefix + "fill"];
}

}

cnt++;

}

}

return definition;

}
Insert cell
function randomValues(numberOfSeries) {
const values = {};

for (const option of ["yMin", "yMax"]) {
values[option] = roll(0, 1) === 1 ? "checked" : "";
}

values["yMinValue"] = roll(0, 8) * 10 - 60;
values["yMaxValue"] = roll(0, 8) * 10 + 40;

const selectElements = [];
for (let i=1; i<=numberOfSeries; i++) {

const prefix = `s${i}-`;

for (const option of ["line", "negativeY"]) {
values[prefix + option] = roll(0, 1) === 1 ? "checked" : "";
}

selectElements.push([prefix + "metric", 5, roll(1, 5)]);
selectElements.push([prefix + "fill", 7, roll(1, 7)]);

values[prefix + "lineColor"] = randomColor();
values[prefix + "lineAlpha"] = roll(30, 255);
values[prefix + "fillColor"] = randomColor();
values[prefix + "fillAlpha"] = roll(30, 255);

}

return Object.assign(values, ...selectElements.map(v => selectOptions(...v)));

}
Insert cell
function roll(from, to) {
return Math.floor(Math.random() * (to - from + 1)) + from;
}
Insert cell
function randomColor() {
let color = "#";
for (let i=0; i<3; i++) {
color += roll(0, 255).toString(16).padStart(2, "0");
}
return color;
}
Insert cell
function selectOptions(id, maxIndex, selectedIndex) {
const options = {};
for (let i=0; i<=maxIndex; i++) {
options[`${id}-${i}`] = i === selectedIndex ? "selected" : "";
}
return options;
}
Insert cell
import {form} from "@mbostock/form-input"
Insert cell
import {TimeSeriesChart} from "@geofduf/simple-dashboard-line-charts"
Insert cell
Insert cell
Insert cell
controlPanelStyling = html`
<style>
.cp-row {
display: flex;
justify-content: start;
flex-wrap: wrap;
font-family: monospace;
font-size: 11px;
}
.cp-group {
width: 300px;
padding-right: 40px;
padding-bottom: 20px;
}
.cp-title {
text-decoration: underline;
font-weight: bold;
padding-top: 5px;
}
.cp-input {
display: flex;
justify-content: space-between;
padding-top: 5px;
}
.cp-complex {
display: flex;
align-items: center;
}
.cp-input select {
font-family: monospace;
font-size: 11px;
width: 80px;
}
.cp-input input[type=text] {
font-family: monospace;
font-size: 11px;
width: 180px;
}
.cp-input input[type=range] {
width: 60px;
}
.cp-input input[type=color] {
margin-left: 5px;
margin-right: 2px;
width: 30px;
}
</style>
`
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more