~sircmpwn/chartsrv

9d7c770fcaf4b5d3a17d9d25e0e88300c9a66630 — Drew DeVault 1 year, 9 months ago 94c6289 master
Revert "Add chart URL tool"

This was mistakenly applied twice.

This reverts commit ff0665c3d477993bf94e0d197e73e91c7d3fc103.
2 files changed, 0 insertions(+), 788 deletions(-)

D demo/base.css
D demo/index.html
D demo/base.css => demo/base.css +0 -540
@@ 1,540 0,0 @@
* {
  box-sizing: border-box; }

html {
  line-height: 1.15;
  -webkit-text-size-adjust: 100%; }

body {
  margin: 0; }

main {
  display: block; }

h1 {
  font-size: 2em;
  margin: 0.67em 0; }

hr {
  box-sizing: content-box;
  height: 0;
  overflow: visible; }

pre {
  font-family: monospace, monospace;
  font-size: 1em; }

a {
  background-color: transparent; }

abbr[title] {
  border-bottom: none;
  text-decoration: underline;
  text-decoration: underline dotted; }

b,
strong {
  font-weight: bolder; }

code,
kbd,
samp {
  font-family: monospace, monospace;
  font-size: 1em; }

small {
  font-size: 80%; }

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline; }

sub {
  bottom: -0.25em; }

sup {
  top: -0.5em; }

img {
  border-style: none; }

button,
input,
optgroup,
select,
textarea {
  font-family: inherit;
  font-size: 100%;
  line-height: 1.15;
  margin: 0; }

button,
input {
  overflow: visible; }

button,
select {
  text-transform: none; }

button,
[type="button"],
[type="reset"],
[type="submit"] {
  -webkit-appearance: button; }

button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
  border-style: none;
  padding: 0; }

button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
  outline: 1px dotted ButtonText; }

fieldset {
  padding: 0.35em 0.75em 0.625em; }

legend {
  box-sizing: border-box;
  color: inherit;
  display: table;
  max-width: 100%;
  padding: 0;
  white-space: normal; }

progress {
  vertical-align: baseline; }

textarea {
  overflow: auto; }

[type="checkbox"],
[type="radio"] {
  box-sizing: border-box;
  padding: 0; }

[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
  height: auto; }

[type="search"] {
  -webkit-appearance: textfield;
  outline-offset: -2px; }

[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none; }

::-webkit-file-upload-button {
  -webkit-appearance: button;
  font: inherit; }

details {
  display: block; }

summary {
  display: list-item; }

template {
  display: none; }

[hidden] {
  display: none; }

