Tableaux de bord et interfaces d’administration

Tableau de bord d’analyse des tendances de capacité du studio

Réaliser un tableau de bord d’analyse des tendances dans un contexte de capacité de studio : il comprend du contenu réel, des contrôles exploitables, un retour d’état clair et une mise en page adaptée à toutes les tailles.

Tableaux de bord et interfaces d’administrationTableau d’analyse des tendancesHTMLCanvasJavaScript
Après activation de JavaScript, ce cas peut être modifié, exécuté et enregistré. Code source fixe ci-dessous :
<!doctype html>
<html lang="fr" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Tableau de bord d’analyse des tendances de capacité du studio</title>
  <style>
    :root { --ink:#ecf7f3; --paper:#071310; --accent:#247ba0; --secondary:#f4b942; --line:color-mix(in srgb, var(--ink) 18%, transparent); --shadow:0 24px 60px color-mix(in srgb, var(--ink) 16%, transparent); color-scheme:light; }
    * { box-sizing:border-box; }
    html { min-width:320px; background:var(--paper); }
    body { min-height:100vh; margin:0; overflow-x:hidden; color:var(--ink); font-family:"Trebuchet MS","PingFang SC",sans-serif; background:radial-gradient(circle at 20% 10%,color-mix(in srgb,var(--accent) 22%,transparent),transparent 35%),radial-gradient(circle at 85% 90%,color-mix(in srgb,var(--secondary) 20%,transparent),transparent 38%),var(--paper); }
    button,input,select,textarea { color:inherit; font:inherit; }
    button,[role="button"],input,select,textarea { accent-color:var(--accent); }
    button { cursor:pointer; }
    button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible { outline:3px solid var(--accent); outline-offset:3px; }
    [hidden] { display:none !important; }
    @media (max-width:700px) { .mast h1 { line-height:1.08 !important; letter-spacing:-.035em !important; overflow-wrap:anywhere; } }
    @media (prefers-reduced-motion:reduce) { *,*::before,*::after { scroll-behavior:auto !important; animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; } }
    .page{width:min(1160px,calc(100% - 30px));margin:auto;padding:60px 0}.mast{display:flex;justify-content:space-between;border-left:4px solid var(--accent);padding-left:22px;gap:28px;align-items:center;margin-bottom:34px}.mast h1{font-family:"Trebuchet MS","PingFang SC",sans-serif;font-weight:900;font-size:clamp(42px,9vw,94px);text-shadow:0 0 28px color-mix(in srgb,var(--accent) 55%,transparent);margin:0;line-height:.92}.eyebrow{display:block;margin-bottom:14px;color:var(--accent);font:900 11px/1 ui-monospace,monospace;letter-spacing:.2em}.intro{max-width:680px;color:color-mix(in srgb,var(--ink) 68%,transparent);line-height:1.7}.scenario{padding:10px 16px;border:1px solid var(--secondary);border-radius:4px;box-shadow:0 0 20px color-mix(in srgb,var(--secondary) 30%,transparent)}.demo{border-color:color-mix(in srgb,var(--accent) 55%,transparent);border-radius:24px;box-shadow:inset 0 0 40px color-mix(in srgb,var(--accent) 8%,transparent),0 0 60px color-mix(in srgb,var(--secondary) 12%,transparent);position:relative;min-height:410px;overflow:hidden;padding:clamp(24px,4vw,50px);background:color-mix(in srgb,var(--paper) 86%,transparent)}@media(max-width:700px){.mast{display:grid}.page{padding:22px 0}.demo{padding:16px}}
    .stack{display:flex;flex-direction:column;gap:18px}.panel{padding:28px;border-left:7px solid var(--accent);background:color-mix(in srgb,var(--secondary) 12%,var(--paper))}.action{min-height:46px;padding:11px 18px;border:0;border-bottom:3px solid var(--ink);background:transparent;font-weight:900}.action.primary,.action.is-active{color:var(--paper);background:var(--ink)}.row{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:8px}.metric{font:900 clamp(32px,7vw,64px)/1 ui-monospace,monospace}.status{min-height:22px;padding-top:12px;border-top:1px dashed var(--line)}.muted{color:color-mix(in srgb,var(--ink) 62%,transparent)}.chip{display:inline-block;padding:5px 8px;background:var(--secondary)}.meter{height:12px;border:1px solid var(--ink)}.meter>i{display:block;height:100%;background:var(--ink)}
    .composition-deck{display:grid;grid-template-rows:auto 1fr;border:1px solid var(--line);border-radius:24px;overflow:hidden;background:color-mix(in srgb,var(--ink) 4%,var(--paper))}.deck-bar{display:flex;justify-content:space-between;gap:18px;align-items:center;padding:12px 18px;color:var(--paper);background:var(--ink);font:700 12px/1 ui-monospace,monospace}.deck-lights{display:flex;gap:7px}.deck-lights i{width:10px;height:10px;border-radius:50%;background:var(--accent)}.deck-lights i:nth-child(2){background:var(--secondary)}.deck-lights i:nth-child(3){background:color-mix(in srgb,var(--paper) 55%,transparent)}.composition-deck .demo{border:0;border-radius:0;box-shadow:none}
    .ops-trend{display:grid;gap:16px}.ops-trend>header{display:grid;grid-template-columns:1fr minmax(150px,.25fr) minmax(180px,.35fr);gap:18px;align-items:end;padding-bottom:16px;border-bottom:1px solid var(--line)}.ops-trend h2{margin:.2em 0}.ops-trend header label{display:grid;grid-template-columns:1fr auto;gap:7px}.ops-trend header select,.ops-trend header input{grid-column:1/-1;width:100%}.ops-trend-board{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(210px,.5fr);gap:14px}.ops-chart-card{display:grid;gap:8px;padding:14px;border:1px solid var(--line);background:#081b25;color:#dff7f5}.ops-chart-card svg{width:100%;min-height:320px}.ops-chart-card #opsTrendPath{fill:none;stroke:#5eead4;stroke-width:5;stroke-linecap:round;stroke-linejoin:round}.ops-chart-card #opsTrendArea{fill:url(#none);fill:#2dd4bf22;stroke:none}.ops-chart-card circle{fill:#fb923c;stroke:#081b25;stroke-width:4;cursor:crosshair}.ops-chart-card output{min-height:22px;color:#99f6e4}.ops-trend-board>aside{display:grid;align-content:start;gap:9px}.ops-trend-board article{display:grid;gap:5px;padding:16px;border:1px solid var(--line);background:var(--paper)}.ops-trend-board strong{font-size:clamp(28px,5vw,48px)}#opsTrendAlerts{display:grid;gap:6px;padding:0;margin:0;list-style:none}#opsTrendAlerts li{padding:9px;border-left:4px solid var(--accent);background:color-mix(in srgb,var(--accent) 9%,var(--paper));font-size:12px}@media(max-width:760px){.ops-trend>header,.ops-trend-board{grid-template-columns:1fr}.ops-chart-card svg{min-height:240px}}.workflow-compare{display:grid;grid-template-columns:minmax(230px,.55fr) minmax(0,1.45fr);gap:18px}.compare-stage{display:grid;gap:12px;min-width:0}.compare-stage>header{display:flex;justify-content:space-between;gap:16px;align-items:end}.compare-stage h2{margin:.2em 0}.compare-core{--compare-split:50%;min-width:0;padding:14px;clip-path:inset(0 calc(100% - var(--compare-split)) 0 0);outline:1px dashed var(--accent);outline-offset:-8px;transition:clip-path .25s,filter .25s}.compare-core[data-compare-channel="B"]{filter:hue-rotate(32deg) saturate(1.15)}.compare-controls{display:grid;align-content:start;gap:16px;padding:20px;border:1px solid var(--line);border-radius:24px 4px 24px 4px;background:var(--paper)}.compare-controls fieldset,.compare-controls>label{display:grid;gap:8px}.compare-controls input[type="range"]{width:100%}#workflowCompareShelf{display:grid;gap:6px;padding:0;margin:0;list-style:none}#workflowCompareShelf li{display:grid;grid-template-columns:auto 1fr auto;gap:8px;padding:9px;border-top:1px solid var(--line);font-size:12px}@media(max-width:900px){.workflow-compare{grid-template-columns:1fr}.compare-stage{order:-1}.compare-core{clip-path:none;border-left:8px solid var(--accent)}}
  </style>
</head>
<body data-aesthetic="dark-neon" data-composition="control-deck">
  <main class="page">
    <header class="mast"><div><span class="eyebrow">dark-neon / Panneau d’analyse des tendances / BEGINNER</span><h1>Tableau de bord d’analyse des tendances de capacité du studio</h1><p class="intro">Réaliser un tableau de bord d’analyse des tendances dans un contexte de capacité de studio : il comprend du contenu réel, des contrôles exploitables, un retour d’état clair et une mise en page adaptée à toutes les tailles.</p></div><span class="scenario">Capacité de Studio</span></header>
    <div class="composition-deck"><div class="deck-bar"><span>CONTROL DECK · 04</span><span>Tableau d’analyse des tendances</span><span class="deck-lights" aria-hidden="true"><i></i><i></i><i></i></span></div><section class="demo" aria-label="Zone interactive du tableau de bord d’analyse des tendances de la capacité du studio"><div class="workflow-compare"><form id="workflowCompareControls" class="compare-controls"><fieldset><legend>Canal de comparaison</legend><label><input type="radio" name="workflowChannel" value="A" checked>A · Capacité normale</label><label><input type="radio" name="workflowChannel" value="B">B · capacité supplémentaire</label></fieldset><label>Poids des objectifs quotidiens<input id="workflowCompareWeight" type="range" min="10" max="90" value="50"><output id="workflowCompareWeightValue">50 éléments</output></label><label><input id="workflowCompareFreeze" type="checkbox">Geler la version actuelle</label><button id="workflowCompareCapture" class="action primary" type="button">Échantillonner et enregistrer la solution</button><ol id="workflowCompareShelf" aria-label="Enregistrement de version"></ol></form><section class="compare-stage"><header><span class="eyebrow">Capacité du studio COMPARE</span><h2>Comparaison de deux versions de plan de capacité</h2><output id="workflowCompareLive">Version A en attente d’échantillonnage</output></header><section id="workflowCore" class="workflow-core compare-core" data-compare-channel="A" style="--compare-split:50%"><!-- 11DZ_CORE_START:dashboards-admin-trend-chart --><div class="ops-trend"><header><div><span class="eyebrow">OPERATIONS TREND</span><h2>Poste d’achèvement de la capacité du studio</h2><p>Affichez de vrais indicateurs métier selon les équipes d’exploitation et générez directement les intervalles à traiter à l’aide de seuils.</p></div><label>Fenêtre d’observation<select id="opsTrendWindow" data-core-bridge="dashboards-admin-trend-chart"><option value="6">Récemment, le service 6</option><option value="9">Dernier service 9</option><option value="12" selected>Tous les cours 12</option></select></label><label>Seuil d’alerte<input id="opsTrendThreshold" type="range" min="10" max="120" value="60"><output id="opsTrendThresholdValue">60 places</output></label></header><section class="ops-trend-board"><div class="ops-chart-card"><svg id="opsTrendSvg" viewBox="0 0 760 360" role="img" aria-labelledby="opsTrendTitle opsTrendDesc"><title id="opsTrendTitle">Tendance opérationnelle de la capacité de production du studio</title><desc id="opsTrendDesc">Le tracé en ligne montre les postes achevés de douze équipes opérationnelles, et la ligne pointillée indique le seuil d’alerte.</desc><g id="opsTrendGrid" aria-hidden="true"></g><line id="opsTrendLimit" x1="48" x2="732" stroke="currentColor" stroke-dasharray="8 7"></line><path id="opsTrendArea"></path><path id="opsTrendPath"></path><g id="opsTrendPoints"></g></svg><output id="opsTrendHover">Survolez un point de données pour voir le service</output></div><aside><article><span>Valeur actuelle</span><strong id="opsTrendCurrent">—</strong></article><article><span>Moyenne glissante</span><strong id="opsTrendAverage">—</strong></article><article><span>Seuil dépassé</span><strong id="opsTrendBreaches">—</strong></article><ol id="opsTrendAlerts" aria-label="Événement de seuil"></ol></aside></section></div><!-- 11DZ_CORE_END --></section></section></div><p id="status" class="status" role="status" aria-live="polite"></p></section></div>
  </main>
  <script>
    'use strict';
    const statusOutput = document.querySelector('#status');
    const announce = message => { statusOutput.textContent = message; };
    /* 11DZ_CORE_SCRIPT_START:dashboards-admin-trend-chart */
const opsTrendAll=[6,8,11,9,14,16,13,18,17,20,19,22];const opsTrendUnit='places';const opsTrendWindow=document.querySelector('#opsTrendWindow');const opsTrendThreshold=document.querySelector('#opsTrendThreshold');const opsTrendSvg=document.querySelector('#opsTrendSvg');const opsTrendState={windowSize:12,threshold:60,visible:opsTrendAll};function opsTrendScale(value,max){return 320-value/max*260;}function renderOpsTrend(){opsTrendState.windowSize=Number(opsTrendWindow.value);opsTrendState.threshold=Number(opsTrendThreshold.value);opsTrendState.visible=opsTrendAll.slice(-opsTrendState.windowSize);const max=Math.max(opsTrendState.threshold,...opsTrendState.visible)*1.12;const step=684/Math.max(1,opsTrendState.visible.length-1);const points=opsTrendState.visible.map((value,index)=>({value,x:48+index*step,y:opsTrendScale(value,max),shift:opsTrendAll.length-opsTrendState.visible.length+index+1}));const commands=points.map((point,index)=>(index?'L':'M')+point.x.toFixed(1)+' '+point.y.toFixed(1)).join(' ');document.querySelector('#opsTrendPath').setAttribute('d',commands);document.querySelector('#opsTrendArea').setAttribute('d',commands+' L '+points.at(-1).x+' 320 L 48 320 Z');const limitY=opsTrendScale(opsTrendState.threshold,max);const limit=document.querySelector('#opsTrendLimit');limit.setAttribute('y1',String(limitY));limit.setAttribute('y2',String(limitY));const pointGroup=document.querySelector('#opsTrendPoints');pointGroup.replaceChildren(...points.map(point=>{const circle=document.createElementNS('http://www.w3.org/2000/svg','circle');circle.setAttribute('cx',String(point.x));circle.setAttribute('cy',String(point.y));circle.setAttribute('r','7');circle.dataset.value=String(point.value);circle.dataset.shift=String(point.shift);circle.setAttribute('tabindex','0');circle.setAttribute('aria-label','Deuxième '+point.shift+' classe,'+point.value+' '+opsTrendUnit);return circle;}));const average=Math.round(opsTrendState.visible.reduce((sum,value)=>sum+value,0)/opsTrendState.visible.length);const breaches=points.filter(point=>point.value>opsTrendState.threshold);document.querySelector('#opsTrendCurrent').textContent=opsTrendState.visible.at(-1)+' '+opsTrendUnit;document.querySelector('#opsTrendAverage').textContent=average+' '+opsTrendUnit;document.querySelector('#opsTrendBreaches').textContent=breaches.length+' Équipe';document.querySelector('#opsTrendThresholdValue').textContent=opsTrendState.threshold+' '+opsTrendUnit;document.querySelector('#opsTrendAlerts').replaceChildren(...breaches.map(point=>{const item=document.createElement('li');item.textContent='Deuxième '+point.shift+' la classe dépasse le seuil '+(point.value-opsTrendState.threshold)+' '+opsTrendUnit;return item;}));announce('La tendance de la capacité du studio a été mise à jour, '+breaches.length+' un poste nécessite une attention particulière');}opsTrendWindow.addEventListener('change',renderOpsTrend);opsTrendThreshold.addEventListener('input',renderOpsTrend);opsTrendSvg.addEventListener('pointermove',event=>{const target=event.target.closest('circle');if(!target)return;document.querySelector('#opsTrendHover').textContent='Deuxième '+target.dataset.shift+' classe · '+target.dataset.value+' '+opsTrendUnit;});opsTrendSvg.addEventListener('focusin',event=>{if(event.target.matches('circle'))document.querySelector('#opsTrendHover').textContent=event.target.getAttribute('aria-label');});renderOpsTrend();
/* 11DZ_CORE_SCRIPT_END */
const workflowBridgeSpec={"name":"dashboards-admin-trend-chart","selector":"[data-core-bridge=\"dashboards-admin-trend-chart\"]","mode":"select","key":"ArrowRight"};const workflowBridgeCore=document.querySelector('#workflowCore');const workflowBridgeControl=workflowBridgeCore.querySelector(workflowBridgeSpec.selector);if(!workflowBridgeControl)throw new Error('Missing core bridge: '+workflowBridgeSpec.name);const workflowBridgeControlledId=workflowBridgeControl.getAttribute('aria-controls');const workflowBridgeControlled=workflowBridgeControlledId?document.getElementById(workflowBridgeControlledId):null;workflowBridgeCore.dataset.workflowBridge=workflowBridgeSpec.name;workflowBridgeCore.dataset.workflowVersion='0';function workflowBridgeSerialize(){const visualNode=workflowBridgeCore.firstElementChild||workflowBridgeCore;const visual=getComputedStyle(visualNode);const outputs=[...workflowBridgeCore.querySelectorAll('output,[role="status"],[aria-live],meter,progress')].map(node=>node.textContent.trim()+'|'+node.getAttribute('aria-valuenow')+'|'+node.getAttribute('value'));const canvas=[...workflowBridgeCore.querySelectorAll('canvas')].map(node=>{try{return node.toDataURL().slice(-160);}catch{return 'canvas-unavailable';}});return JSON.stringify({html:workflowBridgeCore.innerHTML,status:statusOutput.textContent,outputs,canvas,visual:[visual.display,visual.visibility,visual.opacity,visual.transform,visual.filter,visual.backgroundColor,visual.width,visual.height],scroll:workflowBridgeSpec.mode==='scroll'?workflowBridgeControl.scrollTop:null});}let workflowBridgeLastEffect=workflowBridgeSerialize();function workflowBridgeSummary(){const label=(workflowBridgeControl.getAttribute('aria-label')||workflowBridgeControl.textContent||workflowBridgeControl.value||workflowBridgeSpec.name).trim().replace(/\s+/g,' ').slice(0,72);return label+' · Version de base '+workflowBridgeCore.dataset.workflowVersion;}function workflowBridgeCommit(){const effect=workflowBridgeSerialize();if(effect===workflowBridgeLastEffect)return {changed:false,summary:workflowBridgeSummary()};workflowBridgeLastEffect=effect;workflowBridgeCore.dataset.workflowVersion=String(Number(workflowBridgeCore.dataset.workflowVersion||0)+1);return {changed:true,summary:workflowBridgeSummary()};}function workflowBridgeScheduleCommit(){queueMicrotask(workflowBridgeCommit);setTimeout(workflowBridgeCommit,0);}workflowBridgeControl.setAttribute('aria-keyshortcuts',workflowBridgeSpec.key);workflowBridgeControl.addEventListener('keydown',event=>{if(event.key!==workflowBridgeSpec.key)return;event.preventDefault();workflowBridgeControl.selectedIndex=(workflowBridgeControl.selectedIndex+1)%workflowBridgeControl.options.length;workflowBridgeControl.dispatchEvent(new Event('input',{bubbles:true}));workflowBridgeControl.dispatchEvent(new Event('change',{bubbles:true}));});workflowBridgeControl.addEventListener("keydown",workflowBridgeScheduleCommit);workflowBridgeControl.addEventListener('input',workflowBridgeScheduleCommit);workflowBridgeControl.addEventListener('change',workflowBridgeScheduleCommit);const workflowBridgeStateTargets=new Set(workflowBridgeCore.querySelectorAll('dialog'));if(workflowBridgeControlled&&workflowBridgeCore.contains(workflowBridgeControlled))workflowBridgeStateTargets.add(workflowBridgeControlled);workflowBridgeStateTargets.forEach(target=>['close','cancel','toggle'].forEach(eventName=>target.addEventListener(eventName,workflowBridgeScheduleCommit)));function workflowBridgeActivate(){workflowBridgeControl.focus();workflowBridgeControl.selectedIndex=(workflowBridgeControl.selectedIndex+1)%workflowBridgeControl.options.length;workflowBridgeControl.dispatchEvent(new Event('change',{bubbles:true}));const result=workflowBridgeCommit();setTimeout(workflowBridgeCommit,0);return result;}function workflowBridgeReset(){workflowBridgeCore.dataset.workflowVersion='0';workflowBridgeLastEffect=workflowBridgeSerialize();}
const workflowCompareCore=document.querySelector('#workflowCore');const workflowCompareWeight=document.querySelector('#workflowCompareWeight');const workflowCompareState={channel:'A',weight:50,frozen:false,snapshots:[]};function workflowCompareFingerprint(){const controls=[...workflowCompareCore.querySelectorAll('input,select,textarea')];const outputs=[...workflowCompareCore.querySelectorAll('output,[role="status"],strong')].map(node=>node.textContent.trim()).filter(Boolean);return {controlValues:controls.map(control=>control.type==='checkbox'||control.type==='radio'?control.checked:control.value),summary:outputs.slice(0,4).join(' / '),nodes:workflowCompareCore.querySelectorAll('*').length};}function workflowCompareDrive(){workflowCompareCore.dataset.compareChannel=workflowCompareState.channel;workflowCompareCore.style.setProperty('--compare-split',workflowCompareState.weight+'%');document.querySelector('#workflowCompareWeightValue').textContent=workflowCompareState.weight+' pièce';document.querySelector('#workflowCompareLive').textContent=workflowCompareState.channel+' Version · '+workflowCompareState.weight+' pièce'+(workflowCompareState.frozen?' · figé':'');announce('Plan de capacité en cours de consultation '+workflowCompareState.channel+' Version');}function workflowCompareCapture(source){const bridge=workflowBridgeActivate();const snapshot={...workflowCompareFingerprint(),channel:workflowCompareState.channel,weight:workflowCompareState.weight,source,bridge:bridge.summary};workflowCompareState.snapshots.push(snapshot);const item=document.createElement('li');item.innerHTML='<b>'+snapshot.channel+'</b><span>'+(snapshot.summary||snapshot.bridge)+'</span><small>'+snapshot.weight+' élément · '+snapshot.bridge+'</small>';document.querySelector('#workflowCompareShelf').prepend(item);announce('échantillonné '+snapshot.channel+' Enregistrer la version et le plan · '+bridge.summary);}document.querySelectorAll('[name="workflowChannel"]').forEach(input=>input.addEventListener('change',()=>{workflowCompareState.channel=input.value;workflowCompareDrive();}));workflowCompareWeight.addEventListener('input',()=>{workflowCompareState.weight=Number(workflowCompareWeight.value);workflowCompareDrive();});document.querySelector('#workflowCompareFreeze').addEventListener('change',event=>{workflowCompareState.frozen=event.currentTarget.checked;workflowCompareDrive();});document.querySelector('#workflowCompareCapture').addEventListener('click',()=>workflowCompareCapture('Échantillonnage du bouton'));workflowCompareCore.addEventListener('dblclick',()=>workflowCompareCapture('Double-clic sur la vue principale'));workflowCompareDrive();
workflowBridgeReset();
  </script>
</body>
</html>
Commentaires sur la pageVous avez découvert un problème ou avez une suggestion d’amélioration ?
Les fonctions de retour nécessitent l’utilisation de la version en ligne

Veuillez activer JavaScript dans la version en ligne avant de soumettre ; les fonctionnalités locales de l’outil ou du cas ne sont pas affectées.

Aller vers la version en ligne pour envoyer des commentaires