mirror of
				https://github.com/ClusterCockpit/cc-backend
				synced 2025-11-04 01:25:06 +01:00 
			
		
		
		
	Merge pull request #324 from ClusterCockpit/317_add_colorblindmode
add colorblind setting
This commit is contained in:
		web/frontend/src
@@ -18,6 +18,7 @@
 | 
				
			|||||||
  const ccconfig = getContext("cc-config");
 | 
					  const ccconfig = getContext("cc-config");
 | 
				
			||||||
  let message = { msg: "", target: "", color: "#d63384" };
 | 
					  let message = { msg: "", target: "", color: "#d63384" };
 | 
				
			||||||
  let displayMessage = false;
 | 
					  let displayMessage = false;
 | 
				
			||||||
 | 
					  let cbmode = ccconfig?.plot_general_colorblindMode || false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async function handleSettingSubmit(event) {
 | 
					  async function handleSettingSubmit(event) {
 | 
				
			||||||
    const selector = event.detail.selector
 | 
					    const selector = event.detail.selector
 | 
				
			||||||
@@ -28,6 +29,9 @@
 | 
				
			|||||||
      const res = await fetch(form.action, { method: "POST", body: formData });
 | 
					      const res = await fetch(form.action, { method: "POST", body: formData });
 | 
				
			||||||
      if (res.ok) {
 | 
					      if (res.ok) {
 | 
				
			||||||
        let text = await res.text();
 | 
					        let text = await res.text();
 | 
				
			||||||
 | 
					        if (formData.get("key") === "plot_general_colorblindMode") {
 | 
				
			||||||
 | 
					          cbmode = JSON.parse(formData.get("value"));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        popMessage(text, target, "#048109");
 | 
					        popMessage(text, target, "#048109");
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        let text = await res.text();
 | 
					        let text = await res.text();
 | 
				
			||||||
@@ -51,4 +55,4 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<UserOptions config={ccconfig} {username} {isApi} bind:message bind:displayMessage on:update-config={(e) => handleSettingSubmit(e)}/>
 | 
					<UserOptions config={ccconfig} {username} {isApi} bind:message bind:displayMessage on:update-config={(e) => handleSettingSubmit(e)}/>
 | 
				
			||||||
<PlotRenderOptions config={ccconfig} bind:message bind:displayMessage on:update-config={(e) => handleSettingSubmit(e)}/>
 | 
					<PlotRenderOptions config={ccconfig} bind:message bind:displayMessage on:update-config={(e) => handleSettingSubmit(e)}/>
 | 
				
			||||||
<PlotColorScheme config={ccconfig} bind:message bind:displayMessage on:update-config={(e) => handleSettingSubmit(e)}/>
 | 
					<PlotColorScheme config={ccconfig} bind:cbmode bind:message bind:displayMessage on:update-config={(e) => handleSettingSubmit(e)}/>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,7 @@
 | 
				
			|||||||
    export let config;
 | 
					    export let config;
 | 
				
			||||||
    export let message;
 | 
					    export let message;
 | 
				
			||||||
    export let displayMessage;
 | 
					    export let displayMessage;
 | 
				
			||||||
 | 
					    export let cbmode = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const dispatch = createEventDispatcher();
 | 
					    const dispatch = createEventDispatcher();
 | 
				
			||||||
    function updateSetting(selector, target) {
 | 
					    function updateSetting(selector, target) {
 | 
				
			||||||
@@ -265,6 +266,62 @@
 | 
				
			|||||||
      ],
 | 
					      ],
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // https://personal.sron.nl/~pault/
 | 
				
			||||||
 | 
					    // https://tsitsul.in/blog/coloropt/
 | 
				
			||||||
 | 
					    const cvdschemes = {
 | 
				
			||||||
 | 
					      HighContrast: [
 | 
				
			||||||
 | 
					        "rgb(221,170,51)",
 | 
				
			||||||
 | 
					        "rgb(187,85,102)",
 | 
				
			||||||
 | 
					        "rgb(0,68,136)",
 | 
				
			||||||
 | 
					        "rgb(0,0,0)",
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      Bright: [
 | 
				
			||||||
 | 
					        "rgb(68,119,170)",
 | 
				
			||||||
 | 
					        "rgb(102,204,238)",
 | 
				
			||||||
 | 
					        "rgb(34,136,51)",
 | 
				
			||||||
 | 
					        "rgb(204,187,68)",
 | 
				
			||||||
 | 
					        "rgb(238,102,119)",
 | 
				
			||||||
 | 
					        "rgb(170,51,119)",
 | 
				
			||||||
 | 
					        "rgb(187,187,187)",
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      Muted: [
 | 
				
			||||||
 | 
					        "rgb(51,34,136)",
 | 
				
			||||||
 | 
					        "rgb(136,204,238)",
 | 
				
			||||||
 | 
					        "rgb(68,170,153)",
 | 
				
			||||||
 | 
					        "rgb(17,119,51)",
 | 
				
			||||||
 | 
					        "rgb(153,153,51)",
 | 
				
			||||||
 | 
					        "rgb(221,204,119)",
 | 
				
			||||||
 | 
					        "rgb(204,102,119)",
 | 
				
			||||||
 | 
					        "rgb(136,34,85)",
 | 
				
			||||||
 | 
					        "rgb(170,68,153)",
 | 
				
			||||||
 | 
					        "rgb(221,221,221)",
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      NormalSixColor: [
 | 
				
			||||||
 | 
					        "rgb(64,83,211)",
 | 
				
			||||||
 | 
					        "rgb(221,179,16)",
 | 
				
			||||||
 | 
					        "rgb(181,29,20)",
 | 
				
			||||||
 | 
					        "rgb(0,190,255)",
 | 
				
			||||||
 | 
					        "rgb(251,73,176)",
 | 
				
			||||||
 | 
					        "rgb(0,178,93)",
 | 
				
			||||||
 | 
					        "rgb(202,202,202)",
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      NormalTwelveColor: [
 | 
				
			||||||
 | 
					        "rgb(235,172,35)",
 | 
				
			||||||
 | 
					        "rgb(184,0,88)",
 | 
				
			||||||
 | 
					        "rgb(0,140,249)",
 | 
				
			||||||
 | 
					        "rgb(0,110,0)",
 | 
				
			||||||
 | 
					        "rgb(0,187,173)",
 | 
				
			||||||
 | 
					        "rgb(209,99,230)",
 | 
				
			||||||
 | 
					        "rgb(178,69,2)",
 | 
				
			||||||
 | 
					        "rgb(255,146,135)",
 | 
				
			||||||
 | 
					        "rgb(89,84,214)",
 | 
				
			||||||
 | 
					        "rgb(0,198,248)",
 | 
				
			||||||
 | 
					        "rgb(135,133,0)",
 | 
				
			||||||
 | 
					        "rgb(0,167,108)",
 | 
				
			||||||
 | 
					        "rgb(189,189,189)",
 | 
				
			||||||
 | 
					      ]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<Row cols={1} class="p-2 g-2">
 | 
					<Row cols={1} class="p-2 g-2">
 | 
				
			||||||
@@ -281,7 +338,7 @@
 | 
				
			|||||||
          <CardTitle
 | 
					          <CardTitle
 | 
				
			||||||
            style="margin-bottom: 1em; display: flex; align-items: center;"
 | 
					            style="margin-bottom: 1em; display: flex; align-items: center;"
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            <div>Color Scheme for Timeseries Plots</div>
 | 
					            <div>Color Scheme for Timeseries Plots {cbmode ? `(Color Blind Friendly Palettes)` : ``}</div>
 | 
				
			||||||
            {#if displayMessage && message.target == "cs"}<div
 | 
					            {#if displayMessage && message.target == "cs"}<div
 | 
				
			||||||
                style="margin-left: auto; font-size: 0.9em;"
 | 
					                style="margin-left: auto; font-size: 0.9em;"
 | 
				
			||||||
              >
 | 
					              >
 | 
				
			||||||
@@ -293,7 +350,7 @@
 | 
				
			|||||||
          <input type="hidden" name="key" value="plot_general_colorscheme" />
 | 
					          <input type="hidden" name="key" value="plot_general_colorscheme" />
 | 
				
			||||||
          <Table hover>
 | 
					          <Table hover>
 | 
				
			||||||
            <tbody>
 | 
					            <tbody>
 | 
				
			||||||
              {#each Object.entries(colorschemes) as [name, rgbrow]}
 | 
					              {#each Object.entries(cbmode ? cvdschemes : colorschemes) as [name, rgbrow]}
 | 
				
			||||||
                <tr>
 | 
					                <tr>
 | 
				
			||||||
                  <th scope="col">{name}</th>
 | 
					                  <th scope="col">{name}</th>
 | 
				
			||||||
                  <td>
 | 
					                  <td>
 | 
				
			||||||
@@ -333,8 +390,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<style>
 | 
					<style>
 | 
				
			||||||
.color-dot {
 | 
					.color-dot {
 | 
				
			||||||
    height: 10px;
 | 
					    margin-left: 1px;
 | 
				
			||||||
    width: 10px;
 | 
					    height: 12px;
 | 
				
			||||||
 | 
					    width: 12px;
 | 
				
			||||||
    border-radius: 50%;
 | 
					    border-radius: 50%;
 | 
				
			||||||
    display: inline-block;
 | 
					    display: inline-block;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -129,8 +129,8 @@
 | 
				
			|||||||
    >
 | 
					    >
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
    <!-- BACKGROUND -->
 | 
					    <!-- BACKGROUND -->
 | 
				
			||||||
    <Col
 | 
					    <Col class="d-flex justify-content-between"
 | 
				
			||||||
      ><Card class="h-100">
 | 
					      ><Card class="h-100" style="width: 49%;">
 | 
				
			||||||
        <form
 | 
					        <form
 | 
				
			||||||
          id="backgrounds-form"
 | 
					          id="backgrounds-form"
 | 
				
			||||||
          method="post"
 | 
					          method="post"
 | 
				
			||||||
@@ -173,6 +173,50 @@
 | 
				
			|||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
          <Button color="primary" type="submit">Submit</Button>
 | 
					          <Button color="primary" type="submit">Submit</Button>
 | 
				
			||||||
        </form>
 | 
					        </form>
 | 
				
			||||||
      </Card></Col
 | 
					      </Card>
 | 
				
			||||||
    >
 | 
					      <Card class="h-100" style="width: 49%;">
 | 
				
			||||||
 | 
					        <form
 | 
				
			||||||
 | 
					          id="colorblindmode-form"
 | 
				
			||||||
 | 
					          method="post"
 | 
				
			||||||
 | 
					          action="/frontend/configuration/"
 | 
				
			||||||
 | 
					          class="card-body"
 | 
				
			||||||
 | 
					          on:submit|preventDefault={() =>
 | 
				
			||||||
 | 
					            updateSetting("#colorblindmode-form", "cbm")}
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
 | 
					          <!-- Svelte 'class' directive only on DOMs directly, normal 'class="xxx"' does not work, so style-array it is. -->
 | 
				
			||||||
 | 
					          <CardTitle
 | 
				
			||||||
 | 
					            style="margin-bottom: 1em; display: flex; align-items: center;"
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            <div>Color Blind Mode</div>
 | 
				
			||||||
 | 
					            {#if displayMessage && message.target == "cbm"}<div
 | 
				
			||||||
 | 
					                style="margin-left: auto; font-size: 0.9em;"
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                <code style="color: {message.color};" out:fade
 | 
				
			||||||
 | 
					                  >Update: {message.msg}</code
 | 
				
			||||||
 | 
					                >
 | 
				
			||||||
 | 
					              </div>{/if}
 | 
				
			||||||
 | 
					          </CardTitle>
 | 
				
			||||||
 | 
					          <input type="hidden" name="key" value="plot_general_colorblindMode" />
 | 
				
			||||||
 | 
					          <div class="mb-3">
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					              {#if config?.plot_general_colorblindMode}
 | 
				
			||||||
 | 
					                <input type="radio" id="cbm-true-checked" name="value" value="true" checked />
 | 
				
			||||||
 | 
					              {:else}
 | 
				
			||||||
 | 
					                <input type="radio" id="cbm-true" name="value" value="true" />
 | 
				
			||||||
 | 
					              {/if}
 | 
				
			||||||
 | 
					              <label for="true">Yes</label>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					              {#if config?.plot_general_colorblindMode}
 | 
				
			||||||
 | 
					                <input type="radio" id="cbm-false" name="value" value="false" />
 | 
				
			||||||
 | 
					              {:else}
 | 
				
			||||||
 | 
					                <input type="radio" id="cbm-false-checked" name="value" value="false" checked />
 | 
				
			||||||
 | 
					              {/if}
 | 
				
			||||||
 | 
					              <label for="false">No</label>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <Button color="primary" type="submit">Submit</Button>
 | 
				
			||||||
 | 
					        </form>
 | 
				
			||||||
 | 
					      </Card>
 | 
				
			||||||
 | 
					    </Col>
 | 
				
			||||||
</Row>
 | 
					</Row>
 | 
				
			||||||
@@ -152,10 +152,12 @@
 | 
				
			|||||||
  const lineWidth =
 | 
					  const lineWidth =
 | 
				
			||||||
    clusterCockpitConfig.plot_general_lineWidth / window.devicePixelRatio;
 | 
					    clusterCockpitConfig.plot_general_lineWidth / window.devicePixelRatio;
 | 
				
			||||||
  const lineColors = clusterCockpitConfig.plot_general_colorscheme;
 | 
					  const lineColors = clusterCockpitConfig.plot_general_colorscheme;
 | 
				
			||||||
 | 
					  const cbmode = clusterCockpitConfig?.plot_general_colorblindMode || false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const backgroundColors = {
 | 
					  const backgroundColors = {
 | 
				
			||||||
    normal: "rgba(255, 255, 255, 1.0)",
 | 
					    normal: "rgba(255, 255, 255, 1.0)",
 | 
				
			||||||
    caution: "rgba(255, 128, 0, 0.3)",
 | 
					    caution: cbmode ? "rgba(239, 230, 69, 0.3)" : "rgba(255, 128, 0, 0.3)",
 | 
				
			||||||
    alert: "rgba(255, 0, 0, 0.3)",
 | 
					    alert: cbmode ? "rgba(225, 86, 44, 0.3)" : "rgba(255, 0, 0, 0.3)",
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  const thresholds = findJobAggregationThresholds(
 | 
					  const thresholds = findJobAggregationThresholds(
 | 
				
			||||||
    subClusterTopology,
 | 
					    subClusterTopology,
 | 
				
			||||||
@@ -346,13 +348,13 @@
 | 
				
			|||||||
      label: "min",
 | 
					      label: "min",
 | 
				
			||||||
      scale: "y",
 | 
					      scale: "y",
 | 
				
			||||||
      width: lineWidth,
 | 
					      width: lineWidth,
 | 
				
			||||||
      stroke: "red",
 | 
					      stroke: cbmode ? "rgb(0,255,0)" : "red",
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    plotSeries.push({
 | 
					    plotSeries.push({
 | 
				
			||||||
      label: "max",
 | 
					      label: "max",
 | 
				
			||||||
      scale: "y",
 | 
					      scale: "y",
 | 
				
			||||||
      width: lineWidth,
 | 
					      width: lineWidth,
 | 
				
			||||||
      stroke: "green",
 | 
					      stroke: cbmode ? "rgb(0,0,255)" : "green",
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    plotSeries.push({
 | 
					    plotSeries.push({
 | 
				
			||||||
      label: usesMeanStatsSeries ? "mean" : "median",
 | 
					      label: usesMeanStatsSeries ? "mean" : "median",
 | 
				
			||||||
@@ -362,8 +364,8 @@
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    plotBands = [
 | 
					    plotBands = [
 | 
				
			||||||
      { series: [2, 3], fill: "rgba(0,255,0,0.1)" },
 | 
					      { series: [2, 3], fill: cbmode ? "rgba(0,0,255,0.1)" : "rgba(0,255,0,0.1)" },
 | 
				
			||||||
      { series: [3, 1], fill: "rgba(255,0,0,0.1)" },
 | 
					      { series: [3, 1], fill: cbmode ? "rgba(0,255,0,0.1)" : "rgba(255,0,0,0.1)" },
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    for (let i = 0; i < series.length; i++) {
 | 
					    for (let i = 0; i < series.length; i++) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,7 @@
 | 
				
			|||||||
  let timeoutId = null;
 | 
					  let timeoutId = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const lineWidth = clusterCockpitConfig.plot_general_lineWidth;
 | 
					  const lineWidth = clusterCockpitConfig.plot_general_lineWidth;
 | 
				
			||||||
 | 
					  const cbmode = clusterCockpitConfig?.plot_general_colorblindMode || false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Helpers
 | 
					  // Helpers
 | 
				
			||||||
  function getGradientR(x) {
 | 
					  function getGradientR(x) {
 | 
				
			||||||
@@ -61,7 +62,7 @@
 | 
				
			|||||||
    return Math.floor(x * 255.0);
 | 
					    return Math.floor(x * 255.0);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  function getRGB(c) {
 | 
					  function getRGB(c) {
 | 
				
			||||||
    return `rgb(${getGradientR(c)}, ${getGradientG(c)}, ${getGradientB(c)})`;
 | 
					    return `rgb(${cbmode ? '0' : getGradientR(c)}, ${getGradientG(c)}, ${getGradientB(c)})`;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  function nearestThousand(num) {
 | 
					  function nearestThousand(num) {
 | 
				
			||||||
    return Math.ceil(num / 1000) * 1000;
 | 
					    return Math.ceil(num / 1000) * 1000;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user