frontend: Diagramm als Bild (PNG) in die Zwischenablage kopieren
Der Diagramm-Kopieren-Button liefert nun ein grafisches Format statt Text: Das gerenderte Diagramm wird aus der Live-Geometrie in ein eigenständiges SVG (nur Formen + Text, keine externen Ressourcen) nachgezeichnet und als PNG in die Zwischenablage gelegt. Knotenfarben, Größen-Badges, Tags und der Geister-Knoten werden übernommen; Verbindungslinien je Gate neu gezogen (und = durchgezogen Tinte, oder = gestrichelt Grau) und treffen so in allen Modi die Knoten. Fallback: SVG-Quelltext, wenn kein Bild-Clipboard verfügbar. Der bisherige ASCII-Text-Export (treeToText, CODE_BY_KEY) entfällt. Tooltip-Texte auf "als Bild" aktualisiert, SPEC §9 entsprechend ersetzt. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
8398e8ea64
commit
57fb72cbe4
+13
-8
@@ -134,16 +134,21 @@ ist grau (`#6B7A8C`) — kein Petrol mehr im Diagramm. Der Modus ändert nur die
|
|||||||
+ halbe Knotenhöhe). Abzweige zielen auf den **Knoten**, nie auf die Mitte
|
+ halbe Knotenhöhe). Abzweige zielen auf den **Knoten**, nie auf die Mitte
|
||||||
des Teilbaums.
|
des Teilbaums.
|
||||||
|
|
||||||
### Textexport des Diagramms
|
### Grafikexport des Diagramms
|
||||||
Das Diagramm ist per Icon-Schaltfläche als einfacher, überall einsetzbarer
|
Das Diagramm ist per Icon-Schaltfläche als **Bild** in die Zwischenablage
|
||||||
ASCII-Baum in die Zwischenablage kopierbar. Format:
|
kopierbar (grafisches Format, in Dokumente/Chats einfügbar):
|
||||||
|
|
||||||
- Eingerückter Baum mit `├─`/`└─` (all-of-Abzweige) bzw. `├◇`/`└◇`
|
- Das gerenderte Diagramm wird aus der Live-Geometrie in ein eigenständiges
|
||||||
(any-of-Alternativen); Fortsetzungsspalten mit `│`.
|
SVG (nur Formen + Text, keine externen Ressourcen) nachgezeichnet und als
|
||||||
- Je Knoten: `[Status] Label (Größe) @tags` — jeder Teil optional, Reihenfolge
|
**PNG** (`image/png`) in die Zwischenablage gelegt. Fällt der Bild-Clipboard
|
||||||
wie hier. Der Status-Code entspricht §4 (`[ ]`, `[x]`, `[~]`, …).
|
aus (fehlende `ClipboardItem`-Unterstützung), wird der **SVG-Quelltext**
|
||||||
|
kopiert (ebenfalls ein Grafikformat).
|
||||||
|
- Übernommen werden Knotenfarben (Status §4), Größen-Badge, Tags und der
|
||||||
|
Geister-Knoten; die Verbindungslinien werden je Gate neu gezogen
|
||||||
|
(und = durchgezogen Tinte, oder = gestrichelt Grau) und treffen die Knoten
|
||||||
|
unabhängig vom Darstellungsmodus.
|
||||||
- Es wird genau die **sichtbare** Struktur exportiert (der „verworfene
|
- Es wird genau die **sichtbare** Struktur exportiert (der „verworfene
|
||||||
einblenden“-Filter wirkt auch hier). Mehrere Wurzeln durch Leerzeile getrennt.
|
einblenden“-Filter wirkt auch hier).
|
||||||
|
|
||||||
## 10. Beispiel (kanonisch)
|
## 10. Beispiel (kanonisch)
|
||||||
|
|
||||||
|
|||||||
+122
-45
@@ -564,7 +564,7 @@
|
|||||||
<span><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2.5" y="9.5" width="5" height="5" rx="1"/><rect x="16" y="3" width="6" height="4" rx="1"/><rect x="16" y="17" width="6" height="4" rx="1"/><path d="M7.5 12H12M12 5V19M12 5H16M12 19H16"/></svg></span>
|
<span><svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2.5" y="9.5" width="5" height="5" rx="1"/><rect x="16" y="3" width="6" height="4" rx="1"/><rect x="16" y="17" width="6" height="4" rx="1"/><path d="M7.5 12H12M12 5V19M12 5H16M12 19H16"/></svg></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="copybtn" id="copyDiagram" data-i18n-title="copyDiagramTooltip" data-i18n-aria="copyDiagramTooltip" title="Diagramm als Textbaum kopieren" aria-label="Diagramm als Textbaum kopieren">
|
<button type="button" class="copybtn" id="copyDiagram" data-i18n-title="copyDiagramTooltip" data-i18n-aria="copyDiagramTooltip" title="Diagramm als Bild kopieren" aria-label="Diagramm als Bild kopieren">
|
||||||
<svg class="ic-copy" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
<svg class="ic-copy" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
||||||
<svg class="ic-done" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6L9 17l-5-5"/></svg>
|
<svg class="ic-done" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.1" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6L9 17l-5-5"/></svg>
|
||||||
</button>
|
</button>
|
||||||
@@ -615,9 +615,6 @@ const STATUS_BY_CODE = {
|
|||||||
'-': {key:'verworfen', name:'verworfen'}
|
'-': {key:'verworfen', name:'verworfen'}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Rück-Abbildung Status-Key → Code (für den Text-Export des Diagramms) */
|
|
||||||
const CODE_BY_KEY = {idee:'?', geplant:' ', arbeit:'~', durchstich:'/', fertig:'x', prod:'^', verworfen:'-'};
|
|
||||||
|
|
||||||
const src = document.getElementById('src');
|
const src = document.getElementById('src');
|
||||||
const out = document.getElementById('out');
|
const out = document.getElementById('out');
|
||||||
const warnBox = document.getElementById('warn');
|
const warnBox = document.getElementById('warn');
|
||||||
@@ -738,41 +735,121 @@ function render(){
|
|||||||
warnBox.innerHTML = warnings.map(w => `<div>⚠ ${w}</div>`).join('');
|
warnBox.innerHTML = warnings.map(w => `<div>⚠ ${w}</div>`).join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- Diagramm als einfacher Text-Baum ---------- */
|
/* ---------- Diagramm als Grafik (SVG → PNG) ---------- */
|
||||||
/* Einfachstes, aber überall einsetzbares Format: eingerückter ASCII-Baum.
|
/* Das gerenderte Diagramm wird aus der Live-Geometrie in ein eigenständiges
|
||||||
all-of-Abzweige mit ├─/└─, any-of-Alternativen mit ├◇/└◇. Je Knoten:
|
SVG (nur Formen + Text, keine externen Ressourcen) nachgezeichnet und als
|
||||||
[Status] Label (Größe) @tags. Respektiert den „verworfene“-Filter, gibt
|
PNG in die Zwischenablage gelegt. Knotenfarben, Größen-Badges, Tags und
|
||||||
also genau die sichtbare Struktur wieder. */
|
der Geister-Knoten werden übernommen; Verbindungslinien werden je Gate
|
||||||
function nodeLabelText(n){
|
(und = durchgezogen Tinte, oder = gestrichelt Grau) neu gezogen und treffen
|
||||||
let s = n.status ? '[' + (CODE_BY_KEY[n.status.key] ?? ' ') + '] ' : '';
|
so garantiert die Knoten — unabhängig vom Darstellungsmodus. */
|
||||||
s += n.label;
|
function diagramToSvg(){
|
||||||
if(n.size) s += ' (' + n.size + ')';
|
const treeRect = out.getBoundingClientRect();
|
||||||
if(n.tags && n.tags.length) s += ' ' + n.tags.map(x => '@' + x).join(' ');
|
const PAD = 24;
|
||||||
return s;
|
const W = Math.ceil(treeRect.width) + PAD*2;
|
||||||
}
|
const H = Math.ceil(treeRect.height) + PAD*2;
|
||||||
function walkText(node, prefix, lines){
|
const ox = -treeRect.left + PAD, oy = -treeRect.top + PAD;
|
||||||
const kids = visibleChildren(node);
|
const R = el => { const r = el.getBoundingClientRect();
|
||||||
const gate = gateOf(kids);
|
return {x:r.left+ox, y:r.top+oy, w:r.width, h:r.height,
|
||||||
kids.forEach((k, i) => {
|
cx:r.left+ox+r.width/2, cy:r.top+oy+r.height/2, r:r.right+ox, b:r.bottom+oy}; };
|
||||||
const last = i === kids.length - 1;
|
const parts = [`<rect x="0" y="0" width="${W}" height="${H}" fill="#ffffff"/>`];
|
||||||
const conn = gate === 'or'
|
const nodes = [...out.querySelectorAll('.node')];
|
||||||
? (last ? '└◇ ' : '├◇ ')
|
|
||||||
: (last ? '└─ ' : '├─ ');
|
/* 1) Verbindungslinien (hinter den Knoten) */
|
||||||
lines.push(prefix + conn + nodeLabelText(k));
|
const seg = (x1,y1,x2,y2,stroke,dash) =>
|
||||||
walkText(k, prefix + (last ? ' ' : '│ '), lines);
|
`<line x1="${x1.toFixed(1)}" y1="${y1.toFixed(1)}" x2="${x2.toFixed(1)}" y2="${y2.toFixed(1)}" stroke="${stroke}" stroke-width="2"${dash?' stroke-dasharray="5 4"':''} stroke-linecap="round"/>`;
|
||||||
});
|
nodes.forEach(parentEl => {
|
||||||
}
|
const li = parentEl.closest('li');
|
||||||
function treeToText(){
|
const childUl = li && [...li.children].find(c => c.tagName === 'UL');
|
||||||
let {roots} = parse(src.value);
|
if(!childUl) return;
|
||||||
if(!showc.checked){
|
const gate = childUl.classList.contains('or') ? 'or' : 'and';
|
||||||
roots = roots.filter(r => !r.status || r.status.key !== 'verworfen');
|
const stroke = gate === 'or' ? '#6B7A8C' : '#41556E';
|
||||||
|
const dash = gate === 'or';
|
||||||
|
const kids = [...childUl.children]
|
||||||
|
.map(cli => cli.querySelector(':scope > .node, :scope > a.node')).filter(Boolean).map(R);
|
||||||
|
if(!kids.length) return;
|
||||||
|
const p = R(parentEl);
|
||||||
|
const avgdx = kids.reduce((s,k)=>s+(k.cx-p.cx),0)/kids.length;
|
||||||
|
const avgdy = kids.reduce((s,k)=>s+(k.cy-p.cy),0)/kids.length;
|
||||||
|
if(Math.abs(avgdx) >= Math.abs(avgdy)){ /* links→rechts */
|
||||||
|
const toRight = avgdx >= 0;
|
||||||
|
const px = toRight ? p.r : p.x;
|
||||||
|
const busX = toRight ? Math.min(...kids.map(k=>k.x))-14 : Math.max(...kids.map(k=>k.r))+14;
|
||||||
|
const ys = kids.map(k=>k.cy).concat(p.cy);
|
||||||
|
parts.push(seg(px, p.cy, busX, p.cy, stroke, dash));
|
||||||
|
parts.push(seg(busX, Math.min(...ys), busX, Math.max(...ys), stroke, dash));
|
||||||
|
kids.forEach(k => parts.push(seg(busX, k.cy, toRight?k.x:k.r, k.cy, stroke, dash)));
|
||||||
|
} else { /* oben→unten */
|
||||||
|
const toDown = avgdy >= 0;
|
||||||
|
const py = toDown ? p.b : p.y;
|
||||||
|
const busY = toDown ? Math.min(...kids.map(k=>k.y))-14 : Math.max(...kids.map(k=>k.b))+14;
|
||||||
|
const xs = kids.map(k=>k.cx).concat(p.cx);
|
||||||
|
parts.push(seg(p.cx, py, p.cx, busY, stroke, dash));
|
||||||
|
parts.push(seg(Math.min(...xs), busY, Math.max(...xs), busY, stroke, dash));
|
||||||
|
kids.forEach(k => parts.push(seg(k.cx, busY, k.cx, toDown?k.y:k.b, stroke, dash)));
|
||||||
}
|
}
|
||||||
const blocks = roots.map(root => {
|
|
||||||
const lines = [nodeLabelText(root)];
|
|
||||||
walkText(root, '', lines);
|
|
||||||
return lines.join('\n');
|
|
||||||
});
|
});
|
||||||
return blocks.join('\n\n'); /* mehrere Wurzeln durch Leerzeile trennen */
|
|
||||||
|
/* 2) Badge/Pille (Größe, Tags) */
|
||||||
|
const drawBadge = (el, fill, textColor, strokeColor) => {
|
||||||
|
const b = R(el);
|
||||||
|
parts.push(`<rect x="${b.x.toFixed(1)}" y="${b.y.toFixed(1)}" width="${b.w.toFixed(1)}" height="${b.h.toFixed(1)}" rx="${Math.min(b.h/2,9).toFixed(1)}" fill="${fill}"${strokeColor?` stroke="${strokeColor}" stroke-width="1.2"`:''}/>`);
|
||||||
|
parts.push(`<text x="${b.cx.toFixed(1)}" y="${(b.cy+3.2).toFixed(1)}" text-anchor="middle" fill="${textColor}" font-size="9" font-family="'IBM Plex Mono',monospace">${esc(el.textContent.trim())}</text>`);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 3) Knoten */
|
||||||
|
nodes.forEach(node => {
|
||||||
|
const b = R(node), cs = getComputedStyle(node);
|
||||||
|
const dashed = cs.borderTopStyle === 'dashed';
|
||||||
|
parts.push(`<rect x="${b.x.toFixed(1)}" y="${b.y.toFixed(1)}" width="${b.w.toFixed(1)}" height="${b.h.toFixed(1)}" rx="8" fill="${cs.backgroundColor}" stroke="${cs.borderTopColor}" stroke-width="${parseFloat(cs.borderTopWidth)||1.5}"${dashed?' stroke-dasharray="4 3"':''}/>`);
|
||||||
|
const clone = node.cloneNode(true);
|
||||||
|
clone.querySelectorAll('.size,.tags,.ext').forEach(e => e.remove());
|
||||||
|
const label = clone.textContent.replace(/\s+/g,' ').trim();
|
||||||
|
const deco = cs.textDecorationLine.includes('line-through') ? ' text-decoration="line-through"' : '';
|
||||||
|
parts.push(`<text x="${b.cx.toFixed(1)}" y="${(b.cy+5).toFixed(1)}" text-anchor="middle" fill="${cs.color}" font-size="14" font-weight="${cs.fontWeight}"${deco}>${esc(label)}</text>`);
|
||||||
|
const sizeEl = node.querySelector('.size');
|
||||||
|
if(sizeEl) drawBadge(sizeEl, '#0F766E', '#ffffff');
|
||||||
|
node.querySelectorAll('.tag').forEach(tg => {
|
||||||
|
const t = getComputedStyle(tg);
|
||||||
|
drawBadge(tg, t.backgroundColor, t.color, t.borderTopColor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/* 4) Geister-Knoten „Untergliederung fehlt“ */
|
||||||
|
out.querySelectorAll('.ghost-node').forEach(g => {
|
||||||
|
const b = R(g);
|
||||||
|
parts.push(seg(b.cx, b.y-14, b.cx, b.y, '#B45309', true));
|
||||||
|
parts.push(`<rect x="${b.x.toFixed(1)}" y="${b.y.toFixed(1)}" width="${b.w.toFixed(1)}" height="${b.h.toFixed(1)}" rx="8" fill="rgba(180,83,9,0.06)" stroke="#B45309" stroke-width="1.5" stroke-dasharray="4 3"/>`);
|
||||||
|
parts.push(`<text x="${b.cx.toFixed(1)}" y="${(b.cy+4).toFixed(1)}" text-anchor="middle" fill="#B45309" font-size="11" font-style="italic">${esc(g.textContent.trim())}</text>`);
|
||||||
|
});
|
||||||
|
|
||||||
|
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${W}" height="${H}" viewBox="0 0 ${W} ${H}" font-family="'IBM Plex Sans',system-ui,sans-serif">${parts.join('')}</svg>`;
|
||||||
|
return {svg, W, H};
|
||||||
|
}
|
||||||
|
function svgToPngBlob(svg, W, H, scale){
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const img = new Image();
|
||||||
|
img.onload = () => {
|
||||||
|
const c = document.createElement('canvas');
|
||||||
|
c.width = Math.round(W*scale); c.height = Math.round(H*scale);
|
||||||
|
const ctx = c.getContext('2d');
|
||||||
|
ctx.scale(scale, scale);
|
||||||
|
ctx.drawImage(img, 0, 0);
|
||||||
|
c.toBlob(b => resolve(b), 'image/png');
|
||||||
|
};
|
||||||
|
img.onerror = () => resolve(null);
|
||||||
|
img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async function copyDiagramImage(){
|
||||||
|
const {svg, W, H} = diagramToSvg();
|
||||||
|
const blob = await svgToPngBlob(svg, W, H, 2);
|
||||||
|
if(blob && navigator.clipboard && window.ClipboardItem){
|
||||||
|
try{
|
||||||
|
await navigator.clipboard.write([new ClipboardItem({'image/png': blob})]);
|
||||||
|
return;
|
||||||
|
}catch(_){}
|
||||||
|
}
|
||||||
|
await writeClipboard(svg); /* Fallback: SVG-Quelltext (ebenfalls Grafik) */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tab-Taste rückt ein statt den Fokus zu wechseln */
|
/* Tab-Taste rückt ein statt den Fokus zu wechseln */
|
||||||
@@ -937,7 +1014,7 @@ document.getElementById('copy').addEventListener('click', async () => {
|
|||||||
flashCopied(document.getElementById('copy'), 'copyTooltip');
|
flashCopied(document.getElementById('copy'), 'copyTooltip');
|
||||||
});
|
});
|
||||||
document.getElementById('copyDiagram').addEventListener('click', async () => {
|
document.getElementById('copyDiagram').addEventListener('click', async () => {
|
||||||
await writeClipboard(treeToText());
|
await copyDiagramImage();
|
||||||
flashCopied(document.getElementById('copyDiagram'), 'copyDiagramTooltip');
|
flashCopied(document.getElementById('copyDiagram'), 'copyDiagramTooltip');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -951,7 +1028,7 @@ const I18N = {
|
|||||||
brandTooltip:"„Werkbaum“ bedeutet so viel wie ‚Werk-Baum‘ — der Baum des Projektstrukturplans (WBS).",
|
brandTooltip:"„Werkbaum“ bedeutet so viel wie ‚Werk-Baum‘ — der Baum des Projektstrukturplans (WBS).",
|
||||||
editorTitle:"Struktur (Text)", diagramTitle:"Diagramm",
|
editorTitle:"Struktur (Text)", diagramTitle:"Diagramm",
|
||||||
copy:"kopieren", copyDone:"kopiert ✓", copyTooltip:"Text in die Zwischenablage kopieren",
|
copy:"kopieren", copyDone:"kopiert ✓", copyTooltip:"Text in die Zwischenablage kopieren",
|
||||||
copyDiagramTooltip:"Diagramm als Textbaum kopieren",
|
copyDiagramTooltip:"Diagramm als Bild kopieren",
|
||||||
minimize:"minimieren", normal:"normal", maximize:"maximieren",
|
minimize:"minimieren", normal:"normal", maximize:"maximieren",
|
||||||
agenda:"Agenda", discarded:"verworfene",
|
agenda:"Agenda", discarded:"verworfene",
|
||||||
modeHorizontal:"Horizontal – Organigramm, Diagramm über dem Editor",
|
modeHorizontal:"Horizontal – Organigramm, Diagramm über dem Editor",
|
||||||
@@ -980,7 +1057,7 @@ const I18N = {
|
|||||||
brandTooltip:"“Werkbaum” means roughly ‘work tree’ — the tree of the work breakdown structure (WBS).",
|
brandTooltip:"“Werkbaum” means roughly ‘work tree’ — the tree of the work breakdown structure (WBS).",
|
||||||
editorTitle:"Structure (text)", diagramTitle:"Diagram",
|
editorTitle:"Structure (text)", diagramTitle:"Diagram",
|
||||||
copy:"copy", copyDone:"copied ✓", copyTooltip:"Copy text to clipboard",
|
copy:"copy", copyDone:"copied ✓", copyTooltip:"Copy text to clipboard",
|
||||||
copyDiagramTooltip:"Copy diagram as a text tree",
|
copyDiagramTooltip:"Copy diagram as an image",
|
||||||
minimize:"minimize", normal:"normal", maximize:"maximize",
|
minimize:"minimize", normal:"normal", maximize:"maximize",
|
||||||
agenda:"Legend", discarded:"discarded",
|
agenda:"Legend", discarded:"discarded",
|
||||||
modeHorizontal:"Horizontal – org chart, diagram above the editor",
|
modeHorizontal:"Horizontal – org chart, diagram above the editor",
|
||||||
@@ -1009,7 +1086,7 @@ const I18N = {
|
|||||||
brandTooltip:"«Werkbaum» significa algo así como ‘árbol de trabajo’ — el árbol de la estructura de desglose del trabajo (EDT).",
|
brandTooltip:"«Werkbaum» significa algo así como ‘árbol de trabajo’ — el árbol de la estructura de desglose del trabajo (EDT).",
|
||||||
editorTitle:"Estructura (texto)", diagramTitle:"Diagrama",
|
editorTitle:"Estructura (texto)", diagramTitle:"Diagrama",
|
||||||
copy:"copiar", copyDone:"copiado ✓", copyTooltip:"Copiar el texto al portapapeles",
|
copy:"copiar", copyDone:"copiado ✓", copyTooltip:"Copiar el texto al portapapeles",
|
||||||
copyDiagramTooltip:"Copiar el diagrama como árbol de texto",
|
copyDiagramTooltip:"Copiar el diagrama como imagen",
|
||||||
minimize:"minimizar", normal:"normal", maximize:"maximizar",
|
minimize:"minimizar", normal:"normal", maximize:"maximizar",
|
||||||
agenda:"Leyenda", discarded:"descartados",
|
agenda:"Leyenda", discarded:"descartados",
|
||||||
modeHorizontal:"Horizontal – organigrama, diagrama sobre el editor",
|
modeHorizontal:"Horizontal – organigrama, diagrama sobre el editor",
|
||||||
@@ -1038,7 +1115,7 @@ const I18N = {
|
|||||||
brandTooltip:"« Werkbaum » signifie à peu près « arbre de travail » — l’arbre de l’organigramme des tâches (WBS).",
|
brandTooltip:"« Werkbaum » signifie à peu près « arbre de travail » — l’arbre de l’organigramme des tâches (WBS).",
|
||||||
editorTitle:"Structure (texte)", diagramTitle:"Diagramme",
|
editorTitle:"Structure (texte)", diagramTitle:"Diagramme",
|
||||||
copy:"copier", copyDone:"copié ✓", copyTooltip:"Copier le texte dans le presse-papiers",
|
copy:"copier", copyDone:"copié ✓", copyTooltip:"Copier le texte dans le presse-papiers",
|
||||||
copyDiagramTooltip:"Copier le diagramme en arbre de texte",
|
copyDiagramTooltip:"Copier le diagramme comme image",
|
||||||
minimize:"réduire", normal:"normal", maximize:"agrandir",
|
minimize:"réduire", normal:"normal", maximize:"agrandir",
|
||||||
agenda:"Légende", discarded:"abandonnés",
|
agenda:"Légende", discarded:"abandonnés",
|
||||||
modeHorizontal:"Horizontal – organigramme, diagramme au-dessus de l'éditeur",
|
modeHorizontal:"Horizontal – organigramme, diagramme au-dessus de l'éditeur",
|
||||||
@@ -1067,7 +1144,7 @@ const I18N = {
|
|||||||
brandTooltip:"„Werkbaum” znaczy mniej więcej ‚drzewo pracy’ — drzewo struktury podziału pracy (WBS).",
|
brandTooltip:"„Werkbaum” znaczy mniej więcej ‚drzewo pracy’ — drzewo struktury podziału pracy (WBS).",
|
||||||
editorTitle:"Struktura (tekst)", diagramTitle:"Diagram",
|
editorTitle:"Struktura (tekst)", diagramTitle:"Diagram",
|
||||||
copy:"kopiuj", copyDone:"skopiowano ✓", copyTooltip:"Kopiuj tekst do schowka",
|
copy:"kopiuj", copyDone:"skopiowano ✓", copyTooltip:"Kopiuj tekst do schowka",
|
||||||
copyDiagramTooltip:"Kopiuj diagram jako drzewo tekstowe",
|
copyDiagramTooltip:"Kopiuj diagram jako obraz",
|
||||||
minimize:"minimalizuj", normal:"normalny", maximize:"maksymalizuj",
|
minimize:"minimalizuj", normal:"normalny", maximize:"maksymalizuj",
|
||||||
agenda:"Legenda", discarded:"odrzucone",
|
agenda:"Legenda", discarded:"odrzucone",
|
||||||
modeHorizontal:"Poziomo – schemat organizacyjny, diagram nad edytorem",
|
modeHorizontal:"Poziomo – schemat organizacyjny, diagram nad edytorem",
|
||||||
@@ -1096,7 +1173,7 @@ const I18N = {
|
|||||||
brandTooltip:"«Werkbaum» примерно означает ‚дерево работ’ — дерево структуры декомпозиции работ (СДР).",
|
brandTooltip:"«Werkbaum» примерно означает ‚дерево работ’ — дерево структуры декомпозиции работ (СДР).",
|
||||||
editorTitle:"Структура (текст)", diagramTitle:"Диаграмма",
|
editorTitle:"Структура (текст)", diagramTitle:"Диаграмма",
|
||||||
copy:"копировать", copyDone:"скопировано ✓", copyTooltip:"Скопировать текст в буфер обмена",
|
copy:"копировать", copyDone:"скопировано ✓", copyTooltip:"Скопировать текст в буфер обмена",
|
||||||
copyDiagramTooltip:"Скопировать диаграмму как текстовое дерево",
|
copyDiagramTooltip:"Скопировать диаграмму как изображение",
|
||||||
minimize:"свернуть", normal:"обычный", maximize:"развернуть",
|
minimize:"свернуть", normal:"обычный", maximize:"развернуть",
|
||||||
agenda:"Легенда", discarded:"отклонённые",
|
agenda:"Легенда", discarded:"отклонённые",
|
||||||
modeHorizontal:"Горизонтально – оргсхема, диаграмма над редактором",
|
modeHorizontal:"Горизонтально – оргсхема, диаграмма над редактором",
|
||||||
@@ -1125,7 +1202,7 @@ const I18N = {
|
|||||||
brandTooltip:"„Werkbaum“ का अर्थ लगभग ‚कार्य-वृक्ष‘ है — कार्य विभाजन संरचना (WBS) का वृक्ष।",
|
brandTooltip:"„Werkbaum“ का अर्थ लगभग ‚कार्य-वृक्ष‘ है — कार्य विभाजन संरचना (WBS) का वृक्ष।",
|
||||||
editorTitle:"संरचना (टेक्स्ट)", diagramTitle:"आरेख",
|
editorTitle:"संरचना (टेक्स्ट)", diagramTitle:"आरेख",
|
||||||
copy:"कॉपी करें", copyDone:"कॉपी हो गया ✓", copyTooltip:"टेक्स्ट को क्लिपबोर्ड पर कॉपी करें",
|
copy:"कॉपी करें", copyDone:"कॉपी हो गया ✓", copyTooltip:"टेक्स्ट को क्लिपबोर्ड पर कॉपी करें",
|
||||||
copyDiagramTooltip:"आरेख को टेक्स्ट-ट्री के रूप में कॉपी करें",
|
copyDiagramTooltip:"आरेख को छवि के रूप में कॉपी करें",
|
||||||
minimize:"छोटा करें", normal:"सामान्य", maximize:"बड़ा करें",
|
minimize:"छोटा करें", normal:"सामान्य", maximize:"बड़ा करें",
|
||||||
agenda:"लेजेंड", discarded:"अस्वीकृत",
|
agenda:"लेजेंड", discarded:"अस्वीकृत",
|
||||||
modeHorizontal:"क्षैतिज – संगठन-चार्ट, संपादक के ऊपर आरेख",
|
modeHorizontal:"क्षैतिज – संगठन-चार्ट, संपादक के ऊपर आरेख",
|
||||||
|
|||||||
Reference in New Issue
Block a user