@media (prefers-color-scheme: dark) {
  html {
    background: #212529;
    color: #fff; } }

body {
  font-family: sans-serif;
  padding-bottom: 1rem; }

main, .main {
  max-width: 1140px;
  margin: 0 auto; }

table.grid {
  width: 100%;
  border-collapse: collapse;
  margin: 0 -1rem; }
  table.grid td {
    vertical-align: top;
    padding: 0 1rem;
    width: 8.3333333333%; }
  table.grid td[colspan="1"] {
    width: 8.3333333333%; }
  table.grid td[colspan="2"] {
    width: 16.6666666667%; }
  table.grid td[colspan="3"] {
    width: 25%; }
  table.grid td[colspan="4"] {
    width: 33.3333333333%; }
  table.grid td[colspan="5"] {
    width: 41.6666666667%; }
  table.grid td[colspan="6"] {
    width: 50%; }
  table.grid td[colspan="7"] {
    width: 58.3333333333%; }
  table.grid td[colspan="8"] {
    width: 66.6666666667%; }
  table.grid td[colspan="9"] {
    width: 75%; }
  table.grid td[colspan="10"] {
    width: 83.3333333333%; }
  table.grid td[colspan="11"] {
    width: 91.6666666667%; }
  table.grid td[colspan="12"] {
    width: 100%; }
  @supports (display: flex) {
    table.grid {
      display: flex; }
      table.grid tbody {
        display: flex;
        flex-grow: 1;
        flex-direction: column; }
      table.grid tr {
        display: flex; }
      table.grid td {
        display: block; } }

.dl, article dl {
  text-align: left;
  margin-left: 0; }

.dt, article dt {
  font-weight: normal;
  padding: 0; }

.blockquote, article blockquote {
  margin-left: -1rem;
  margin-left: calc(-4px - 1rem);
  padding-left: 1rem;
  border-left: solid 4px #ced4da; }
  @media (prefers-color-scheme: dark) {
    .blockquote, article blockquote {
      border-left: solid 4px #6c757d; } }
.figure, article figure {
  margin: 0; }
  .figure img, article figure img {
    display: block;
    max-width: 80%;
    margin: 0 auto; }
  .figure figcaption, article figure figcaption {
    display: block;
    text-align: center;
    margin: 0 auto;
    font-size: 0.9rem;
    max-width: 70%; }

.aside, article aside {
  float: right;
  max-width: 40%;
  padding-left: 1rem;
  margin-left: 1rem;
  border-left: solid 4px #ced4da; }
  @media (prefers-color-scheme: dark) {
    .aside, article aside {
      border-left: solid 4px #6c757d; } }
.pre, article pre {
  background: #e9ecef;
  margin: 0 -1rem;
  padding: 1rem; }
  @media (prefers-color-scheme: dark) {
    .pre, article pre {
      background: #131618; } }
.table, article table {
  width: 100%;
  border-collapse: collapse; }
  .table th, article table th {
    text-align: left;
    border-bottom: solid 1px #131618; }
    @media (prefers-color-scheme: dark) {
      .table th, article table th {
        border-bottom: solid 1px #fff; } }
a, .link, .tabs h1 a, .tabs h2 a, .tabs h3 a, .tabs h4 a, .tabs h5 a {
  color: #007bff; }
  a:hover, .link:hover, .tabs h1 a:hover, .tabs h2 a:hover, .tabs h3 a:hover, .tabs h4 a:hover, .tabs h5 a:hover {
    text-decoration: none; }
  a:active, .link:active, .tabs h1 a:active, .tabs h2 a:active, .tabs h3 a:active, .tabs h4 a:active, .tabs h5 a:active {
    color: #0062cc; }
  a:visited, .link:visited, .tabs h1 a:visited, .tabs h2 a:visited, .tabs h3 a:visited, .tabs h4 a:visited, .tabs h5 a:visited {
    color: #004a99; }
  @media (prefers-color-scheme: dark) {
    a, .link, .tabs h1 a, .tabs h2 a, .tabs h3 a, .tabs h4 a, .tabs h5 a {
      color: #3395ff; }
      a:active, .link:active, .tabs h1 a:active, .tabs h2 a:active, .tabs h3 a:active, .tabs h4 a:active, .tabs h5 a:active {
        color: #006fe6; }
      a:visited, .link:visited, .tabs h1 a:visited, .tabs h2 a:visited, .tabs h3 a:visited, .tabs h4 a:visited, .tabs h5 a:visited {
        color: #006fe6; } }
h1 small {
  font-size: 1.2rem; }

del {
  color: inherit; }

hr {
  border: #ced4da solid 1px; }
  @media (prefers-color-scheme: dark) {
    hr {
      border: #6c757d solid 1px; } }
.align-center {
  text-align: center; }

.align-left {
  text-align: left; }

.align-right {
  text-align: right; }

.block {
  display: block !important; }

.inline {
  display: inline !important; }

.float-left {
  float: left; }

.float-right {
  float: right; }

.text-info {
  color: #17a2b8; }

.text-success {
  color: #28a745; }

.text-danger {
  color: #dc3545; }

.text-muted, form .help, input[disabled] + label {
  color: #343a40; }
  @media (prefers-color-scheme: dark) {
    .text-muted, form .help, input[disabled] + label {
      color: #adb5bd; } }
.alert {
  padding: 0.5rem;
  border: 1px solid transparent;
  margin-bottom: 1rem; }

.alert-danger {
  background: #f8d7da;
  color: #842029;
  border-color: #f5c6cb; }

.btn, button {
  display: inline-block;
  padding: .1rem .75rem;
  background: #e9ecef;
  border: #343a40 1px solid;
  font-size: 0.9rem;
  font-weight: 400;
  line-height: 1.5;
  cursor: pointer;
  color: #131618;
  border-radius: 0;
  transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; }
  .btn:hover, button:hover {
    text-decoration: none;
    background: #f8f9fa;
    color: #131618; }
  @media (prefers-color-scheme: dark) {
    .btn, button {
      background: #212529;
      color: #fff;
      border: #495057 1px solid; }
      .btn:hover, button:hover {
        background: #131618;
        color: #fff; } }
.btn-primary {
  border: #001933 1px solid;
  background: #007bff;
  color: #fff; }
  .btn-primary:hover {
    background: #0069d9;
    color: #fff; }
  @media (prefers-color-scheme: dark) {
    .btn-primary {
      background: #0062cc;
      color: #fff;
      border: #001933 1px solid; }
      .btn-primary:hover {
        background: #0069d9;
        color: #fff; } }
a.btn {
  text-decoration: none;
  color: #131618; }
  @media (prefers-color-scheme: dark) {
    a.btn {
      color: #fff; } }
a.btn-primary {
  color: #fff; }
  @media (prefers-color-scheme: dark) {
    a.btn-primary {
      color: #fff; } }
.btn.block, button.block {
  margin-bottom: 0.5rem; }

.form-field, .form-checkbox {
  margin-top: 1rem; }

label {
  display: block; }

input, textarea, select {
  display: block;
  width: 100%;
  border: 1px solid #888;
  padding: .375rem;
  font-size: 1rem;
  line-height: 1.5;
  background-color: #fff;
  background-clip: padding-box;
  transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
  border-radius: 0; }
  input:focus, textarea:focus, select:focus {
    outline: 0;
    border-color: #80bdff;
    box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); }
  @media (prefers-color-scheme: dark) {
    input, textarea, select {
      background: #131618;
      color: #fff;
      border-color: #6c757d; }
      input:active, input:focus, textarea:active, textarea:focus, select:active, select:focus {
        background: #212529;
        color: #fff; }
      input[disabled], input[readonly], textarea[disabled], textarea[readonly], select[disabled], select[readonly] {
        background: #212529;
        color: #ced4da; } }
.has-error input, .has-error textarea, .has-error select {
  border-color: #dc3545; }

.has-error .error {
  color: #dc3545; }

tr:first-child td .form-field:first-child {
  margin-top: 0; }

button {
  display: block; }

button.block {
  width: 100%; }

.form-checkbox input[type="checkbox"],
.form-checkbox input[type="radio"] {
  float: left;
  width: 1em;
  height: 1em;
  margin-top: 0.1rem;
  margin-right: 0.25rem;
  vertical-align: top; }

.form-checkbox label {
  display: inline-block; }

.form-checkbox.inline {
  display: inline-block !important;
  margin-right: 1rem; }

fieldset {
  border: none;
  padding: 0;
  margin-top: 1rem; }

.inset, .infobox {
  background: #f8f9fa;
  padding: 1rem; }
  @media (prefers-color-scheme: dark) {
    .inset, .infobox {
      background: #131618; } }
.infobox header {
  margin-bottom: 1rem; }

.infobox :not(header) {
  margin: 0; }

nav, .nav {
  max-width: 1140px;
  margin: 1rem auto; }
  nav ul, .nav ul {
    display: inline;
    margin: 0 -0.5rem;
    padding-left: 0; }
  nav li, .nav li {
    display: inline;
    margin: 0 0.5rem; }
  nav a, nav a:visited, .nav a, .nav a:visited {
    color: #131618; }
    @media (prefers-color-scheme: dark) {
      nav a, nav a:visited, .nav a, .nav a:visited {
        color: #fff; } }
  nav .active a, nav .active a:visited, .nav .active a, .nav .active a:visited {
    color: #007bff; }
    @media (prefers-color-scheme: dark) {
      nav .active a, nav .active a:visited, .nav .active a, .nav .active a:visited {
        color: #3395ff; } }
  nav .brand a, .nav .brand a {
    text-decoration: none; }
  nav .right, .nav .right {
    float: right; }

.tabs:not(.tabs-aside) {
  border-bottom: solid 3px #ced4da; }
  @media (prefers-color-scheme: dark) {
    .tabs:not(.tabs-aside) {
      border-bottom: solid 3px #131618; } }
.tabs nav {
  margin: 0 auto;
  position: relative; }

.tabs h1, .tabs h2, .tabs h3, .tabs h4, .tabs h5 {
  display: inline;
  margin-right: 1rem;
  font-weight: normal; }

.tabs ul {
  display: inline;
  margin: 0 -0.5rem;
  padding-left: 0;
  position: absolute;
  bottom: 0; }

.tabs li {
  display: inline;
  margin: 0; }
  .tabs li a {
    padding: 0 1rem; }
  .tabs li.active, .tabs li:hover {
    background: #ced4da; }
    @media (prefers-color-scheme: dark) {
      .tabs li.active, .tabs li:hover {
        background: #131618; } }
    .tabs li.active a, .tabs li:hover a {
      color: #131618; }
      @media (prefers-color-scheme: dark) {
        .tabs li.active a, .tabs li:hover a {
          color: #fff; } }
.tabs a {
  text-decoration: none; }

.tabs aside {
  background: #ced4da;
  padding: 0.2rem 0; }
  @media (prefers-color-scheme: dark) {
    .tabs aside {
      background: #131618; } }
  .tabs aside p {
    margin: 0 auto;
    max-width: 1140px; }

header + main {
  margin-top: 1rem; }

D demo/index.html => demo/index.html +0 -248
@@ 1,248 0,0 @@
<!doctype html>
<html lang="en">
<meta charset="utf-8" />
<title>Chartsrv</title>
<link rel="stylesheet" href="base.css" />
<style>
  #preview, #alert { max-width: 100%; margin-top: 0.25em; }
</style>
<main>
  <form>
    <table class="grid">
      <tr>
        <td colspan="2"></td>
        <td colspan="10">
          <h1>Chartsrv</h1>
          <p>
            Web service which renders SVG plots from Prometheus data.
            <a href="https://sr.ht/~sircmpwn/chartsrv/">See on SourceHut.</a>
          </p>
          <noscript>
            <p class="text-danger">Please enable JavaScript to use this tool.</p>
          </noscript>
        </td>
        <td colspan="2"></td>
      </tr>
      <tr>
        <td colspan="3"></td>
        <td colspan="4">
          <div class="form-field">
            <label for="instance">
              Chartsrv instance <span class="text-danger">*</span>
            </label>
            <input type="text" id="instance" placeholder="metrics.sr.ht:8142"
              value="metrics.sr.ht:8142" />
          </div>
        </td>
        <td colspan="2">
          <div class="form-field">
            <label for="format">Format</label>
            <select id="format">
              <option>svg</option>
              <option>png</option>
            </select>
          </div>
        </td>
        <td colspan="3"></td>
      </tr>
      <tr>
        <td colspan="3"></td>
        <td colspan="6">
          <div class="form-field">
            <label for="query">Query <span class="text-danger">*</span></label>
            <input type="text" id="query"
              value="avg_over_time(node_load15[1h])" />
          </div>
          <div class="form-checkbox">
            <input type="checkbox" id="stacked" />
            <label for="stacked" class="checkbox">Stacked</label>
          </div>
        </td>
        <td colspan="3"></td>
      </tr>
      <tr>
        <td colspan="3"></td>
        <td colspan="2">
          <div class="form-field">
            <label for="since">Time from</label>
            <input type="text" id="since" placeholder="24h" />
          </div>
        </td>
        <td colspan="2">
          <div class="form-field">
            <label for="until">Time to</label>
            <input type="text" id="until" />
          </div>
        </td>
        <td colspan="2">
          <div class="form-field">
            <label for="step">Step</label>
            <input type="number" id="step" />
          </div>
        </td>
        <td colspan="3"></td>
      </tr>
      <tr>
        <td colspan="3"></td>
        <td colspan="6">
          <span class="help">
            Time fields are relative to present and use
            <a href="https://godocs.io/time#ParseDuration">duration strings</a>.
            <em>Step</em> is in seconds.
          </span>
        </td>
        <td colspan="3"></td>
      </tr>
      <tr>
        <td colspan="3"></td>
        <td colspan="3">
          <div class="form-field">
            <label for="min">Y min</label>
            <input type="number" id="min" />
          </div>
        </td>
        <td colspan="3">
          <div class="form-field">
            <label for="max">Y max</label>
            <input type="number" id="max" />
          </div>
        </td>
        <td colspan="3"></td>
      </tr>
      <tr>
        <td colspan="3"></td>
        <td colspan="3">
          <div class="form-field">
            <label for="title">Title</label>
            <input type="text" id="title" />
          </div>
        </td>
        <td colspan="3">
          <div class="form-field">
            <label for="label">Label</label>
            <input type="text" id="label" placeholder="{{.instance}}"
              value="{{.instance}}" />
          </div>
        </td>
        <td colspan="3"></td>
      </tr>
      <tr>
        <td colspan="3"></td>
        <td colspan="6">
          <span class="help">
            <em>Label</em> accepts a
            <a href="https://godocs.io/text/template">template</a>.
            All Prometheus labels are available.
          </span>
        </td>
        <td colspan="3"></td>
      </tr>
      <tr>
        <td colspan="3"></td>
        <td colspan="3">
          <div class="form-field">
            <label for="width">Width</label>
            <input type="number" id="width" min="0" placeholder="12" />
          </div>
        </td>
        <td colspan="3">
          <div class="form-field">
            <label for="height">Height</label>
            <input type="number" id="height" min="0" placeholder="6" />
          </div>
        </td>
        <td colspan="3"></td>
      </tr>
      <tr>
        <td colspan="3"></td>
        <td colspan="6">
          <span class="help">
            Dimensions are in inches. DPI is fixed at 96.
          </span>
        </td>
        <td colspan="3"></td>
      </tr>
      <tr>
        <td colspan="3"></td>
        <td colspan="6">
          <div class="form-field">
            <label for="url">Chart URL</label>
            <input type="text" id="url" disabled />
          </div>
        </td>
        <td colspan="3"></td>
      </tr>
      <tr>
        <td colspan="3"></td>
        <td colspan="6">
          <div class="form-field">
            <label for="preview">Chart preview</label>
            <div id="alert" class="alert alert-danger" style="display: none">
              Loading preview failed. Are the parameters correct?
            </div>
            <img id="preview" alt="" />
          </div>
        </td>
        <td colspan="3"></td>
      </tr>
   </table>
  </form>
</main>

<script>
  function getValue(id) {
    var el = document.getElementById(id);

    if (el.type === "checkbox") {
      return el.checked ? id : "";
    }

    return el.value;
  }

  function updateChart() {
    var src = getValue("instance");

    if (!/^[a-z]+\:\/{2}/.test(src)) {
        src = "http://" + src;
    }
    if (src[src.length - 1] !== "/") { src += "/"; }

    src += "chart." + getValue("format") + "?";

    var params = ["query", "title", "stacked", "since", "until", "width",
        "height", "step", "min", "max", "label"];
    var first = true;
    for (var i = 0; i < params.length; ++i) {
      var value = getValue(params[i]);
      if (value !== "") {
        if (!first) { src += "&"; }
        first = false;

        src += params[i] + "=" + encodeURIComponent(getValue(params[i]));
      }
    }

    document.getElementById("url").value = src;
    document.getElementById("preview").src = src;
  }

  function showAlert() {
    document.getElementById("alert").style.display = "";
  }

  function hideAlert() {
    document.getElementById("alert").style.display = "none";
  }

  var inputs = document.getElementsByTagName("input");
  for (var i = 0; i < inputs.length; ++i) {
    inputs[i].onchange = updateChart;
  }
  document.getElementById("format").onchange = updateChart;

  document.getElementById("preview").onerror = showAlert;
  document.getElementById("preview").onload = hideAlert;

  updateChart();
</script>