initial
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
*.bkp
|
||||
.$*
|
||||
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Gemeinsames adesso-Styling für die Workshop-Folien.
|
||||
Teal->Blau-Verlauf, Fira Sans, weiße Shapes + Coral-Akzente,
|
||||
Header (Pill + Titel) und schlanke Fußzeile (Seitenzahl + adesso)."""
|
||||
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
||||
from pptx.enum.shapes import MSO_SHAPE
|
||||
from pptx.oxml.ns import qn
|
||||
|
||||
# ---- adesso Palette --------------------------------------------------------
|
||||
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
|
||||
INK = RGBColor(0x0E, 0x2A, 0x47) # tiefes Navy – Text auf hellen Boxen / dunkle Füllungen
|
||||
BLUE = RGBColor(0x00, 0x6E, 0xC7)
|
||||
TEAL = RGBColor(0x28, 0xDC, 0xAA)
|
||||
GREEN = RGBColor(0x76, 0xC8, 0x00)
|
||||
CORAL = RGBColor(0xFF, 0x98, 0x68)
|
||||
PINK = RGBColor(0xF5, 0x66, 0xBA)
|
||||
TAUPE = RGBColor(0x88, 0x7D, 0x75)
|
||||
LIGHT = RGBColor(0xD7, 0xE6, 0xF4) # helle, gedämpfte Schrift/Linien auf dem Verlauf
|
||||
MUTE = RGBColor(0x6B, 0x77, 0x85) # mittleres Grau – Text auf weißen Flächen
|
||||
RECF = RGBColor(0xE6, 0xEF, 0xF8) # helle Kästchen in weißen Boxen
|
||||
|
||||
F = "Fira Sans"
|
||||
FC = "Fira Sans Condensed"
|
||||
|
||||
|
||||
def alpha(shape, opacity_pct):
|
||||
"""Deckkraft (0-100) auf die Solid-Füllung setzen."""
|
||||
srgb = shape._element.spPr.find(qn('a:solidFill')).find(qn('a:srgbClr'))
|
||||
srgb.append(srgb.makeelement(qn('a:alpha'), {'val': str(int(opacity_pct * 1000))}))
|
||||
|
||||
|
||||
def line_alpha(shape, opacity_pct):
|
||||
ln = shape._element.spPr.find(qn('a:ln'))
|
||||
srgb = ln.find(qn('a:solidFill')).find(qn('a:srgbClr'))
|
||||
srgb.append(srgb.makeelement(qn('a:alpha'), {'val': str(int(opacity_pct * 1000))}))
|
||||
|
||||
|
||||
def paint_background(s, width, height):
|
||||
"""Teal->Blau-Verlauf als Folienhintergrund."""
|
||||
bgr = s.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, width, height)
|
||||
bgr.line.fill.background(); bgr.shadow.inherit = False
|
||||
bgr.fill.gradient()
|
||||
try:
|
||||
bgr.fill.gradient_angle = 90.0
|
||||
except Exception:
|
||||
pass
|
||||
st = bgr.fill.gradient_stops
|
||||
st[0].position = 0.0; st[0].color.rgb = TEAL
|
||||
st[1].position = 1.0; st[1].color.rgb = BLUE
|
||||
return bgr
|
||||
|
||||
|
||||
def chrome(s, title, page):
|
||||
"""Header (Pill + Titel) + schlanke Fußzeile (Seitenzahl + adesso)."""
|
||||
pill = s.shapes.add_shape(MSO_SHAPE.ROUNDED_RECTANGLE,
|
||||
Inches(0.55), Inches(0.46), Inches(0.5), Inches(0.26))
|
||||
pill.fill.background(); pill.line.color.rgb = WHITE; pill.line.width = Pt(1.5)
|
||||
pill.shadow.inherit = False
|
||||
try: pill.adjustments[0] = 0.5
|
||||
except Exception: pass
|
||||
|
||||
def _t(x, y, w, h, t, size, color, bold=False, align=PP_ALIGN.LEFT, font=FC):
|
||||
tb = s.shapes.add_textbox(x, y, w, h); tf = tb.text_frame
|
||||
tf.word_wrap = True; tf.margin_left = tf.margin_right = Pt(0)
|
||||
tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
p = tf.paragraphs[0]; p.alignment = align
|
||||
r = p.add_run(); r.text = t
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.name = font; r.font.color.rgb = color
|
||||
|
||||
_t(Inches(1.25), Inches(0.34), Inches(11), Inches(0.7), title, 30, WHITE, bold=True)
|
||||
_t(Inches(0.55), Inches(7.06), Inches(1.0), Inches(0.3), str(page), 11, LIGHT)
|
||||
_t(Inches(10.95), Inches(6.99), Inches(1.85), Inches(0.4), "adesso", 17, WHITE,
|
||||
bold=True, align=PP_ALIGN.RIGHT)
|
||||
Binary file not shown.
+246
@@ -0,0 +1,246 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Workshop-Folien 'Vault – Technischer Impuls': ruhig, visuell, wenig Text."""
|
||||
|
||||
import os
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
||||
from pptx.enum.shapes import MSO_SHAPE
|
||||
|
||||
# ---- Palette ---------------------------------------------------------------
|
||||
INK = RGBColor(0x2A, 0x2F, 0x3A)
|
||||
NAVY = RGBColor(0x1F, 0x3A, 0x5F)
|
||||
ACCENT = RGBColor(0xC0, 0x49, 0x2F)
|
||||
MUTE = RGBColor(0x8A, 0x93, 0xA0)
|
||||
SOFT = RGBColor(0xE9, 0xEC, 0xEF) # heller Kasten
|
||||
SOFT2 = RGBColor(0xDD, 0xE5, 0xEC) # heller Kasten blau
|
||||
LINEC = RGBColor(0xC3, 0xC9, 0xD1)
|
||||
BG = RGBColor(0xFF, 0xFF, 0xFF)
|
||||
WHITE = RGBColor(0xFF, 0xFF, 0xFF)
|
||||
F = "Calibri"
|
||||
|
||||
prs = Presentation()
|
||||
prs.slide_width = Inches(13.333)
|
||||
prs.slide_height = Inches(7.5)
|
||||
SW, SH = prs.slide_width, prs.slide_height
|
||||
BLANK = prs.slide_layouts[6]
|
||||
MX = Inches(0.95)
|
||||
|
||||
|
||||
def slide(bg=BG):
|
||||
s = prs.slides.add_slide(BLANK)
|
||||
r = s.shapes.add_shape(MSO_SHAPE.RECTANGLE, 0, 0, SW, SH)
|
||||
r.fill.solid(); r.fill.fore_color.rgb = bg; r.line.fill.background()
|
||||
r.shadow.inherit = False
|
||||
s.shapes._spTree.remove(r._element); s.shapes._spTree.insert(2, r._element)
|
||||
return s
|
||||
|
||||
|
||||
def shape(s, kind, x, y, w, h, fill=None, line=None, lw=Pt(1)):
|
||||
sh = s.shapes.add_shape(kind, x, y, w, h)
|
||||
if fill is None: sh.fill.background()
|
||||
else: sh.fill.solid(); sh.fill.fore_color.rgb = fill
|
||||
if line is None: sh.line.fill.background()
|
||||
else: sh.line.color.rgb = line; sh.line.width = lw
|
||||
sh.shadow.inherit = False
|
||||
return sh
|
||||
|
||||
|
||||
def box(s, x, y, w, h, text="", fill=SOFT, tc=INK, size=15, bold=False,
|
||||
rounded=True, line=None, sub=None, sub_c=None):
|
||||
kind = MSO_SHAPE.ROUNDED_RECTANGLE if rounded else MSO_SHAPE.RECTANGLE
|
||||
sh = shape(s, kind, x, y, w, h, fill=fill, line=line)
|
||||
tf = sh.text_frame; tf.word_wrap = True
|
||||
tf.vertical_anchor = MSO_ANCHOR.MIDDLE
|
||||
tf.margin_top = tf.margin_bottom = Pt(2)
|
||||
p = tf.paragraphs[0]; p.alignment = PP_ALIGN.CENTER
|
||||
r = p.add_run(); r.text = text
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.name = F; r.font.color.rgb = tc
|
||||
if sub:
|
||||
p2 = tf.add_paragraph(); p2.alignment = PP_ALIGN.CENTER; p2.space_before = Pt(2)
|
||||
r2 = p2.add_run(); r2.text = sub
|
||||
r2.font.size = Pt(11); r2.font.name = F; r2.font.color.rgb = sub_c or MUTE
|
||||
return sh
|
||||
|
||||
|
||||
def text(s, x, y, w, h, runs, align=PP_ALIGN.LEFT, anchor=MSO_ANCHOR.TOP,
|
||||
leading=1.1, space=0):
|
||||
tb = s.shapes.add_textbox(x, y, w, h); tf = tb.text_frame
|
||||
tf.word_wrap = True; tf.vertical_anchor = anchor
|
||||
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
p = tf.paragraphs[0]; p.alignment = align; p.line_spacing = leading; p.space_after = Pt(space)
|
||||
for t, kw in runs:
|
||||
r = p.add_run(); r.text = t
|
||||
r.font.size = Pt(kw.get("size", 16)); r.font.bold = kw.get("bold", False)
|
||||
r.font.italic = kw.get("italic", False); r.font.name = F
|
||||
r.font.color.rgb = kw.get("color", INK)
|
||||
return tb
|
||||
|
||||
|
||||
def kicker(s, t):
|
||||
tb = text(s, MX, Inches(0.62), Inches(11), Inches(0.4),
|
||||
[(t.upper(), {"size": 12.5, "color": ACCENT, "bold": True})])
|
||||
tb.text_frame.paragraphs[0].runs[0].font._rPr.set('spc', '240')
|
||||
|
||||
|
||||
def head(s, t):
|
||||
text(s, MX, Inches(1.0), Inches(11.4), Inches(0.9),
|
||||
[(t, {"size": 32, "color": NAVY, "bold": True})])
|
||||
shape(s, MSO_SHAPE.RECTANGLE, MX, Inches(1.78), Inches(0.6), Pt(4), fill=ACCENT)
|
||||
|
||||
|
||||
def caption(s, t):
|
||||
text(s, MX, Inches(6.62), Inches(11.4), Inches(0.6),
|
||||
[(t, {"size": 16, "color": MUTE})], leading=1.15)
|
||||
|
||||
|
||||
def vline(s, x, y, h, color=LINEC):
|
||||
shape(s, MSO_SHAPE.RECTANGLE, x, y, Pt(1.6), h, fill=color)
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# TITEL
|
||||
# ===========================================================================
|
||||
s = slide(NAVY)
|
||||
shape(s, MSO_SHAPE.RECTANGLE, 0, 0, Inches(0.24), SH, fill=ACCENT)
|
||||
shape(s, MSO_SHAPE.RECTANGLE, MX, Inches(2.7), Inches(0.85), Pt(5), fill=ACCENT)
|
||||
text(s, MX, Inches(1.7), Inches(10), Inches(0.5),
|
||||
[("TECHNISCHER IMPULS", {"size": 14, "color": RGBColor(0xC6,0xD1,0xDE), "bold": True})]
|
||||
).text_frame.paragraphs[0].runs[0].font._rPr.set('spc', '280')
|
||||
text(s, MX, Inches(3.05), Inches(11.4), Inches(2.0),
|
||||
[("LIS – wohin", {"size": 50, "color": WHITE, "bold": True})])
|
||||
text(s, MX, Inches(4.05), Inches(11.4), Inches(2.0),
|
||||
[("technisch denken?", {"size": 50, "color": WHITE, "bold": True})])
|
||||
|
||||
# ===========================================================================
|
||||
# FOLIE 1 – Produkt oder Projekt (Balken-Bild)
|
||||
# ===========================================================================
|
||||
s = slide()
|
||||
kicker(s, "Diagnose")
|
||||
head(s, "Produkt oder Projekt?")
|
||||
|
||||
base = Inches(5.45) # Grundlinie
|
||||
bw, gap = Inches(0.52), Inches(0.16)
|
||||
|
||||
|
||||
def bars(cx_start, heights, colors, label):
|
||||
n = len(heights)
|
||||
for i, (hh, col) in enumerate(zip(heights, colors)):
|
||||
x = cx_start + i * (bw + gap)
|
||||
h = Inches(hh)
|
||||
shape(s, MSO_SHAPE.ROUNDED_RECTANGLE, x, base - h, bw, h, fill=col)
|
||||
total = n * bw + (n - 1) * gap
|
||||
# Grundlinie
|
||||
shape(s, MSO_SHAPE.RECTANGLE, cx_start, base, total, Pt(2), fill=LINEC)
|
||||
text(s, cx_start, base + Inches(0.18), total, Inches(0.4),
|
||||
[(label, {"size": 18, "color": NAVY, "bold": True})], align=PP_ALIGN.CENTER)
|
||||
|
||||
|
||||
bars(Inches(1.5), [0.45, 0.5, 2.7, 0.5, 0.45],
|
||||
[MUTE, MUTE, ACCENT, MUTE, MUTE], "Projekt")
|
||||
bars(Inches(8.0), [1.7, 2.0, 1.8, 2.1, 1.7],
|
||||
[NAVY, NAVY, NAVY, NAVY, NAVY], "Produkt")
|
||||
|
||||
# kleine neutrale Unterschriften
|
||||
text(s, Inches(1.5), base + Inches(0.6), Inches(3.42), Inches(0.4),
|
||||
[("tief in einer Dimension", {"size": 13, "color": MUTE})], align=PP_ALIGN.CENTER)
|
||||
text(s, Inches(8.0), base + Inches(0.6), Inches(3.42), Inches(0.4),
|
||||
[("breit über viele", {"size": 13, "color": MUTE})], align=PP_ALIGN.CENTER)
|
||||
|
||||
# ===========================================================================
|
||||
# FOLIE 2 – Eine Schicht dazwischen (Layer-Diagramm)
|
||||
# ===========================================================================
|
||||
s = slide()
|
||||
kicker(s, "Architektur")
|
||||
head(s, "Eine Schicht dazwischen")
|
||||
|
||||
cxL, cxR = MX, Inches(12.38)
|
||||
full_w = cxR - cxL
|
||||
|
||||
# oben: Gruppe / Prozesse
|
||||
top_y = Inches(2.2)
|
||||
chips = ["Reporting", "DFÜ / Anlieferung", "Fusion"]
|
||||
cw = Inches(3.2); cg = (full_w - 3 * cw) / 2
|
||||
for i, c in enumerate(chips):
|
||||
box(s, cxL + i * (cw + cg), top_y, cw, Inches(0.72), c,
|
||||
fill=BG, tc=NAVY, size=15, bold=True, line=LINEC)
|
||||
|
||||
# Mitte: die Schicht (Hero)
|
||||
mid_y = Inches(3.55)
|
||||
box(s, cxL, mid_y, full_w, Inches(0.95),
|
||||
"Integrations- & Abstraktionsschicht",
|
||||
fill=NAVY, tc=WHITE, size=20, bold=True)
|
||||
|
||||
# unten: Systeme
|
||||
bot_y = Inches(5.15)
|
||||
labs = [("Labor A", "LIS"), ("Labor B", "LIS"), ("Vault", "LIS"), ("Labor C", "eigenes LIS")]
|
||||
lw = Inches(2.65); lg = (full_w - 4 * lw) / 3
|
||||
for i, (nm, sub) in enumerate(labs):
|
||||
x = cxL + i * (lw + lg)
|
||||
box(s, x, bot_y, lw, Inches(0.95), nm, fill=SOFT, tc=INK, size=16, bold=True,
|
||||
sub=sub, sub_c=MUTE)
|
||||
# Verbinder Schicht -> System
|
||||
vline(s, x + lw / 2, mid_y + Inches(0.95), bot_y - (mid_y + Inches(0.95)))
|
||||
|
||||
# Verbinder oben -> Schicht
|
||||
for i in range(3):
|
||||
cx = cxL + i * (cw + cg) + cw / 2
|
||||
vline(s, cx, top_y + Inches(0.72), mid_y - (top_y + Inches(0.72)))
|
||||
|
||||
caption(s, "Labore docken an und behalten ihr LIS. Die Schicht verbindet.")
|
||||
|
||||
# ===========================================================================
|
||||
# FOLIE 3 – Zustand oder Ereignis (Event Sourcing, visuell)
|
||||
# ===========================================================================
|
||||
s = slide()
|
||||
kicker(s, "Modell")
|
||||
head(s, "Zustand oder Ereignis")
|
||||
|
||||
cxL, cxR = MX, Inches(12.38)
|
||||
full_w = cxR - cxL
|
||||
|
||||
# --- obere Spur: Zustand ---
|
||||
ay = Inches(2.35)
|
||||
text(s, cxL, ay - Inches(0.05), Inches(3), Inches(0.4),
|
||||
[("Zustand", {"size": 15, "color": MUTE, "bold": True})])
|
||||
zy = ay + Inches(0.42)
|
||||
box(s, cxL, zy, Inches(2.4), Inches(0.95), "Probe", fill=SOFT, tc=INK, size=16, bold=True)
|
||||
# Pfeil "überschreiben"
|
||||
shape(s, MSO_SHAPE.RIGHT_ARROW, cxL + Inches(2.65), zy + Inches(0.27),
|
||||
Inches(1.5), Inches(0.42), fill=LINEC)
|
||||
text(s, cxL + Inches(2.55), zy - Inches(0.18), Inches(1.7), Inches(0.3),
|
||||
[("überschreiben", {"size": 11, "color": MUTE, "italic": True})], align=PP_ALIGN.CENTER)
|
||||
box(s, cxL + Inches(4.4), zy, Inches(2.7), Inches(0.95), "1 Abrechnung",
|
||||
fill=BG, tc=NAVY, size=16, bold=True, line=LINEC)
|
||||
|
||||
# Trennlinie
|
||||
shape(s, MSO_SHAPE.RECTANGLE, cxL, Inches(4.25), full_w, Pt(1.2), fill=LINEC)
|
||||
|
||||
# --- untere Spur: Ereignisse ---
|
||||
by = Inches(4.55)
|
||||
text(s, cxL, by - Inches(0.05), Inches(3), Inches(0.4),
|
||||
[("Ereignisse", {"size": 15, "color": MUTE, "bold": True})])
|
||||
ey = by + Inches(0.42)
|
||||
ev = ["Eingang", "Messung", "Abrechnung", "Abrechnung"]
|
||||
ew = Inches(1.85); eg = Inches(0.32)
|
||||
for i, e in enumerate(ev):
|
||||
x = cxL + i * (ew + eg)
|
||||
col = ACCENT if e == "Abrechnung" else NAVY
|
||||
box(s, x, ey, ew, Inches(0.85), e, fill=col, tc=WHITE, size=14, bold=True)
|
||||
if i < len(ev) - 1:
|
||||
shape(s, MSO_SHAPE.CHEVRON, x + ew + Inches(0.02), ey + Inches(0.24),
|
||||
Inches(0.28), Inches(0.38), fill=LINEC)
|
||||
# Pfeil zum abgeleiteten Zustand
|
||||
last_x = cxL + 4 * (ew + eg)
|
||||
shape(s, MSO_SHAPE.RIGHT_ARROW, last_x - Inches(0.05), ey + Inches(0.22),
|
||||
Inches(0.7), Inches(0.42), fill=LINEC)
|
||||
box(s, last_x + Inches(0.75), ey - Inches(0.05), Inches(2.7), Inches(0.95),
|
||||
"Zustand", fill=SOFT2, tc=NAVY, size=15, bold=True,
|
||||
sub="abgeleitet", sub_c=MUTE)
|
||||
|
||||
caption(s, "Der Zustand entsteht aus den Ereignissen – Mehrfaches inklusive.")
|
||||
|
||||
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Vault_Impuls_Workshop.pptx")
|
||||
prs.save(out)
|
||||
print("saved", out)
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Folie 10 – Was bringt der Integrationsserver? Wichtige Funktionen (adesso-Stil, deutsch)."""
|
||||
|
||||
import os
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
||||
from pptx.enum.shapes import MSO_SHAPE
|
||||
from adesso_style import (WHITE, INK, BLUE, TEAL, GREEN, CORAL, LIGHT, MUTE, RECF,
|
||||
F, FC, chrome)
|
||||
|
||||
BG = RGBColor(0x0A, 0x3D, 0x6B)
|
||||
SUBC = RGBColor(0x3C, 0x4A, 0x5A)
|
||||
|
||||
prs = Presentation(); prs.slide_width = Inches(13.333); prs.slide_height = Inches(7.5)
|
||||
SW, SH = prs.slide_width, prs.slide_height
|
||||
s = prs.slides.add_slide(prs.slide_layouts[6])
|
||||
|
||||
|
||||
def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), adj=None):
|
||||
sh = s.shapes.add_shape(kind, Inches(x), Inches(y), Inches(w), Inches(h))
|
||||
if fill is None: sh.fill.background()
|
||||
else: sh.fill.solid(); sh.fill.fore_color.rgb = fill
|
||||
if line is None: sh.line.fill.background()
|
||||
else: sh.line.color.rgb = line; sh.line.width = lw
|
||||
if adj is not None:
|
||||
try: sh.adjustments[0] = adj
|
||||
except Exception: pass
|
||||
sh.shadow.inherit = False
|
||||
return sh
|
||||
|
||||
|
||||
def txt(x, y, w, h, t, size=12, color=WHITE, bold=False, italic=False,
|
||||
align=PP_ALIGN.LEFT, font=F, anchor=MSO_ANCHOR.MIDDLE):
|
||||
tb = s.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h)); tf = tb.text_frame
|
||||
tf.word_wrap = True; tf.vertical_anchor = anchor
|
||||
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
p = tf.paragraphs[0]; p.alignment = align
|
||||
r = p.add_run(); r.text = t
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.italic = italic
|
||||
r.font.name = font; r.font.color.rgb = color
|
||||
return tb
|
||||
|
||||
|
||||
def card(x, y, w, h, title, body):
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, y, w, h, fill=WHITE, adj=0.06)
|
||||
shp(MSO_SHAPE.RECTANGLE, x, y + 0.16, 0.12, h - 0.32, fill=CORAL)
|
||||
txt(x + 0.32, y + 0.18, w - 0.48, 0.78, title, size=13.5, color=INK, bold=True,
|
||||
anchor=MSO_ANCHOR.TOP)
|
||||
txt(x + 0.32, y + 0.92, w - 0.52, h - 1.06, body, size=11, color=SUBC,
|
||||
anchor=MSO_ANCHOR.TOP)
|
||||
|
||||
|
||||
# ---- Hintergrund + Header --------------------------------------------------
|
||||
shp(MSO_SHAPE.RECTANGLE, 0, 0, SW.inches, SH.inches, fill=BG)
|
||||
chrome(s, "Was bringt der Integrationsserver?", 11)
|
||||
|
||||
shp(MSO_SHAPE.RECTANGLE, 0.45, 1.12, 0.16, 0.22, fill=CORAL)
|
||||
txt(0.71, 1.05, 9.0, 0.34, "Wichtige Funktionen", size=15, color=WHITE, bold=True,
|
||||
anchor=MSO_ANCHOR.MIDDLE)
|
||||
|
||||
cards = [
|
||||
("Zentrale Anbindung (Adapter)",
|
||||
"Jedes System über einen Adapter — neues System = neuer Adapter, ohne Eingriff in den Bestand."),
|
||||
("Routing der Aufträge",
|
||||
"Integriert mehrere LIS- und Abrechnungs-Instanzen — Aufträge werden gezielt an das passende LIS bzw. die richtige Abrechnung verteilt."),
|
||||
("Routing Engine",
|
||||
"Verteilt Events regelbasiert an die richtigen Ziele — z. B. Proben-Routing."),
|
||||
("Event Store (append-only)",
|
||||
"Kanonische Wahrheit, vollständige Historie, jederzeit Replay-fähig."),
|
||||
("Projektionen / Read-Models",
|
||||
"Bedarfsgerechte Sichten: Auftragsstatus, Reporting, Leistungsverzeichnis …"),
|
||||
("Stammdaten / MDM",
|
||||
"Single Point of Truth — Daten einmal pflegen, doppelte Stammdatenpflege entfällt."),
|
||||
("Monitoring & Überwachung",
|
||||
"Status, Fehler-Queues und Alerting für alle Schnittstellen an einer Stelle."),
|
||||
("Audit-Trail, Replay & Archiv",
|
||||
"Revisionssicher & manipulationssicher; Wiederaufsetzen per Replay; Langzeit-Archiv."),
|
||||
]
|
||||
|
||||
cw, ch = 2.92, 2.45
|
||||
cols = [0.45, 3.62, 6.79, 9.96]
|
||||
rows = [1.58, 4.22]
|
||||
for i, (title, body) in enumerate(cards):
|
||||
card(cols[i % 4], rows[i // 4], cw, ch, title, body)
|
||||
|
||||
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Folie10.pptx")
|
||||
prs.save(out)
|
||||
print("saved", out)
|
||||
@@ -0,0 +1,174 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Folie 2 – Grenzen der Vault-Integration (adesso-Styling).
|
||||
Kette: Auftrag -> Auftragsannahme -> Schattenbuchhaltung (SPOT) -> Vault ->
|
||||
Zusammenführung."""
|
||||
|
||||
import os
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
||||
from pptx.enum.shapes import MSO_SHAPE
|
||||
from adesso_style import (WHITE, INK, CORAL, LIGHT, RECF, F, FC,
|
||||
alpha, line_alpha, paint_background, chrome)
|
||||
|
||||
prs = Presentation()
|
||||
prs.slide_width = Inches(13.333)
|
||||
prs.slide_height = Inches(7.5)
|
||||
s = prs.slides.add_slide(prs.slide_layouts[6])
|
||||
|
||||
|
||||
def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), rot=0):
|
||||
sh = s.shapes.add_shape(kind, x, y, w, h)
|
||||
if fill is None: sh.fill.background()
|
||||
else: sh.fill.solid(); sh.fill.fore_color.rgb = fill
|
||||
if line is None: sh.line.fill.background()
|
||||
else: sh.line.color.rgb = line; sh.line.width = lw
|
||||
if rot: sh.rotation = rot
|
||||
sh.shadow.inherit = False
|
||||
return sh
|
||||
|
||||
|
||||
def boxtext(sh, t, size=14, color=INK, bold=False, font=F):
|
||||
tf = sh.text_frame; tf.word_wrap = True
|
||||
tf.vertical_anchor = MSO_ANCHOR.MIDDLE
|
||||
tf.margin_left = tf.margin_right = Pt(4); tf.margin_top = tf.margin_bottom = Pt(1)
|
||||
p = tf.paragraphs[0]; p.alignment = PP_ALIGN.CENTER
|
||||
r = p.add_run(); r.text = t
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.name = font; r.font.color.rgb = color
|
||||
|
||||
|
||||
def txt(x, y, w, h, t, size=14, color=INK, bold=False, italic=False,
|
||||
align=PP_ALIGN.LEFT, spc=None, lead=1.1, anchor=MSO_ANCHOR.TOP, font=F):
|
||||
tb = s.shapes.add_textbox(x, y, w, h); tf = tb.text_frame
|
||||
tf.word_wrap = True; tf.vertical_anchor = anchor
|
||||
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
p = tf.paragraphs[0]; p.alignment = align; p.line_spacing = lead
|
||||
r = p.add_run(); r.text = t
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.italic = italic
|
||||
r.font.name = font; r.font.color.rgb = color
|
||||
if spc: r.font._rPr.set('spc', str(spc))
|
||||
return tb
|
||||
|
||||
|
||||
paint_background(s, prs.slide_width, prs.slide_height)
|
||||
chrome(s, "Grenzen der Vault-Integration?", 2)
|
||||
|
||||
# ---- Linke Spalte ----------------------------------------------------------
|
||||
def claim(y, t, bold=False, sub=None):
|
||||
shp(MSO_SHAPE.RECTANGLE, Inches(0.95), y + Inches(0.08), Inches(0.14), Inches(0.14), fill=CORAL)
|
||||
txt(Inches(1.28), y, Inches(4.5), Inches(0.4), t, size=16.5, color=WHITE, bold=bold)
|
||||
if sub:
|
||||
txt(Inches(1.28), y + Inches(0.34), Inches(4.5), Inches(0.32), sub,
|
||||
size=12.5, color=LIGHT, italic=True)
|
||||
|
||||
|
||||
claim(Inches(2.2), "Middleware kapselt den Rand – den Kern nicht", bold=True)
|
||||
claim(Inches(2.95), "Mischaufträge nur als Schattenmodell",
|
||||
sub="aufwändig · fragil · fehleranfällig")
|
||||
claim(Inches(3.95), "die Fachwahrheit verlässt den Kern")
|
||||
|
||||
shp(MSO_SHAPE.RECTANGLE, Inches(0.95), Inches(4.95), Inches(0.5), Pt(3.5), fill=CORAL)
|
||||
txt(Inches(0.95), Inches(5.12), Inches(4.85), Inches(1.1),
|
||||
"Die Schattenbuchhaltung wird zum Single Point of Truth – nicht Vault.",
|
||||
size=19, color=WHITE, bold=True, lead=1.08, font=FC)
|
||||
txt(Inches(0.95), Inches(6.45), Inches(4.85), Inches(0.4),
|
||||
"Genau die Rolle, die Vault halten müsste.", size=13.5, color=LIGHT, italic=True)
|
||||
|
||||
# ===========================================================================
|
||||
# RECHTS: Kette Auftrag -> Auftragsannahme -> SPOT -> Vault -> Zusammenführung
|
||||
# ===========================================================================
|
||||
fx, fy, fw, fh = Inches(6.25), Inches(2.1), Inches(5.9), Inches(4.72)
|
||||
panel = shp(MSO_SHAPE.ROUNDED_RECTANGLE, fx, fy, fw, fh, fill=WHITE)
|
||||
alpha(panel, 10)
|
||||
panel.line.color.rgb = WHITE; panel.line.width = Pt(1)
|
||||
line_alpha(panel, 35)
|
||||
txt(fx + Inches(0.3), fy + Inches(0.12), fw - Inches(0.6), Inches(0.3),
|
||||
"Auftragsweg – hin und zurück durch den Layer", size=12.5, color=WHITE, bold=True)
|
||||
|
||||
cxc = fx + Inches(2.05)
|
||||
bw = Inches(2.7)
|
||||
bx = cxc - bw / 2
|
||||
|
||||
|
||||
def down(y, label=None):
|
||||
shp(MSO_SHAPE.DOWN_ARROW, cxc - Inches(0.11), y, Inches(0.22), Inches(0.22), fill=LIGHT)
|
||||
if label:
|
||||
txt(cxc + Inches(0.22), y - Inches(0.02), Inches(1.7), Inches(0.3), label,
|
||||
size=11, color=LIGHT, italic=True, anchor=MSO_ANCHOR.MIDDLE)
|
||||
|
||||
|
||||
# 1) Auftrag
|
||||
b = shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx, fy + Inches(0.44), bw, Inches(0.40), fill=WHITE)
|
||||
boxtext(b, "Auftrag · Mischauftrag", size=12.5, color=INK, bold=True)
|
||||
down(fy + Inches(0.86))
|
||||
|
||||
# 2) Auftragsannahme (ersetzt altes LIS)
|
||||
b = shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx, fy + Inches(1.06), bw, Inches(0.40), fill=WHITE)
|
||||
boxtext(b, "Auftragsannahme", size=13, color=INK, bold=True)
|
||||
down(fy + Inches(1.48), "Magic")
|
||||
|
||||
# 3) Schattenbuchhaltung = Rahmen um den Vault-Kasten
|
||||
frx, fry = bx - Inches(0.22), fy + Inches(1.72)
|
||||
frw, frh = bw + Inches(0.50), Inches(2.22)
|
||||
frame = shp(MSO_SHAPE.ROUNDED_RECTANGLE, frx, fry, frw, frh,
|
||||
fill=RGBColor(0xFF, 0xE3, 0x9B))
|
||||
alpha(frame, 22)
|
||||
frame.line.color.rgb = CORAL; frame.line.width = Pt(2)
|
||||
|
||||
# Überschrift + Positions-Mapping (oben im Rahmen)
|
||||
txt(frx, fy + Inches(1.78), frw, Inches(0.28), "Schattenbuchhaltung",
|
||||
size=13, color=CORAL, bold=True, align=PP_ALIGN.CENTER)
|
||||
txt(frx, fy + Inches(2.07), frw, Inches(0.24), "Positions-Mapping",
|
||||
size=11.5, color=WHITE, align=PP_ALIGN.CENTER)
|
||||
|
||||
# aktiver SPOT-Stern (rechts neben dem Rahmen)
|
||||
shp(MSO_SHAPE.STAR_5_POINT, Inches(10.75), fy + Inches(1.80), Inches(0.5), Inches(0.5), fill=CORAL)
|
||||
txt(Inches(9.95), fy + Inches(2.32), Inches(2.1), Inches(0.28), "Single Point of Truth",
|
||||
size=10.5, color=CORAL, bold=True, align=PP_ALIGN.CENTER)
|
||||
down(fy + Inches(2.33))
|
||||
|
||||
# 4) Vault speichert (aufgesplittet) – im Rahmen
|
||||
b = shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx, fy + Inches(2.50), bw, Inches(0.70), fill=WHITE)
|
||||
txt(bx, fy + Inches(2.55), bw, Inches(0.3), "Vault · 1:1 · Speicher",
|
||||
size=13, color=INK, bold=True, align=PP_ALIGN.CENTER)
|
||||
for k in range(3):
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, cxc - Inches(1.08) + k * Inches(0.78),
|
||||
fy + Inches(2.87), Inches(0.62), Inches(0.3), fill=RECF)
|
||||
txt(cxc - Inches(1.08) + k * Inches(0.78), fy + Inches(2.87), Inches(0.62), Inches(0.3),
|
||||
"Rec", size=9.5, color=INK, align=PP_ALIGN.CENTER, anchor=MSO_ANCHOR.MIDDLE)
|
||||
# Geist-Stern (durchgestrichen) – die Wahrheit müsste hier liegen
|
||||
gx = Inches(10.79)
|
||||
gs = shp(MSO_SHAPE.STAR_5_POINT, gx, fy + Inches(2.55), Inches(0.42), Inches(0.42))
|
||||
gs.fill.background(); gs.line.color.rgb = LIGHT; gs.line.width = Pt(1.25)
|
||||
shp(MSO_SHAPE.RECTANGLE, gx - Inches(0.02), fy + Inches(2.73), Inches(0.46), Pt(2),
|
||||
fill=CORAL, rot=20)
|
||||
txt(Inches(9.95), fy + Inches(3.02), Inches(2.1), Inches(0.3), "müsste hier liegen",
|
||||
size=10, color=LIGHT, align=PP_ALIGN.CENTER)
|
||||
down(fy + Inches(3.22))
|
||||
|
||||
# 5) Daten zusammenführen (unten im Rahmen)
|
||||
txt(frx, fy + Inches(3.42), frw, Inches(0.28), "Daten Zusammenführen",
|
||||
size=12.5, color=WHITE, bold=True, align=PP_ALIGN.CENTER)
|
||||
|
||||
# 6) Weiterverarbeitung – grauer Pfeil + weißer Kasten unter dem Rahmen
|
||||
shp(MSO_SHAPE.DOWN_ARROW, cxc - Inches(0.11), fy + Inches(4.00), Inches(0.22), Inches(0.22),
|
||||
fill=RGBColor(0x8C, 0x8C, 0x8C))
|
||||
b = shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx, fy + Inches(4.26), bw, Inches(0.40), fill=WHITE)
|
||||
boxtext(b, "Weiterverarbeitung", size=12.5, color=INK, bold=True)
|
||||
|
||||
# Rückweg (Lesen) – Pfeil links nach oben, Label vertikal daneben
|
||||
ua = shp(MSO_SHAPE.UP_ARROW, fx + Inches(0.08), fy + Inches(1.55), Inches(0.26), Inches(2.30),
|
||||
fill=LIGHT)
|
||||
alpha(ua, 55)
|
||||
lt = s.shapes.add_textbox(fx - Inches(0.95), fy + Inches(2.40), Inches(2.2), Inches(0.3))
|
||||
ltf = lt.text_frame; ltf.word_wrap = False
|
||||
ltf.margin_left = ltf.margin_right = ltf.margin_top = ltf.margin_bottom = Pt(0)
|
||||
lp = ltf.paragraphs[0]; lp.alignment = PP_ALIGN.CENTER
|
||||
lr = lp.add_run(); lr.text = "Lesen: zurück durch den Layer"
|
||||
lr.font.size = Pt(9.5); lr.font.name = F; lr.font.color.rgb = CORAL
|
||||
lt.rotation = 270
|
||||
|
||||
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Folie2.pptx")
|
||||
prs.save(out)
|
||||
print("saved", out)
|
||||
@@ -0,0 +1,283 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Folie 3 – LIS mit Umsystemen (Adapter, links/rechts) und andockenden Modulen
|
||||
(unten), unter einer Steuerungs-/Governance-Schicht; weitere LIS angedeutet."""
|
||||
|
||||
import os
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
||||
from pptx.enum.shapes import MSO_SHAPE
|
||||
from adesso_style import (WHITE, INK, BLUE, TEAL, GREEN, CORAL, LIGHT, MUTE, RECF,
|
||||
F, FC, paint_background, chrome)
|
||||
|
||||
# Rollen-Mapping auf die adesso-Palette
|
||||
NAVY = INK # dunkle Strukturelemente (Bar, LIS-Kern)
|
||||
ACCENT = CORAL # Adapter-Linien
|
||||
AMBER = GREEN # zweites Modul
|
||||
LINEC = LIGHT # Verbinder / feine Linien
|
||||
HINT = RGBColor(0xE6, 0xEF, 0xF8) # helle "weitere LIS"-Karten
|
||||
HINTL = RGBColor(0xC4, 0xD6, 0xE8)
|
||||
TINT_T = WHITE # Modul-Boxen weiß
|
||||
TINT_A = WHITE
|
||||
UMS = WHITE # Umsystem-Boxen weiß
|
||||
BG = WHITE
|
||||
|
||||
prs = Presentation()
|
||||
prs.slide_width = Inches(13.333)
|
||||
prs.slide_height = Inches(7.5)
|
||||
s = prs.slides.add_slide(prs.slide_layouts[6])
|
||||
paint_background(s, prs.slide_width, prs.slide_height)
|
||||
|
||||
|
||||
def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), rot=0):
|
||||
sh = s.shapes.add_shape(kind, x, y, w, h)
|
||||
if fill is None: sh.fill.background()
|
||||
else: sh.fill.solid(); sh.fill.fore_color.rgb = fill
|
||||
if line is None: sh.line.fill.background()
|
||||
else: sh.line.color.rgb = line; sh.line.width = lw
|
||||
if rot: sh.rotation = rot
|
||||
sh.shadow.inherit = False
|
||||
return sh
|
||||
|
||||
|
||||
def boxtext(sh, t, size=14, color=INK, bold=False):
|
||||
tf = sh.text_frame; tf.word_wrap = True
|
||||
tf.vertical_anchor = MSO_ANCHOR.MIDDLE
|
||||
tf.margin_left = tf.margin_right = Pt(3); tf.margin_top = tf.margin_bottom = Pt(1)
|
||||
p = tf.paragraphs[0]; p.alignment = PP_ALIGN.CENTER
|
||||
r = p.add_run(); r.text = t
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.name = F; r.font.color.rgb = color
|
||||
|
||||
|
||||
def txt(x, y, w, h, t, size=14, color=INK, bold=False, italic=False,
|
||||
align=PP_ALIGN.LEFT, spc=None):
|
||||
tb = s.shapes.add_textbox(x, y, w, h); tf = tb.text_frame
|
||||
tf.word_wrap = True; tf.vertical_anchor = MSO_ANCHOR.MIDDLE
|
||||
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
p = tf.paragraphs[0]; p.alignment = align
|
||||
r = p.add_run(); r.text = t
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.italic = italic
|
||||
r.font.name = F; r.font.color.rgb = color
|
||||
if spc: r.font._rPr.set('spc', str(spc))
|
||||
return tb
|
||||
|
||||
|
||||
def hline(x, y, w, color=LINEC, weight=Pt(1.4)):
|
||||
shp(MSO_SHAPE.RECTANGLE, x, y - weight / 2, w, weight, fill=color)
|
||||
|
||||
|
||||
def vline(x, y, h, color=LINEC, weight=Pt(1.4)):
|
||||
shp(MSO_SHAPE.RECTANGLE, x - weight / 2, y, weight, h, fill=color)
|
||||
|
||||
|
||||
# ---- Kopf ------------------------------------------------------------------
|
||||
chrome(s, "Offen – und gesteuert", 3)
|
||||
|
||||
x0, x1 = Inches(0.95), Inches(12.38)
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# GOVERNANCE – Icon-Karten + Strich
|
||||
# ===========================================================================
|
||||
def card(cx, label):
|
||||
cw_, ch_ = Inches(2.05), Inches(1.25)
|
||||
x, y = cx - cw_ / 2, Inches(1.5)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, y, cw_, ch_, fill=BG, line=LINEC, lw=Pt(1.25))
|
||||
txt(x, y + ch_ - Inches(0.4), cw_, Inches(0.34), label,
|
||||
size=14, color=NAVY, bold=True, align=PP_ALIGN.CENTER)
|
||||
return cx, y + Inches(0.42)
|
||||
|
||||
|
||||
def regler(cx, cy):
|
||||
tw = Inches(0.62)
|
||||
left = cx - tw / 2
|
||||
for j, frac in enumerate([0.30, 0.68, 0.48]):
|
||||
ty = cy - Inches(0.18) + j * Inches(0.18)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, left, ty - Inches(0.022), tw, Inches(0.045), fill=LINEC)
|
||||
kx = left + Inches(0.62 * frac)
|
||||
shp(MSO_SHAPE.OVAL, kx - Inches(0.07), ty - Inches(0.07),
|
||||
Inches(0.14), Inches(0.14), fill=NAVY)
|
||||
|
||||
|
||||
cx1, cy1 = card(Inches(4.75), "Steuerung")
|
||||
cx2, cy2 = card(Inches(6.95), "Reporting")
|
||||
cx3, cy3 = card(Inches(9.15), "Governance")
|
||||
|
||||
regler(cx1, cy1)
|
||||
|
||||
# Reporting – Zahlenreihen
|
||||
nb = s.shapes.add_textbox(cx2 - Inches(0.85), cy2 - Inches(0.36), Inches(1.7), Inches(0.72))
|
||||
tf = nb.text_frame; tf.word_wrap = False; tf.vertical_anchor = MSO_ANCHOR.MIDDLE
|
||||
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
for i, row in enumerate(["3 8 1 4 7", "6 0 9 2 5", "5 7 2 8 1"]):
|
||||
p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
|
||||
p.alignment = PP_ALIGN.CENTER; p.line_spacing = 0.95
|
||||
r = p.add_run(); r.text = row
|
||||
r.font.size = Pt(11); r.font.name = "Consolas"; r.font.color.rgb = MUTE
|
||||
|
||||
# Governance – §
|
||||
gtb = s.shapes.add_textbox(cx3 - Inches(0.6), cy3 - Inches(0.42), Inches(1.2), Inches(0.8))
|
||||
gtf = gtb.text_frame; gtf.vertical_anchor = MSO_ANCHOR.MIDDLE
|
||||
gp = gtf.paragraphs[0]; gp.alignment = PP_ALIGN.CENTER
|
||||
gr = gp.add_run(); gr.text = "§"; gr.font.size = Pt(34); gr.font.bold = True
|
||||
gr.font.name = F; gr.font.color.rgb = NAVY
|
||||
|
||||
gov_y = Inches(3.05)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x0, gov_y - Inches(0.07), x1 - x0, Inches(0.14), fill=NAVY)
|
||||
for cc in (cx1, cx2, cx3):
|
||||
vline(cc, Inches(2.75), gov_y - Inches(0.07) - Inches(2.75), color=LINEC, weight=Pt(1))
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# LIS + Umsysteme (Adapter links/rechts) + Module (andocken, unten)
|
||||
# ===========================================================================
|
||||
core_x, core_w = Inches(3.7), Inches(2.3)
|
||||
core_y, core_h = Inches(4.3), Inches(1.2)
|
||||
core_cx = core_x + core_w / 2
|
||||
core_by = core_y + core_h
|
||||
|
||||
# Adapter-Schicht: echte Schicht als Hülle um den Kern (Trennung)
|
||||
lay_pad_x, lay_pad_t = Inches(0.24), Inches(0.30)
|
||||
lay_x = core_x - lay_pad_x
|
||||
lay_w = core_w + lay_pad_x * 2
|
||||
lay_y = core_y - lay_pad_t
|
||||
lay_h = core_h + lay_pad_t
|
||||
lay_right = lay_x + lay_w
|
||||
|
||||
|
||||
def adapter(xc, yc):
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, xc - Inches(0.10), yc - Inches(0.11),
|
||||
Inches(0.16), Inches(0.22), fill=ACCENT)
|
||||
shp(MSO_SHAPE.RECTANGLE, xc + Inches(0.06), yc - Inches(0.055), Inches(0.1), Pt(2.4), fill=ACCENT)
|
||||
shp(MSO_SHAPE.RECTANGLE, xc + Inches(0.06), yc + Inches(0.03), Inches(0.1), Pt(2.4), fill=ACCENT)
|
||||
|
||||
|
||||
def dock(xc, yc):
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, xc - Inches(0.1), yc - Inches(0.1),
|
||||
Inches(0.2), Inches(0.2), fill=NAVY)
|
||||
shp(MSO_SHAPE.OVAL, xc - Inches(0.055), yc - Inches(0.055), Inches(0.11), Inches(0.11),
|
||||
fill=ACCENT)
|
||||
|
||||
|
||||
def icon_truck(ix, iy): # Anlieferung
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, ix - Inches(0.20), iy - Inches(0.10),
|
||||
Inches(0.24), Inches(0.16), fill=NAVY)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, ix + Inches(0.05), iy - Inches(0.035),
|
||||
Inches(0.12), Inches(0.095), fill=NAVY)
|
||||
for wx in (ix - Inches(0.11), ix + Inches(0.08)):
|
||||
shp(MSO_SHAPE.OVAL, wx - Inches(0.038), iy + Inches(0.05),
|
||||
Inches(0.076), Inches(0.076), fill=NAVY)
|
||||
|
||||
|
||||
def icon_device(ix, iy): # Gerät
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, ix - Inches(0.16), iy - Inches(0.14),
|
||||
Inches(0.32), Inches(0.28), fill=NAVY)
|
||||
shp(MSO_SHAPE.RECTANGLE, ix - Inches(0.11), iy - Inches(0.10),
|
||||
Inches(0.22), Inches(0.085), fill=RGBColor(0x34, 0x4E, 0x70))
|
||||
shp(MSO_SHAPE.OVAL, ix - Inches(0.085), iy + Inches(0.03), Inches(0.055), Inches(0.055), fill=TEAL)
|
||||
shp(MSO_SHAPE.OVAL, ix + Inches(0.03), iy + Inches(0.03), Inches(0.055), Inches(0.055), fill=AMBER)
|
||||
|
||||
|
||||
def icon_dfu(ix, iy): # DFÜ
|
||||
shp(MSO_SHAPE.RIGHT_ARROW, ix - Inches(0.16), iy - Inches(0.12), Inches(0.32), Inches(0.095),
|
||||
fill=NAVY)
|
||||
shp(MSO_SHAPE.LEFT_ARROW, ix - Inches(0.16), iy + Inches(0.025), Inches(0.32), Inches(0.095),
|
||||
fill=ACCENT)
|
||||
|
||||
|
||||
g = Inches(0.10) # Abstand Adapter-Linie <-> LIS
|
||||
th = Inches(0.08) # Dicke der roten Adapter-Linie
|
||||
|
||||
# Governance -> obere Adapter-Linie am Kern
|
||||
vline(core_cx, gov_y + Inches(0.07), (core_y - g - th) - (gov_y + Inches(0.07)),
|
||||
color=LINEC, weight=Pt(1))
|
||||
|
||||
uw, uh = Inches(1.55), Inches(0.6)
|
||||
|
||||
|
||||
def ums_box(bx, yc, name, icon_fn):
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx, yc - uh / 2, uw, uh, fill=UMS, line=LINEC)
|
||||
icon_fn(bx + Inches(0.32), yc)
|
||||
txt(bx + Inches(0.58), yc - Inches(0.16), uw - Inches(0.64), Inches(0.32), name,
|
||||
size=12, color=INK, align=PP_ALIGN.LEFT)
|
||||
|
||||
|
||||
# Umsysteme links -> Adapter-Schichten am linken Kernrand
|
||||
lx = Inches(0.8)
|
||||
ums_box(lx, Inches(4.6), "Anlieferung", icon_truck)
|
||||
ums_box(lx, Inches(5.2), "DFÜ", icon_dfu)
|
||||
for yc in (Inches(4.6), Inches(5.2)):
|
||||
hline(lx + uw, yc, (core_x - g - th) - (lx + uw))
|
||||
|
||||
# Umsystem rechts -> Adapter-Linie am rechten Kernrand
|
||||
gx = Inches(6.65)
|
||||
ums_box(gx, Inches(4.9), "Geräte", icon_device)
|
||||
hline(core_x + core_w + g + th, Inches(4.9), gx - (core_x + core_w + g + th))
|
||||
|
||||
# ---- LIS-Kern -------------------------------------------------------------
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, core_x, core_y, core_w, core_h, fill=NAVY)
|
||||
sh = shp(MSO_SHAPE.ROUNDED_RECTANGLE, core_x, core_y, core_w, core_h, fill=NAVY)
|
||||
boxtext(sh, "LIS", size=22, color=WHITE, bold=True)
|
||||
|
||||
|
||||
# ---- 5 Adapter-Linien – je Schnittstelle eine, mit Abstand zum Kern -------
|
||||
def rbar_v(outer_x, yc, h=Inches(0.55)): # vertikal, linker/rechter Rand
|
||||
shp(MSO_SHAPE.RECTANGLE, outer_x, yc - h / 2, th, h, fill=ACCENT)
|
||||
|
||||
|
||||
def rbar_h(xc, outer_y, w): # horizontal, oben/unten
|
||||
shp(MSO_SHAPE.RECTANGLE, xc - w / 2, outer_y, w, th, fill=ACCENT)
|
||||
|
||||
|
||||
rbar_v(core_x - g - th, Inches(4.6)) # 1) Anlieferung
|
||||
rbar_v(core_x - g - th, Inches(5.2)) # 2) DFÜ
|
||||
rbar_h(core_cx, core_y - g - th, Inches(1.15)) # 3) nach oben (Steuerung)
|
||||
rbar_v(core_x + core_w + g, Inches(4.9)) # 4) Geräte
|
||||
rbar_h(core_cx, core_by + g, core_w - Inches(0.2)) # 5) Fachliche Verarbeitung
|
||||
|
||||
# Fachliche Verarbeitung (unten): Module an der unteren Adapter-Linie
|
||||
mw, mh = Inches(1.7), Inches(0.6)
|
||||
my = Inches(6.05)
|
||||
for nm, fill, tc, mcx in [("Hochdurchsatz", TINT_T, TEAL, Inches(3.85)),
|
||||
("Spezial", TINT_A, AMBER, Inches(5.85))]:
|
||||
vline(mcx, core_by + g + th, my - (core_by + g + th), color=LINEC, weight=Pt(1))
|
||||
sh = shp(MSO_SHAPE.ROUNDED_RECTANGLE, mcx - mw / 2, my, mw, mh, fill=fill, line=tc, lw=Pt(1.5))
|
||||
boxtext(sh, nm, size=12.5, color=INK, bold=True)
|
||||
|
||||
txt(Inches(2.9), my + mh + Inches(0.12), Inches(4.0), Inches(0.3), "Fachliche Verarbeitung",
|
||||
size=12, color=LIGHT, bold=True, align=PP_ALIGN.CENTER)
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
# WEITERE LIS – überlappend, nur angedeutet
|
||||
# ===========================================================================
|
||||
hw_, hh_ = Inches(1.8), Inches(2.0)
|
||||
|
||||
def mini_lis(hx, hy, faded=False):
|
||||
fill = RGBColor(0xF4, 0xF6, 0xF8) if faded else HINT
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, hx, hy, hw_, hh_, fill=fill, line=HINTL, lw=Pt(1.25))
|
||||
hdc = shp(MSO_SHAPE.ROUNDED_RECTANGLE, hx, hy, hw_, Inches(0.46),
|
||||
fill=HINTL if not faded else RGBColor(0xDF, 0xE4, 0xEA))
|
||||
boxtext(hdc, "LIS", size=14, color=NAVY, bold=True)
|
||||
for k in range(3):
|
||||
yy = hy + Inches(0.66) + k * Inches(0.4)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, hx + Inches(0.2), yy, hw_ - Inches(0.4),
|
||||
Inches(0.28), fill=WHITE, line=HINTL, lw=Pt(0.75))
|
||||
|
||||
mini_lis(Inches(10.5), Inches(4.35), faded=True)
|
||||
mini_lis(Inches(10.0), Inches(4.75), faded=False)
|
||||
vline(Inches(10.0) + hw_ / 2, gov_y + Inches(0.07), Inches(4.75) - (gov_y + Inches(0.07)),
|
||||
color=LINEC, weight=Pt(1))
|
||||
txt(Inches(9.9), Inches(4.35) + hh_ + Inches(0.2), Inches(2.4), Inches(0.35), "weitere LIS",
|
||||
size=13, color=LIGHT, align=PP_ALIGN.CENTER)
|
||||
|
||||
# ---- Mini-Legende ----------------------------------------------------------
|
||||
ly = Inches(7.05)
|
||||
shp(MSO_SHAPE.RECTANGLE, Inches(7.55), ly - Inches(0.11), th, Inches(0.22), fill=ACCENT)
|
||||
txt(Inches(7.8), ly - Inches(0.16), Inches(3.2), Inches(0.32),
|
||||
"Adapter-Schicht – je Schnittstelle eine", size=11.5, color=LIGHT)
|
||||
|
||||
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Folie3.pptx")
|
||||
prs.save(out)
|
||||
print("saved", out)
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Folie 4 (eingehängt nach Folie 3) – Architektur der Modularisierung:
|
||||
Modularer Monolith vs. Microservices, anschaulich im Containerumfeld.
|
||||
Links: 1 Container, Module mit In-Process-Calls, 1 geteilte DB.
|
||||
Rechts: N Container, Services über Netzwerk, DB je Service.
|
||||
Unten: kompakte Gegenüberstellung der wesentlichen Unterschiede."""
|
||||
|
||||
import os
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
||||
from pptx.enum.shapes import MSO_SHAPE
|
||||
from adesso_style import (WHITE, INK, BLUE, TEAL, GREEN, CORAL, LIGHT, MUTE, RECF,
|
||||
F, FC, paint_background, chrome)
|
||||
|
||||
NAVY = INK
|
||||
ACCENT = CORAL
|
||||
LINEC = LIGHT
|
||||
|
||||
prs = Presentation()
|
||||
prs.slide_width = Inches(13.333)
|
||||
prs.slide_height = Inches(7.5)
|
||||
s = prs.slides.add_slide(prs.slide_layouts[6])
|
||||
paint_background(s, prs.slide_width, prs.slide_height)
|
||||
|
||||
|
||||
def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), rot=0):
|
||||
sh = s.shapes.add_shape(kind, x, y, w, h)
|
||||
if fill is None: sh.fill.background()
|
||||
else: sh.fill.solid(); sh.fill.fore_color.rgb = fill
|
||||
if line is None: sh.line.fill.background()
|
||||
else: sh.line.color.rgb = line; sh.line.width = lw
|
||||
if rot: sh.rotation = rot
|
||||
sh.shadow.inherit = False
|
||||
return sh
|
||||
|
||||
|
||||
def boxtext(sh, t, size=14, color=INK, bold=False):
|
||||
tf = sh.text_frame; tf.word_wrap = True
|
||||
tf.vertical_anchor = MSO_ANCHOR.MIDDLE
|
||||
tf.margin_left = tf.margin_right = Pt(3); tf.margin_top = tf.margin_bottom = Pt(1)
|
||||
p = tf.paragraphs[0]; p.alignment = PP_ALIGN.CENTER
|
||||
r = p.add_run(); r.text = t
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.name = F; r.font.color.rgb = color
|
||||
|
||||
|
||||
def txt(x, y, w, h, t, size=14, color=INK, bold=False, italic=False,
|
||||
align=PP_ALIGN.LEFT, spc=None):
|
||||
tb = s.shapes.add_textbox(x, y, w, h); tf = tb.text_frame
|
||||
tf.word_wrap = True; tf.vertical_anchor = MSO_ANCHOR.MIDDLE
|
||||
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
p = tf.paragraphs[0]; p.alignment = align
|
||||
r = p.add_run(); r.text = t
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.italic = italic
|
||||
r.font.name = F; r.font.color.rgb = color
|
||||
if spc: r.font._rPr.set('spc', str(spc))
|
||||
return tb
|
||||
|
||||
|
||||
def vline(x, y, h, color=LINEC, weight=Pt(1.4)):
|
||||
shp(MSO_SHAPE.RECTANGLE, x - weight / 2, y, weight, h, fill=color)
|
||||
|
||||
|
||||
def hline(x, y, w, color=LINEC, weight=Pt(1.4)):
|
||||
shp(MSO_SHAPE.RECTANGLE, x, y - weight / 2, w, weight, fill=color)
|
||||
|
||||
|
||||
# ---- Kopf + Kernaussage ----------------------------------------------------
|
||||
chrome(s, "Architektur der Modularisierung", 4)
|
||||
txt(Inches(1.25), Inches(0.98), Inches(11.6), Inches(0.34),
|
||||
"Gleiche fachlichen Schnitte – der Unterschied ist die Laufzeit- und Deployment-Grenze.",
|
||||
size=14, color=LIGHT, italic=True)
|
||||
|
||||
DOT = [TEAL, GREEN, BLUE] # gleiche Module/Services beidseitig farblich verankert
|
||||
LET = ["A", "B", "C"]
|
||||
|
||||
# ===========================================================================
|
||||
# Spalten-Titel
|
||||
# ===========================================================================
|
||||
cL = Inches(3.6) # Mittelpunkt linke Spalte
|
||||
cR = Inches(9.75) # Mittelpunkt rechte Spalte
|
||||
|
||||
txt(Inches(0.95), Inches(1.5), Inches(5.3), Inches(0.32), "Modularer Monolith",
|
||||
size=18, color=WHITE, bold=True, align=PP_ALIGN.CENTER)
|
||||
txt(Inches(0.95), Inches(1.84), Inches(5.3), Inches(0.26), "1 Deployable · 1 Prozess",
|
||||
size=11.5, color=LIGHT, align=PP_ALIGN.CENTER)
|
||||
|
||||
txt(Inches(7.0), Inches(1.5), Inches(5.5), Inches(0.32), "Microservices",
|
||||
size=18, color=WHITE, bold=True, align=PP_ALIGN.CENTER)
|
||||
txt(Inches(7.0), Inches(1.84), Inches(5.5), Inches(0.26), "N Deployables · N Prozesse",
|
||||
size=11.5, color=LIGHT, align=PP_ALIGN.CENTER)
|
||||
|
||||
# ===========================================================================
|
||||
# LINKS – Modularer Monolith: 1 Container, Module, geteilte DB
|
||||
# ===========================================================================
|
||||
cx_x, cx_w, cx_y, cx_h = Inches(0.95), Inches(5.3), Inches(2.2), Inches(1.6)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, cx_x, cx_y, cx_w, cx_h, line=WHITE, lw=Pt(1.5))
|
||||
txt(cx_x + Inches(0.15), cx_y + Inches(0.05), Inches(2.0), Inches(0.26), "1 Container",
|
||||
size=11, color=LIGHT, bold=True)
|
||||
|
||||
mw, mh, my = Inches(1.35), Inches(0.8), Inches(2.62)
|
||||
mcx = [Inches(2.05), Inches(3.6), Inches(5.15)]
|
||||
for i, mx in enumerate(mcx):
|
||||
sh = shp(MSO_SHAPE.ROUNDED_RECTANGLE, mx - mw / 2, my, mw, mh, fill=WHITE, line=LINEC, lw=Pt(1))
|
||||
boxtext(sh, "Modul " + LET[i], size=13, color=INK, bold=True)
|
||||
shp(MSO_SHAPE.OVAL, mx - Inches(0.07), my + Inches(0.12), Inches(0.14), Inches(0.14), fill=DOT[i])
|
||||
# In-Process-Pfeile zwischen den Modulen
|
||||
for ax in (Inches(2.725), Inches(4.275)):
|
||||
shp(MSO_SHAPE.RIGHT_ARROW, ax, my + mh / 2 - Inches(0.09), Inches(0.2), Inches(0.18), fill=ACCENT)
|
||||
txt(cx_x, cx_y + cx_h - Inches(0.34), cx_w, Inches(0.26), "In-Process-Aufrufe · Nanosekunden",
|
||||
size=11, color=LIGHT, align=PP_ALIGN.CENTER)
|
||||
|
||||
# geteilte Datenbank
|
||||
db_w, db_h, db_y = Inches(1.5), Inches(0.95), Inches(4.0)
|
||||
vline(cL, cx_y + cx_h, db_y - (cx_y + cx_h), color=LINEC, weight=Pt(1.4))
|
||||
sh = shp(MSO_SHAPE.CAN, cL - db_w / 2, db_y, db_w, db_h, fill=WHITE, line=LINEC, lw=Pt(1))
|
||||
boxtext(sh, "DB", size=14, color=INK, bold=True)
|
||||
txt(cx_x, db_y + db_h + Inches(0.06), cx_w, Inches(0.28), "1 geteilte Datenbank",
|
||||
size=12.5, color=WHITE, bold=True, align=PP_ALIGN.CENTER)
|
||||
|
||||
# ===========================================================================
|
||||
# RECHTS – Microservices: Netzwerk-Bus, N Container, DB je Service
|
||||
# ===========================================================================
|
||||
bar_x, bar_w, bar_y, bar_h = Inches(7.1), Inches(5.3), Inches(2.2), Inches(0.26)
|
||||
bar = shp(MSO_SHAPE.ROUNDED_RECTANGLE, bar_x, bar_y, bar_w, bar_h, fill=NAVY)
|
||||
boxtext(bar, "Netzwerk-Grenze · HTTP / gRPC / Events", size=11, color=WHITE, bold=True)
|
||||
|
||||
scx = [Inches(7.95), Inches(9.75), Inches(11.55)]
|
||||
sc_w, sc_h, sc_y = Inches(1.5), Inches(1.2), Inches(2.62)
|
||||
sdb_w, sdb_h, sdb_y = Inches(0.85), Inches(0.7), Inches(3.97)
|
||||
for i, cx in enumerate(scx):
|
||||
vline(cx, bar_y + bar_h, sc_y - (bar_y + bar_h), color=LINEC, weight=Pt(1.1))
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, cx - sc_w / 2, sc_y, sc_w, sc_h, line=WHITE, lw=Pt(1.5))
|
||||
sh = shp(MSO_SHAPE.ROUNDED_RECTANGLE, cx - Inches(0.55), sc_y + Inches(0.3),
|
||||
Inches(1.1), Inches(0.62), fill=WHITE, line=LINEC, lw=Pt(1))
|
||||
boxtext(sh, "Svc " + LET[i], size=12.5, color=INK, bold=True)
|
||||
shp(MSO_SHAPE.OVAL, cx - Inches(0.06), sc_y + Inches(0.4), Inches(0.12), Inches(0.12), fill=DOT[i])
|
||||
# eigene DB je Service
|
||||
vline(cx, sc_y + sc_h, sdb_y - (sc_y + sc_h), color=LINEC, weight=Pt(1.1))
|
||||
sh = shp(MSO_SHAPE.CAN, cx - sdb_w / 2, sdb_y, sdb_w, sdb_h, fill=WHITE, line=LINEC, lw=Pt(1))
|
||||
boxtext(sh, "DB", size=11, color=INK, bold=True)
|
||||
txt(bar_x, sdb_y + sdb_h + Inches(0.06), bar_w, Inches(0.28), "Datenbank je Service",
|
||||
size=12.5, color=WHITE, bold=True, align=PP_ALIGN.CENTER)
|
||||
|
||||
# ===========================================================================
|
||||
# Trenner + vs.
|
||||
# ===========================================================================
|
||||
vline(Inches(6.65), Inches(1.55), Inches(3.5), color=LINEC, weight=Pt(1))
|
||||
vs = shp(MSO_SHAPE.OVAL, Inches(6.65) - Inches(0.31), Inches(3.05), Inches(0.62), Inches(0.46),
|
||||
line=WHITE, lw=Pt(1.5))
|
||||
vs.fill.background()
|
||||
boxtext(vs, "vs.", size=13, color=WHITE, bold=True)
|
||||
|
||||
# ===========================================================================
|
||||
# Gegenüberstellung – wesentliche Unterschiede
|
||||
# ===========================================================================
|
||||
rows = [
|
||||
("Skalierung", "als Ganzes (mehr Replicas)", "je Service gezielt"),
|
||||
("Datenhaltung", "1 geteilte DB", "DB je Service"),
|
||||
("Deployment", "gemeinsam, 1 Pipeline", "unabhängig je Service"),
|
||||
("Konsistenz", "ACID, lokal", "eventual / Saga"),
|
||||
]
|
||||
ry = Inches(5.5)
|
||||
rh = Inches(0.33)
|
||||
chip_w = Inches(1.95)
|
||||
for i, (dim, mono, ms) in enumerate(rows):
|
||||
y = ry + rh * i
|
||||
chip = shp(MSO_SHAPE.ROUNDED_RECTANGLE, Inches(6.65) - chip_w / 2, y, chip_w, Inches(0.28),
|
||||
line=LINEC, lw=Pt(0.75))
|
||||
chip.fill.background()
|
||||
boxtext(chip, dim, size=11, color=LIGHT, bold=True)
|
||||
txt(Inches(2.5), y - Inches(0.02), Inches(3.1), Inches(0.32), mono,
|
||||
size=12, color=WHITE, align=PP_ALIGN.RIGHT)
|
||||
txt(Inches(7.72), y - Inches(0.02), Inches(3.1), Inches(0.32), ms,
|
||||
size=12, color=WHITE, align=PP_ALIGN.LEFT)
|
||||
|
||||
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Folie3b.pptx")
|
||||
prs.save(out)
|
||||
print("saved", out)
|
||||
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Folie 4 – Eventstream als Quelle; Aussagen links, Lupen rechts, Strecke unten
|
||||
(adesso-Styling)."""
|
||||
|
||||
import os
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
||||
from pptx.enum.shapes import MSO_SHAPE
|
||||
from adesso_style import (WHITE, INK, BLUE, TEAL, GREEN, CORAL, LIGHT, RECF, F, FC,
|
||||
paint_background, chrome)
|
||||
|
||||
# Rollen-Mapping auf die adesso-Palette
|
||||
NAVY = INK # dunkle Füllungen (Lupe, Maschine)
|
||||
ACCENT = CORAL
|
||||
AMBER = GREEN
|
||||
GLASS = RECF
|
||||
BELT = RECF
|
||||
DARK = INK
|
||||
LINEC = LIGHT
|
||||
THIN = LIGHT
|
||||
STREAM = INK
|
||||
MID = RGBColor(0x34, 0x4E, 0x70)
|
||||
|
||||
prs = Presentation()
|
||||
prs.slide_width = Inches(13.333)
|
||||
prs.slide_height = Inches(7.5)
|
||||
SW, SH = prs.slide_width, prs.slide_height
|
||||
s = prs.slides.add_slide(prs.slide_layouts[6])
|
||||
|
||||
|
||||
def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), rot=0):
|
||||
sh = s.shapes.add_shape(kind, x, y, w, h)
|
||||
if fill is None: sh.fill.background()
|
||||
else: sh.fill.solid(); sh.fill.fore_color.rgb = fill
|
||||
if line is None: sh.line.fill.background()
|
||||
else: sh.line.color.rgb = line; sh.line.width = lw
|
||||
if rot: sh.rotation = rot
|
||||
sh.shadow.inherit = False
|
||||
return sh
|
||||
|
||||
|
||||
def txt(x, y, w, h, t, size=16, color=WHITE, bold=False, italic=False,
|
||||
align=PP_ALIGN.LEFT, spc=None, font=F):
|
||||
tb = s.shapes.add_textbox(x, y, w, h); tf = tb.text_frame
|
||||
tf.word_wrap = True; tf.vertical_anchor = MSO_ANCHOR.MIDDLE
|
||||
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
p = tf.paragraphs[0]; p.alignment = align
|
||||
r = p.add_run(); r.text = t
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.italic = italic
|
||||
r.font.name = font; r.font.color.rgb = color
|
||||
if spc: r.font._rPr.set('spc', str(spc))
|
||||
return tb
|
||||
|
||||
|
||||
paint_background(s, SW, SH)
|
||||
chrome(s, "Zustand oder Ereignis", 5)
|
||||
|
||||
x0, x1 = Inches(1.0), Inches(12.33)
|
||||
beltw = x1 - x0
|
||||
|
||||
# ---- Aussagen links --------------------------------------------------------
|
||||
claims = [
|
||||
"Eventstream = einzige Quelle der Wahrheit",
|
||||
"kann nicht überschrieben werden",
|
||||
"vollständige 3D-Sicht auf Maschine / Strang",
|
||||
]
|
||||
cy = Inches(1.95)
|
||||
for i, c in enumerate(claims):
|
||||
y = cy + Inches(0.6) * i
|
||||
shp(MSO_SHAPE.RECTANGLE, Inches(0.95), y + Inches(0.1), Inches(0.14), Inches(0.14), fill=ACCENT)
|
||||
txt(Inches(1.28), y, Inches(4.6), Inches(0.45), c, size=16.5, color=WHITE, bold=(i == 0))
|
||||
|
||||
# ===========================================================================
|
||||
# LUPEN (Projektionen)
|
||||
# ===========================================================================
|
||||
def lupe(cx, label, label_w):
|
||||
cyy = Inches(2.45)
|
||||
d = Inches(0.9)
|
||||
shp(MSO_SHAPE.OVAL, cx - d / 2, cyy - d / 2, d, d, fill=WHITE, line=NAVY, lw=Pt(4))
|
||||
shp(MSO_SHAPE.OVAL, cx - d / 2 + Inches(0.13), cyy - d / 2 + Inches(0.12),
|
||||
Inches(0.17), Inches(0.13), fill=RECF)
|
||||
hw, hh = Inches(0.48), Inches(0.15)
|
||||
hcx, hcy = cx + d * 0.52, cyy + d * 0.52
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, hcx - hw / 2, hcy - hh / 2, hw, hh, fill=NAVY, rot=45)
|
||||
txt(cx - label_w / 2, cyy + d / 2 + Inches(0.16), label_w, Inches(0.6),
|
||||
label, size=14, color=WHITE, bold=True, align=PP_ALIGN.CENTER)
|
||||
return cyy + d / 2
|
||||
|
||||
|
||||
lupes = [
|
||||
(Inches(7.05), "Gruppen-Reporting", Inches(2.3)),
|
||||
(Inches(9.45), "Optimierung der Auslastung", Inches(2.3)),
|
||||
(Inches(11.55), "Abrechnungen", Inches(1.9)),
|
||||
]
|
||||
lens_bottoms = [lupe(cx, lb, lw) for cx, lb, lw in lupes]
|
||||
|
||||
# ===========================================================================
|
||||
# EVENTSTREAM (Pfeil)
|
||||
# ===========================================================================
|
||||
ay, ah = Inches(4.45), Inches(0.46)
|
||||
shp(MSO_SHAPE.RIGHT_ARROW, x0, ay, beltw, ah, fill=STREAM)
|
||||
acx = ay + ah / 2
|
||||
txt(Inches(5.65), ay + Inches(0.04), Inches(2.0), ah - Inches(0.08),
|
||||
"Eventstream", size=14, color=WHITE, bold=True, align=PP_ALIGN.CENTER)
|
||||
|
||||
# Verbinder Lupe -> Strom
|
||||
for (cx, _, _), lb_y in zip(lupes, lens_bottoms):
|
||||
shp(MSO_SHAPE.RECTANGLE, cx - Pt(0.5), lb_y, Pt(1), ay - lb_y, fill=LINEC)
|
||||
|
||||
# ===========================================================================
|
||||
# RÖHRCHEN-STRECKE durch Maschine – unten
|
||||
# ===========================================================================
|
||||
belt_top = Inches(6.1)
|
||||
belt_h = Inches(0.30)
|
||||
|
||||
for rx in (x0 - Inches(0.18), x1 - Inches(0.32)):
|
||||
shp(MSO_SHAPE.OVAL, rx, belt_top - Inches(0.10), Inches(0.5), Inches(0.5),
|
||||
fill=BELT, line=LINEC)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x0, belt_top, beltw, belt_h, fill=BELT)
|
||||
|
||||
mx, mw = Inches(5.45), Inches(2.45)
|
||||
my, mh = Inches(5.2), Inches(1.5)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, mx, my, mw, mh, fill=NAVY)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, mx + Inches(0.3), my + Inches(0.22),
|
||||
mw - Inches(0.6), Inches(0.32), fill=MID)
|
||||
shp(MSO_SHAPE.OVAL, mx + Inches(0.35), my + Inches(0.74), Inches(0.15), Inches(0.15), fill=TEAL)
|
||||
shp(MSO_SHAPE.OVAL, mx + Inches(0.6), my + Inches(0.74), Inches(0.15), Inches(0.15), fill=AMBER)
|
||||
shp(MSO_SHAPE.RECTANGLE, mx - Inches(0.02), belt_top - Inches(0.02),
|
||||
Inches(0.14), belt_h + Inches(0.04), fill=DARK)
|
||||
shp(MSO_SHAPE.RECTANGLE, mx + mw - Inches(0.12), belt_top - Inches(0.02),
|
||||
Inches(0.14), belt_h + Inches(0.04), fill=DARK)
|
||||
|
||||
|
||||
def tube(cx, liquid):
|
||||
bw, bh = Inches(0.22), Inches(0.6)
|
||||
bx, by = cx - bw / 2, belt_top - bh
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx, by, bw, bh, fill=GLASS, line=LINEC, lw=Pt(0.75))
|
||||
lh = Inches(0.25)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, bx + Pt(1), belt_top - lh, bw - Pt(2), lh, fill=liquid)
|
||||
cw, ch = Inches(0.26), Inches(0.12)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, cx - cw / 2, by - Inches(0.06), cw, ch, fill=DARK)
|
||||
|
||||
|
||||
cols = [ACCENT, TEAL, AMBER]
|
||||
pre_x = [1.55, 2.1, 2.65, 3.2, 3.75, 4.3, 4.85]
|
||||
post_x = [8.25, 8.8, 9.35, 9.9, 10.45, 11.0]
|
||||
for i, xv in enumerate(pre_x + post_x):
|
||||
tube(Inches(xv), cols[i % 3])
|
||||
|
||||
tube_top = belt_top - Inches(0.6)
|
||||
for xv in pre_x + post_x:
|
||||
shp(MSO_SHAPE.RECTANGLE, Inches(xv) - Pt(0.4), ay + ah,
|
||||
Pt(0.8), tube_top - (ay + ah), fill=THIN)
|
||||
shp(MSO_SHAPE.OVAL, Inches(xv) - Inches(0.05), acx - Inches(0.05),
|
||||
Inches(0.1), Inches(0.1), fill=AMBER)
|
||||
|
||||
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Folie4.pptx")
|
||||
prs.save(out)
|
||||
print("saved", out)
|
||||
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Folie 5 – Event Sourcing: das groessere Bild (DEUTSCH).
|
||||
Quellen differenziert (Publisher / Subsysteme), Event-Prozessoren als Teil des Stores,
|
||||
Hot Store & Cold Store als Kernfunktion (Coral, CORE-Tag), Projektionen dazwischen,
|
||||
darunter Cold Store / Monitoring / Reporting. Tech-Impls als Chips. (adesso-Styling)
|
||||
Hintergrund: solides dunkles Blau (BG) – Farbe frei anpassbar."""
|
||||
|
||||
import os
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
||||
from pptx.enum.shapes import MSO_SHAPE
|
||||
from adesso_style import (WHITE, INK, BLUE, TEAL, GREEN, CORAL, LIGHT, MUTE, RECF,
|
||||
F, FC, chrome)
|
||||
|
||||
# ---- Hintergrundfarbe (solid, keine Transparenz) – frei anpassbar ----------
|
||||
BG = RGBColor(0x0A, 0x3D, 0x6B) # dunkles Blau
|
||||
|
||||
prs = Presentation()
|
||||
prs.slide_width = Inches(13.333)
|
||||
prs.slide_height = Inches(7.5)
|
||||
SW, SH = prs.slide_width, prs.slide_height
|
||||
s = prs.slides.add_slide(prs.slide_layouts[6])
|
||||
|
||||
|
||||
def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), rot=0, adj=None):
|
||||
sh = s.shapes.add_shape(kind, x, y, w, h)
|
||||
if fill is None: sh.fill.background()
|
||||
else: sh.fill.solid(); sh.fill.fore_color.rgb = fill
|
||||
if line is None: sh.line.fill.background()
|
||||
else: sh.line.color.rgb = line; sh.line.width = lw
|
||||
if rot: sh.rotation = rot
|
||||
if adj is not None:
|
||||
try: sh.adjustments[0] = adj
|
||||
except Exception: pass
|
||||
sh.shadow.inherit = False
|
||||
return sh
|
||||
|
||||
|
||||
def txt(x, y, w, h, t, size=16, color=WHITE, bold=False, italic=False,
|
||||
align=PP_ALIGN.LEFT, font=F, anchor=MSO_ANCHOR.MIDDLE):
|
||||
tb = s.shapes.add_textbox(x, y, w, h); tf = tb.text_frame
|
||||
tf.word_wrap = True; tf.vertical_anchor = anchor
|
||||
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
first = True
|
||||
for line in t.split("\n"):
|
||||
p = tf.paragraphs[0] if first else tf.add_paragraph()
|
||||
first = False
|
||||
p.alignment = align
|
||||
r = p.add_run(); r.text = line
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.italic = italic
|
||||
r.font.name = font; r.font.color.rgb = color
|
||||
return tb
|
||||
|
||||
|
||||
def chip(cx, y, text, fill=INK, fg=WHITE, size=11):
|
||||
"""Tech-Impl als kleine Pill, zentriert um cx."""
|
||||
w = Inches(0.34 + 0.092 * len(text)); h = Inches(0.30)
|
||||
x = cx - w / 2
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, y, w, h, fill=fill, adj=0.5)
|
||||
txt(x, y, w, h, text, size=size, color=fg, bold=False,
|
||||
align=PP_ALIGN.CENTER, font=FC)
|
||||
|
||||
|
||||
def core_tag(x, y):
|
||||
w, h = Inches(0.62), Inches(0.26)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, y, w, h, fill=INK, adj=0.5)
|
||||
txt(x, y, w, h, "CORE", size=9.5, color=TEAL, bold=True,
|
||||
align=PP_ALIGN.CENTER, font=FC)
|
||||
|
||||
|
||||
# ---- solider Hintergrund (zuerst -> liegt hinten) --------------------------
|
||||
bg = shp(MSO_SHAPE.RECTANGLE, 0, 0, SW, SH, fill=BG)
|
||||
|
||||
chrome(s, "System Landscape", 6)
|
||||
|
||||
CX = Inches(6.665) # Folienmitte (x)
|
||||
|
||||
# ---- Quellen: differenziert ------------------------------------------------
|
||||
src_y, src_h = Inches(1.36), Inches(0.92)
|
||||
|
||||
|
||||
def source_box(x, w, title, examples):
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, src_y, w, src_h, fill=WHITE, adj=0.10)
|
||||
txt(x + Inches(0.28), src_y + Inches(0.10), w - Inches(0.56), Inches(0.32),
|
||||
title, size=14.5, color=INK, bold=True, anchor=MSO_ANCHOR.TOP)
|
||||
txt(x + Inches(0.28), src_y + Inches(0.46), w - Inches(0.56), Inches(0.36),
|
||||
examples, size=12, color=MUTE, anchor=MSO_ANCHOR.TOP)
|
||||
|
||||
|
||||
pub_x, pub_w = Inches(0.9), Inches(5.6)
|
||||
sub_x, sub_w = Inches(6.83), Inches(5.6)
|
||||
pub_cx = pub_x + pub_w / 2
|
||||
sub_cx = sub_x + sub_w / 2
|
||||
|
||||
source_box(pub_x, pub_w, "Publisher (nur publizieren)",
|
||||
"z. B. AB+M · LabAccess · MDN · Stammdaten — proprietär")
|
||||
source_box(sub_x, sub_w, "Subsysteme (konsumieren & publizieren)",
|
||||
"z. B. LIS · Geräte / Analyzer — proprietär")
|
||||
|
||||
# ---- Pfeile Quellen -> Hot Store ------------------------------------------
|
||||
ay, ah = src_y + src_h + Inches(0.02), Inches(0.30)
|
||||
shp(MSO_SHAPE.DOWN_ARROW, pub_cx - Inches(0.16), ay, Inches(0.32), ah, fill=CORAL)
|
||||
txt(pub_cx + Inches(0.28), ay - Inches(0.01), Inches(1.6), ah + Inches(0.02),
|
||||
"publizieren", size=11, color=LIGHT, italic=True)
|
||||
shp(MSO_SHAPE.UP_DOWN_ARROW, sub_cx - Inches(0.11), ay - Inches(0.05), Inches(0.22),
|
||||
ah + Inches(0.10), fill=CORAL)
|
||||
txt(sub_cx - Inches(2.85), ay - Inches(0.01), Inches(2.5), ah + Inches(0.02),
|
||||
"konsumieren & publizieren", size=11, color=LIGHT, italic=True, align=PP_ALIGN.RIGHT)
|
||||
|
||||
# ---- HOT STORE (Kern) + Event-Prozessoren (Teil des Stores) ----------------
|
||||
hx, hy, hw, hh = Inches(3.4), Inches(2.62), Inches(6.53), Inches(1.50)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, hx, hy, hw, hh, fill=CORAL, line=INK, lw=Pt(3.5), adj=0.07)
|
||||
core_tag(hx + Inches(0.16), hy + Inches(0.13))
|
||||
txt(hx, hy + Inches(0.05), hw, Inches(0.34),
|
||||
"Event Store — Hot Store", size=20, color=INK, bold=True, align=PP_ALIGN.CENTER)
|
||||
txt(hx, hy + Inches(0.40), hw, Inches(0.20),
|
||||
"append-only · kanonische Wahrheit", size=12.5, color=INK, align=PP_ALIGN.CENTER)
|
||||
chip(CX, hy + Inches(0.62), "z. B. Kafka")
|
||||
|
||||
# Event-Prozessoren als eingebetteter Bestandteil des Stores
|
||||
ep_x, ep_y, ep_w, ep_h = hx + Inches(0.28), hy + Inches(0.98), hw - Inches(0.56), Inches(0.44)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, ep_x, ep_y, ep_w, ep_h, fill=WHITE, adj=0.22)
|
||||
txt(ep_x, ep_y, ep_w, ep_h,
|
||||
"Event-Prozessoren (konsumieren & publizieren) · z. B. Proben-Routing",
|
||||
size=11.5, color=INK, bold=True, align=PP_ALIGN.CENTER)
|
||||
|
||||
# ---- Hot -> Projektionen ---------------------------------------------------
|
||||
shp(MSO_SHAPE.DOWN_ARROW, CX - Inches(0.16), hy + hh + Inches(0.03),
|
||||
Inches(0.32), Inches(0.28), fill=CORAL)
|
||||
|
||||
# ---- PROJEKTIONEN ----------------------------------------------------------
|
||||
px, py, pw, ph = Inches(3.4), Inches(4.46), Inches(6.53), Inches(0.66)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, px, py, pw, ph, fill=WHITE, adj=0.14)
|
||||
txt(px + Inches(0.3), py, Inches(3.0), ph, "Projektionen", size=16, color=INK, bold=True)
|
||||
chip(px + pw - Inches(2.0), py + ph / 2 - Inches(0.15), "Kafka Streams → PostgreSQL")
|
||||
|
||||
# ---- Verteiler (Projektionen -> 3 Bloecke) --------------------------------
|
||||
boxes_y = Inches(5.34)
|
||||
bw = Inches(3.7); bh = Inches(1.56)
|
||||
cold_x = Inches(0.9); cold_cx = cold_x + bw / 2
|
||||
mon_x = Inches(4.815); mon_cx = mon_x + bw / 2
|
||||
rep_x = Inches(8.73); rep_cx = rep_x + bw / 2
|
||||
|
||||
bus_y = py + ph + Inches(0.10)
|
||||
shp(MSO_SHAPE.RECTANGLE, CX - Pt(0.75), py + ph, Pt(1.5), bus_y - (py + ph), fill=LIGHT)
|
||||
shp(MSO_SHAPE.RECTANGLE, cold_cx, bus_y, rep_cx - cold_cx, Pt(1.5), fill=LIGHT)
|
||||
for cx in (cold_cx, mon_cx, rep_cx):
|
||||
shp(MSO_SHAPE.DOWN_ARROW, cx - Inches(0.11), bus_y, Inches(0.22), boxes_y - bus_y,
|
||||
fill=LIGHT)
|
||||
|
||||
|
||||
def block(x, title, body, tech, core=False):
|
||||
fill = CORAL if core else WHITE
|
||||
line = INK if core else None
|
||||
lw = Pt(3.5) if core else Pt(1)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, boxes_y, bw, bh, fill=fill, line=line, lw=lw, adj=0.07)
|
||||
ty = boxes_y + (Inches(0.30) if core else Inches(0.20))
|
||||
if core:
|
||||
core_tag(x + Inches(0.16), boxes_y + Inches(0.16))
|
||||
txt(x, ty, bw, Inches(0.42), title, size=17, color=INK, bold=True, align=PP_ALIGN.CENTER)
|
||||
txt(x + Inches(0.25), ty + Inches(0.46), bw - Inches(0.5), Inches(0.5), body,
|
||||
size=12.5, color=(INK if core else MUTE), align=PP_ALIGN.CENTER)
|
||||
chip(x + bw / 2, boxes_y + bh - Inches(0.42), tech)
|
||||
|
||||
|
||||
block(cold_x, "Cold Store",
|
||||
"Archiv · Audit-Trail · Dokumente", "z. B. PostgreSQL", core=True)
|
||||
block(mon_x, "Monitoring",
|
||||
"Auftragsstatus / Auslastung", "z. B. Grafana")
|
||||
block(rep_x, "Reporting",
|
||||
"Bericht an Gruppe · KPIs", "z. B. Power BI")
|
||||
|
||||
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Folie5.pptx")
|
||||
prs.save(out)
|
||||
print("saved", out)
|
||||
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Folie 6 – Core / Rationale (DEUTSCH): kompakte Landscape links, Argumente als Karten rechts.
|
||||
(adesso-Styling). Hintergrund: solides dunkles Blau (BG) – Farbe frei anpassbar."""
|
||||
|
||||
import os
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
||||
from pptx.enum.shapes import MSO_SHAPE
|
||||
from adesso_style import (WHITE, INK, BLUE, TEAL, GREEN, CORAL, LIGHT, MUTE, RECF,
|
||||
F, FC, chrome)
|
||||
|
||||
# ---- Hintergrundfarbe (solid, keine Transparenz) – frei anpassbar ----------
|
||||
BG = RGBColor(0x0A, 0x3D, 0x6B) # dunkles Blau
|
||||
|
||||
prs = Presentation()
|
||||
prs.slide_width = Inches(13.333)
|
||||
prs.slide_height = Inches(7.5)
|
||||
SW, SH = prs.slide_width, prs.slide_height
|
||||
s = prs.slides.add_slide(prs.slide_layouts[6])
|
||||
|
||||
|
||||
def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), rot=0, adj=None):
|
||||
sh = s.shapes.add_shape(kind, x, y, w, h)
|
||||
if fill is None: sh.fill.background()
|
||||
else: sh.fill.solid(); sh.fill.fore_color.rgb = fill
|
||||
if line is None: sh.line.fill.background()
|
||||
else: sh.line.color.rgb = line; sh.line.width = lw
|
||||
if rot: sh.rotation = rot
|
||||
if adj is not None:
|
||||
try: sh.adjustments[0] = adj
|
||||
except Exception: pass
|
||||
sh.shadow.inherit = False
|
||||
return sh
|
||||
|
||||
|
||||
def txt(x, y, w, h, t, size=16, color=WHITE, bold=False, italic=False,
|
||||
align=PP_ALIGN.LEFT, font=F, anchor=MSO_ANCHOR.MIDDLE, sp=None):
|
||||
tb = s.shapes.add_textbox(x, y, w, h); tf = tb.text_frame
|
||||
tf.word_wrap = True; tf.vertical_anchor = anchor
|
||||
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
first = True
|
||||
for line in t.split("\n"):
|
||||
p = tf.paragraphs[0] if first else tf.add_paragraph()
|
||||
first = False
|
||||
p.alignment = align
|
||||
if sp is not None: p.space_after = Pt(sp)
|
||||
r = p.add_run(); r.text = line
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.italic = italic
|
||||
r.font.name = font; r.font.color.rgb = color
|
||||
return tb
|
||||
|
||||
|
||||
def chip(cx, y, text, size=10):
|
||||
w = Inches(0.30 + 0.085 * len(text)); h = Inches(0.27)
|
||||
x = cx - w / 2
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, y, w, h, fill=INK, adj=0.5)
|
||||
txt(x, y, w, h, text, size=size, color=WHITE, align=PP_ALIGN.CENTER, font=FC)
|
||||
|
||||
|
||||
def core_tag(x, y):
|
||||
w, h = Inches(0.54), Inches(0.23)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, y, w, h, fill=INK, adj=0.5)
|
||||
txt(x, y, w, h, "CORE", size=8.5, color=TEAL, bold=True, align=PP_ALIGN.CENTER, font=FC)
|
||||
|
||||
|
||||
# ---- solider Hintergrund (zuerst -> liegt hinten) --------------------------
|
||||
bg = shp(MSO_SHAPE.RECTANGLE, 0, 0, SW, SH, fill=BG)
|
||||
|
||||
chrome(s, "Warum Event Sourcing passt", 7)
|
||||
|
||||
# ===========================================================================
|
||||
# LINKS – kompakte Landscape
|
||||
# ===========================================================================
|
||||
LCX = Inches(3.35)
|
||||
|
||||
# Quellen
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, Inches(0.7), Inches(1.58), Inches(5.3), Inches(0.7),
|
||||
fill=WHITE, adj=0.12)
|
||||
txt(Inches(0.92), Inches(1.66), Inches(4.9), Inches(0.26), "Quellen",
|
||||
size=12.5, color=INK, bold=True, anchor=MSO_ANCHOR.TOP)
|
||||
txt(Inches(0.92), Inches(1.94), Inches(4.9), Inches(0.28),
|
||||
"Publisher (publizieren) · Subsysteme (konsumieren & publizieren)",
|
||||
size=10.5, color=MUTE, anchor=MSO_ANCHOR.TOP)
|
||||
|
||||
shp(MSO_SHAPE.DOWN_ARROW, LCX - Inches(0.13), Inches(2.30), Inches(0.26), Inches(0.26),
|
||||
fill=CORAL)
|
||||
|
||||
# Hot Store (CORE) inkl. Event-Prozessoren
|
||||
hy, hh = Inches(2.58), Inches(0.98)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, Inches(1.35), hy, Inches(4.0), hh,
|
||||
fill=CORAL, line=INK, lw=Pt(3), adj=0.08)
|
||||
core_tag(Inches(1.50), hy + Inches(0.12))
|
||||
txt(Inches(1.35), hy + Inches(0.08), Inches(4.0), Inches(0.34),
|
||||
"Event Store — Hot Store", size=15, color=INK, bold=True, align=PP_ALIGN.CENTER)
|
||||
txt(Inches(1.35), hy + Inches(0.40), Inches(4.0), Inches(0.24),
|
||||
"inkl. Event-Prozessoren", size=10.5, color=INK, align=PP_ALIGN.CENTER)
|
||||
chip(LCX, hy + hh - Inches(0.34), "Kafka")
|
||||
|
||||
shp(MSO_SHAPE.DOWN_ARROW, LCX - Inches(0.13), hy + hh + Inches(0.02),
|
||||
Inches(0.26), Inches(0.24), fill=CORAL)
|
||||
|
||||
# Projektionen
|
||||
py, ph = Inches(3.82), Inches(0.56)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, Inches(1.35), py, Inches(4.0), ph, fill=WHITE, adj=0.16)
|
||||
txt(Inches(1.55), py, Inches(2.0), ph, "Projektionen", size=12.5, color=INK, bold=True)
|
||||
chip(Inches(4.25), py + ph / 2 - Inches(0.135), "Kafka Streams → PostgreSQL")
|
||||
|
||||
# Verteiler -> 3 Bloecke
|
||||
boxes_y = Inches(4.72); mbh = Inches(1.28)
|
||||
mb_w = Inches(1.65)
|
||||
cold_x = Inches(0.7); cold_cx = cold_x + mb_w / 2
|
||||
mon_x = Inches(2.55); mon_cx = mon_x + mb_w / 2
|
||||
rep_x = Inches(4.40); rep_cx = rep_x + mb_w / 2
|
||||
bus_y = py + ph + Inches(0.10)
|
||||
shp(MSO_SHAPE.RECTANGLE, LCX - Pt(0.75), py + ph, Pt(1.5), bus_y - (py + ph), fill=LIGHT)
|
||||
shp(MSO_SHAPE.RECTANGLE, cold_cx, bus_y, rep_cx - cold_cx, Pt(1.5), fill=LIGHT)
|
||||
for cx in (cold_cx, mon_cx, rep_cx):
|
||||
shp(MSO_SHAPE.DOWN_ARROW, cx - Inches(0.10), bus_y, Inches(0.20), boxes_y - bus_y, fill=LIGHT)
|
||||
|
||||
|
||||
def minibox(x, title, tech, core=False):
|
||||
fill = CORAL if core else WHITE
|
||||
line = INK if core else None
|
||||
lw = Pt(3) if core else Pt(1)
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, boxes_y, mb_w, mbh, fill=fill, line=line, lw=lw, adj=0.10)
|
||||
if core:
|
||||
core_tag(x + Inches(0.12), boxes_y + Inches(0.12))
|
||||
txt(x, boxes_y + (Inches(0.42) if core else Inches(0.26)), mb_w, Inches(0.5), title,
|
||||
size=12, color=INK, bold=True, align=PP_ALIGN.CENTER)
|
||||
chip(x + mb_w / 2, boxes_y + mbh - Inches(0.36), tech)
|
||||
|
||||
|
||||
minibox(cold_x, "Cold\nStore", "PostgreSQL", core=True)
|
||||
minibox(mon_x, "Monitoring", "Grafana")
|
||||
minibox(rep_x, "Reporting", "Power BI")
|
||||
|
||||
# ===========================================================================
|
||||
# RECHTS – Argumente als Karten
|
||||
# ===========================================================================
|
||||
cards = [
|
||||
("Bewährte Technologie",
|
||||
"Erprobt in regulierten Branchen mit hohem Volumen — z. B. ING setzt auf Kafka / Event-Streaming."),
|
||||
("Flexibel",
|
||||
"Neues System = neuer Adapter, ohne Eingriff in den Rest. Neue Event-Folgen & Projektionen jederzeit baubar."),
|
||||
("Skalierbar",
|
||||
"Selbst massive Lastzunahme wird durch mehr Hardware aufgefangen — horizontal, ohne Redesign."),
|
||||
("Kosteneffizient",
|
||||
"Wiederverwendbare Adapter statt Punkt-zu-Punkt. Open Source auf Standard-Hardware — kein Lock-in."),
|
||||
("Auditierbar & revisionssicher",
|
||||
"Append-only, vollständige & manipulationssichere Historie — vollständig replay-fähig."),
|
||||
("Resilient & entkoppelt",
|
||||
"Systeme fallen aus und holen per Replay auf; ein Log statt N² Schnittstellen."),
|
||||
]
|
||||
|
||||
cw, ch = Inches(3.0), Inches(1.42)
|
||||
col_x = [Inches(6.55), Inches(9.8)]
|
||||
row_y = [Inches(1.62), Inches(3.30), Inches(4.98)]
|
||||
for i, (title, body) in enumerate(cards):
|
||||
x = col_x[i % 2]; y = row_y[i // 2]
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, y, cw, ch, fill=WHITE, adj=0.08)
|
||||
shp(MSO_SHAPE.RECTANGLE, x + Inches(0.0), y + Inches(0.14), Inches(0.11), ch - Inches(0.28),
|
||||
fill=CORAL)
|
||||
txt(x + Inches(0.32), y + Inches(0.15), cw - Inches(0.5), Inches(0.36), title,
|
||||
size=13.5, color=INK, bold=True, anchor=MSO_ANCHOR.TOP)
|
||||
txt(x + Inches(0.32), y + Inches(0.55), cw - Inches(0.52), ch - Inches(0.68), body,
|
||||
size=10.5, color=MUTE, anchor=MSO_ANCHOR.TOP)
|
||||
|
||||
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Folie6.pptx")
|
||||
prs.save(out)
|
||||
print("saved", out)
|
||||
@@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Folie 7 – Integrationsserver / Event-Sourcing-Anbindung (DEUTSCH, adesso-Stil).
|
||||
Eingaenge (Order Entry/CLAB, Probeneingang [Atras+PVT], Geraete, Middleware, MiBi/Hybase,
|
||||
Stammdaten) -> Adapter-Ebene -> Event Store -> unten Event-Prozessoren, Projektionen,
|
||||
Konsumenten (SinaBI, Archivierung). Hintergrund: solides dunkles Blau (BG)."""
|
||||
|
||||
import os
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
||||
from pptx.enum.shapes import MSO_SHAPE, MSO_CONNECTOR
|
||||
from pptx.oxml.ns import qn
|
||||
from adesso_style import (WHITE, INK, BLUE, TEAL, GREEN, CORAL, LIGHT, MUTE, RECF,
|
||||
F, FC, chrome)
|
||||
|
||||
BG = RGBColor(0x0A, 0x3D, 0x6B)
|
||||
GRAY = RGBColor(0xAE, 0xB7, 0xC2)
|
||||
ADC = RGBColor(0xCF, 0xE2, 0xF7)
|
||||
SUBC = RGBColor(0x3C, 0x4A, 0x5A) # zweite Zeile – dunkel & gut lesbar
|
||||
|
||||
prs = Presentation(); prs.slide_width = Inches(13.333); prs.slide_height = Inches(7.5)
|
||||
SW, SH = prs.slide_width, prs.slide_height
|
||||
s = prs.slides.add_slide(prs.slide_layouts[6])
|
||||
|
||||
|
||||
def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), adj=None):
|
||||
sh = s.shapes.add_shape(kind, Inches(x), Inches(y), Inches(w), Inches(h))
|
||||
if fill is None: sh.fill.background()
|
||||
else: sh.fill.solid(); sh.fill.fore_color.rgb = fill
|
||||
if line is None: sh.line.fill.background()
|
||||
else: sh.line.color.rgb = line; sh.line.width = lw
|
||||
if adj is not None:
|
||||
try: sh.adjustments[0] = adj
|
||||
except Exception: pass
|
||||
sh.shadow.inherit = False
|
||||
return sh
|
||||
|
||||
|
||||
def txt(x, y, w, h, t, size=11, color=WHITE, bold=False, italic=False,
|
||||
align=PP_ALIGN.LEFT, font=F, anchor=MSO_ANCHOR.MIDDLE):
|
||||
tb = s.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h)); tf = tb.text_frame
|
||||
tf.word_wrap = True; tf.vertical_anchor = anchor
|
||||
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
first = True
|
||||
for line in t.split("\n"):
|
||||
p = tf.paragraphs[0] if first else tf.add_paragraph(); first = False
|
||||
p.alignment = align
|
||||
r = p.add_run(); r.text = line
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.italic = italic
|
||||
r.font.name = font; r.font.color.rgb = color
|
||||
return tb
|
||||
|
||||
|
||||
def conn(x1, y1, x2, y2, color=LIGHT, w=1.6, both=False):
|
||||
c = s.shapes.add_connector(MSO_CONNECTOR.STRAIGHT, Inches(x1), Inches(y1),
|
||||
Inches(x2), Inches(y2))
|
||||
c.line.color.rgb = color; c.line.width = Pt(w); c.shadow.inherit = False
|
||||
ln = c.line._get_or_add_ln()
|
||||
if both:
|
||||
ln.append(ln.makeelement(qn('a:headEnd'), {'type': 'triangle'}))
|
||||
ln.append(ln.makeelement(qn('a:tailEnd'), {'type': 'triangle'}))
|
||||
return c
|
||||
|
||||
|
||||
def group(x, y, w, h, title, tsize=11.5):
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, y, w, h, fill=None, line=LIGHT, lw=Pt(1.25), adj=0.04)
|
||||
txt(x, y + 0.05, w, 0.26, title, size=tsize, color=WHITE, bold=True,
|
||||
align=PP_ALIGN.CENTER, anchor=MSO_ANCHOR.TOP)
|
||||
|
||||
|
||||
def box(x, y, w, h, title, sub=None, fill=WHITE, tcol=INK, tsize=10.5, line=None, lw=Pt(1)):
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, y, w, h, fill=fill, line=line, lw=lw, adj=0.16)
|
||||
tb = s.shapes.add_textbox(Inches(x + 0.05), Inches(y), Inches(w - 0.10), Inches(h))
|
||||
tf = tb.text_frame; tf.word_wrap = True; tf.vertical_anchor = MSO_ANCHOR.MIDDLE
|
||||
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
p = tf.paragraphs[0]; p.alignment = PP_ALIGN.CENTER; p.line_spacing = 0.98
|
||||
r = p.add_run(); r.text = title; r.font.size = Pt(tsize); r.font.bold = True
|
||||
r.font.name = F; r.font.color.rgb = tcol
|
||||
if sub is not None:
|
||||
p.space_after = Pt(2)
|
||||
p2 = tf.add_paragraph(); p2.alignment = PP_ALIGN.CENTER; p2.line_spacing = 0.98
|
||||
r2 = p2.add_run(); r2.text = sub; r2.font.size = Pt(tsize - 0.5)
|
||||
r2.font.name = F; r2.font.color.rgb = SUBC
|
||||
return tb
|
||||
|
||||
|
||||
AD_Y, AD_H = 3.50, 0.48
|
||||
def adapter(x, w, title):
|
||||
box(x, AD_Y, w, AD_H, title, fill=ADC, tcol=INK, tsize=9, line=BLUE, lw=Pt(1.1))
|
||||
|
||||
|
||||
# ---- Hintergrund + Header --------------------------------------------------
|
||||
shp(MSO_SHAPE.RECTANGLE, 0, 0, SW.inches, SH.inches, fill=BG)
|
||||
chrome(s, "Event Sourcing — Integrationsserver", 8)
|
||||
|
||||
# ---- Legende ---------------------------------------------------------------
|
||||
ly = 0.95
|
||||
def legsq(x, color, label, lw_txt):
|
||||
shp(MSO_SHAPE.RECTANGLE, x, ly + 0.02, 0.15, 0.15, fill=color)
|
||||
txt(x + 0.21, ly - 0.03, lw_txt, 0.26, label, size=10, color=WHITE, anchor=MSO_ANCHOR.MIDDLE)
|
||||
legsq(0.40, CORAL, "Event Store", 1.2)
|
||||
legsq(1.76, GREEN, "Prop-Limbach", 1.3)
|
||||
legsq(3.28, ADC, "Adapter (own)", 1.4)
|
||||
legsq(4.90, WHITE, "System", 0.9)
|
||||
txt(6.30, 0.92, 6.63, 0.3,
|
||||
"↕ publizieren & abonnieren ↓ publizieren grau = Kommunikation",
|
||||
size=10, color=LIGHT, italic=True, anchor=MSO_ANCHOR.MIDDLE, align=PP_ALIGN.RIGHT)
|
||||
|
||||
# ---- EVENT STORE -----------------------------------------------------------
|
||||
ST_X, ST_Y, ST_W, ST_H = 0.40, 4.18, 12.53, 0.60
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, ST_X, ST_Y, ST_W, ST_H, fill=CORAL, line=INK, lw=Pt(3.5), adj=0.10)
|
||||
txt(ST_X, ST_Y + 0.06, ST_W, 0.30, "Event Store — append-only Event-Log",
|
||||
size=15, color=INK, bold=True, align=PP_ALIGN.CENTER)
|
||||
txt(ST_X, ST_Y + 0.35, ST_W, 0.22, "kanonische Wahrheit · Replay-fähig · (Kafka)",
|
||||
size=10.5, color=INK, align=PP_ALIGN.CENTER)
|
||||
|
||||
# ===========================================================================
|
||||
# OBEN – Systeme + Adapter-Ebene
|
||||
# ===========================================================================
|
||||
TGY, TGH = 1.28, 2.78
|
||||
|
||||
# --- 1: Order Entry ueber CLAB ---------------------------------------------
|
||||
group(0.40, TGY, 2.70, TGH, "Order Entry über CLAB")
|
||||
box(0.52, 1.62, 1.16, 0.42, "LabAccess")
|
||||
box(1.82, 1.62, 1.16, 0.42, "MDN")
|
||||
box(1.18, 2.22, 1.14, 0.44, "AB+M")
|
||||
box(1.05, 2.84, 1.40, 0.42, "CLAB (LIS)", fill=GREEN)
|
||||
adapter(0.78, 1.94, "CLAB-Adapter")
|
||||
conn(1.10, 2.04, 1.55, 2.22); conn(2.40, 2.04, 1.95, 2.22)
|
||||
conn(1.75, 2.66, 1.75, 2.84); conn(1.75, 3.26, 1.75, AD_Y)
|
||||
conn(1.75, AD_Y + AD_H, 1.75, ST_Y, both=True)
|
||||
|
||||
# --- 2: Probeneingang (Atras SL + PVT) -------------------------------------
|
||||
group(3.26, TGY, 1.95, TGH, "Probeneingang")
|
||||
box(3.34, 2.30, 0.86, 0.52, "Atras SL")
|
||||
box(4.27, 2.30, 0.86, 0.52, "PVT")
|
||||
adapter(3.34, 1.79, "Adapter (Probe → Event)")
|
||||
conn(2.32, 2.50, 3.34, 2.56, color=GRAY, both=True) # Praeanalytik-Kommunikation
|
||||
txt(2.28, 2.04, 1.30, 0.34, "Präanalytik-\nKomm.", size=8, color=GRAY, italic=True,
|
||||
align=PP_ALIGN.CENTER)
|
||||
conn(3.77, 2.82, 3.95, AD_Y); conn(4.70, 2.82, 4.55, AD_Y)
|
||||
conn(4.235, AD_Y + AD_H, 4.235, ST_Y)
|
||||
|
||||
# --- 3: Geraete -------------------------------------------------------------
|
||||
group(5.37, TGY, 1.78, TGH, "Geräte-Adapter")
|
||||
box(5.49, 2.10, 1.54, 0.70, "Geräte", "Sysmex · Analyzer")
|
||||
adapter(5.45, 1.62, "Adapter (Device → Event)")
|
||||
conn(6.26, 2.80, 6.26, AD_Y); conn(6.26, AD_Y + AD_H, 6.26, ST_Y, both=True)
|
||||
|
||||
# --- 4: Middleware ----------------------------------------------------------
|
||||
group(7.31, TGY, 1.78, TGH, "Middleware")
|
||||
box(7.43, 2.10, 1.54, 0.70, "Middleware-Systeme", "Myla/Maestria · LabOps · Liason")
|
||||
adapter(7.39, 1.62, "Adapter (Middleware → Event)")
|
||||
conn(8.20, 2.80, 8.20, AD_Y); conn(8.20, AD_Y + AD_H, 8.20, ST_Y, both=True)
|
||||
|
||||
# --- 5: MiBi (Hybase) -------------------------------------------------------
|
||||
group(9.25, TGY, 1.70, TGH, "MiBi")
|
||||
box(9.37, 2.10, 1.46, 0.70, "Hybase", "Resistenz / ID-Daten")
|
||||
adapter(9.33, 1.54, "Adapter (MiBi → Event)")
|
||||
conn(10.10, 2.80, 10.10, AD_Y); conn(10.10, AD_Y + AD_H, 10.10, ST_Y, both=True)
|
||||
|
||||
# --- 6: Stammdaten ----------------------------------------------------------
|
||||
group(11.11, TGY, 1.82, TGH, "Stammdaten")
|
||||
box(11.23, 2.10, 1.58, 0.70, "Stammdaten-Quellen", "SinaCRM · OTS/Znooni")
|
||||
adapter(11.19, 1.66, "Adapter (MasterData → Event)")
|
||||
conn(12.02, 2.80, 12.02, AD_Y); conn(12.02, AD_Y + AD_H, 12.02, ST_Y)
|
||||
|
||||
# ===========================================================================
|
||||
# UNTEN – Event-Prozessoren · Projektionen · Konsumenten
|
||||
# ===========================================================================
|
||||
BGY, BGH = 4.96, 1.96
|
||||
|
||||
group(0.40, BGY, 2.95, BGH, "Event-Prozessoren")
|
||||
box(0.56, 5.42, 2.63, 0.55, "Mapping / Transformation")
|
||||
box(0.56, 6.12, 2.63, 0.55, "Routing Engine")
|
||||
conn(1.85, ST_Y + ST_H, 1.85, BGY, both=True)
|
||||
|
||||
group(3.50, BGY, 5.85, BGH, "Projektionen")
|
||||
box(3.66, 5.46, 1.78, 1.02, "Auftragsstatus")
|
||||
box(5.56, 5.46, 1.78, 1.02, "Audit Trail")
|
||||
box(7.46, 5.46, 1.73, 1.02, "Reporting")
|
||||
conn(6.40, ST_Y + ST_H, 6.40, BGY)
|
||||
|
||||
group(9.50, BGY, 3.43, BGH, "Konsumenten")
|
||||
box(9.66, 5.38, 3.11, 0.68, "SinaBI (Power BI)", "Reporting / BI")
|
||||
box(9.66, 6.12, 3.11, 0.68, "Archivierung · Vaultbox", "Roche Navify · LDT2")
|
||||
conn(11.21, ST_Y + ST_H, 11.21, BGY)
|
||||
|
||||
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Folie7.pptx")
|
||||
prs.save(out)
|
||||
print("saved", out)
|
||||
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Folie 8 – Funktionszuordnung je System (aus Anforderungskatalog_LIS_Fit-Gap v2.xlsx).
|
||||
Pro System eine Kachel; Funktionen NUR dort = kraeftig/dunkel, auch woanders = grau mit
|
||||
'· auch: ...'. Einspaltig, Fira Sans Condensed. (adesso-Stil, deutsch, dunkelblau.)"""
|
||||
|
||||
import os
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
||||
from pptx.enum.shapes import MSO_SHAPE
|
||||
from openpyxl import load_workbook
|
||||
from openpyxl.utils import column_index_from_string as ci
|
||||
from adesso_style import (WHITE, INK, BLUE, TEAL, GREEN, CORAL, LIGHT, MUTE, RECF,
|
||||
F, FC, chrome)
|
||||
|
||||
BG = RGBColor(0x0A, 0x3D, 0x6B)
|
||||
SHARE = RGBColor(0x6B, 0x77, 0x85) # grau fuer "auch woanders"
|
||||
|
||||
# ---- Daten aus dem Excel lesen --------------------------------------------
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
wb = load_workbook(os.path.join(HERE, "Anforderungskatalog_LIS_Fit-Gap v2.xlsx"), data_only=True)
|
||||
ws = wb["Anforderungen & Fit-Gap"]
|
||||
SYS = [('H', 'Order Entry'), ('N', 'AB+M'), ('O', 'Integrationsserver'), ('P', 'PVT'),
|
||||
('Q', 'R. LabOps'), ('R', 'Sysmex'), ('S', 'SAP'), ('T', 'Consens')]
|
||||
ABBR = {'Order Entry': 'OE', 'AB+M': 'AB+M', 'Integrationsserver': 'Int.-Server',
|
||||
'PVT': 'PVT', 'R. LabOps': 'R.LabOps', 'Sysmex': 'Sysmex', 'SAP': 'SAP',
|
||||
'Consens': 'Consens'}
|
||||
|
||||
reqs = []; cur = None
|
||||
for r in range(5, ws.max_row + 1):
|
||||
b = ws.cell(r, 2).value; c = ws.cell(r, 3).value
|
||||
marks = {d: (ws.cell(r, ci(col)).value not in (None, '')) for col, d in SYS}
|
||||
if b:
|
||||
cur = {'name': (str(c).strip() if c else str(b)), 'm': dict(marks)}
|
||||
reqs.append(cur)
|
||||
elif cur:
|
||||
for d, v in marks.items():
|
||||
if v: cur['m'][d] = True
|
||||
if c: cur['name'] = (cur['name'] + ' / ' + str(c).strip())
|
||||
|
||||
persys = {d: [] for _, d in SYS}
|
||||
for req in reqs:
|
||||
active = [d for _, d in SYS if req['m'][d]]
|
||||
for d in active:
|
||||
persys[d].append((req['name'], [o for o in active if o != d]))
|
||||
for d in persys:
|
||||
persys[d].sort(key=lambda it: (1 if it[1] else 0))
|
||||
|
||||
# ---- PPTX ------------------------------------------------------------------
|
||||
prs = Presentation(); prs.slide_width = Inches(13.333); prs.slide_height = Inches(7.5)
|
||||
SW, SH = prs.slide_width, prs.slide_height
|
||||
s = prs.slides.add_slide(prs.slide_layouts[6])
|
||||
|
||||
|
||||
def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), adj=None):
|
||||
sh = s.shapes.add_shape(kind, Inches(x), Inches(y), Inches(w), Inches(h))
|
||||
if fill is None: sh.fill.background()
|
||||
else: sh.fill.solid(); sh.fill.fore_color.rgb = fill
|
||||
if line is None: sh.line.fill.background()
|
||||
else: sh.line.color.rgb = line; sh.line.width = lw
|
||||
if adj is not None:
|
||||
try: sh.adjustments[0] = adj
|
||||
except Exception: pass
|
||||
sh.shadow.inherit = False
|
||||
return sh
|
||||
|
||||
|
||||
def txt(x, y, w, h, t, size=12, color=WHITE, bold=False, align=PP_ALIGN.LEFT,
|
||||
font=F, anchor=MSO_ANCHOR.MIDDLE):
|
||||
tb = s.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h)); tf = tb.text_frame
|
||||
tf.word_wrap = True; tf.vertical_anchor = anchor
|
||||
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
p = tf.paragraphs[0]; p.alignment = align
|
||||
r = p.add_run(); r.text = t
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.name = font; r.font.color.rgb = color
|
||||
return tb
|
||||
|
||||
|
||||
def cut(t, n):
|
||||
return t if len(t) <= n else t[:n].rstrip() + "…"
|
||||
|
||||
|
||||
def tile(x, y, w, h, title, items, accent, isize, sa, name_max):
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, y, w, h, fill=WHITE, adj=0.05)
|
||||
txt(x + 0.22, y + 0.14, w - 0.44, 0.32, title, size=14, color=INK, bold=True,
|
||||
anchor=MSO_ANCHOR.MIDDLE)
|
||||
n = len([i for i in items if not i[1]])
|
||||
txt(x + w - 1.7, y + 0.18, 1.5, 0.24, "%d · %d nur hier" % (len(items), n),
|
||||
size=8.5, color=SHARE, align=PP_ALIGN.RIGHT, font=FC, anchor=MSO_ANCHOR.MIDDLE)
|
||||
shp(MSO_SHAPE.RECTANGLE, x + 0.22, y + 0.50, w - 0.44, 0.030, fill=accent)
|
||||
|
||||
tb = s.shapes.add_textbox(Inches(x + 0.22), Inches(y + 0.62), Inches(w - 0.40),
|
||||
Inches(h - 0.74))
|
||||
tf = tb.text_frame; tf.word_wrap = True; tf.vertical_anchor = MSO_ANCHOR.TOP
|
||||
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
for i, (name, others) in enumerate(items):
|
||||
p = tf.paragraphs[0] if i == 0 else tf.add_paragraph()
|
||||
p.alignment = PP_ALIGN.LEFT; p.line_spacing = 0.96; p.space_after = Pt(sa)
|
||||
r = p.add_run(); r.font.name = FC; r.font.size = Pt(isize)
|
||||
if others:
|
||||
r.text = cut(name, name_max); r.font.bold = False; r.font.color.rgb = SHARE
|
||||
r2 = p.add_run(); r2.text = " · auch: " + ", ".join(ABBR[o] for o in others)
|
||||
r2.font.name = FC; r2.font.size = Pt(isize - 1); r2.font.color.rgb = SHARE
|
||||
else:
|
||||
r.text = cut(name, name_max + 4); r.font.bold = True; r.font.color.rgb = INK
|
||||
|
||||
|
||||
# ---- Hintergrund + Header --------------------------------------------------
|
||||
shp(MSO_SHAPE.RECTANGLE, 0, 0, SW.inches, SH.inches, fill=BG)
|
||||
chrome(s, "Funktionszuordnung je System", 9)
|
||||
txt(0.42, 0.96, 12.5, 0.3,
|
||||
"Dunkel/fett = nur dieses System · grau „· auch: …" + chr(34) + " = Funktion liegt auch in anderen Systemen",
|
||||
size=11, color=LIGHT, anchor=MSO_ANCHOR.MIDDLE, font=FC)
|
||||
|
||||
CY, CH = 1.46, 5.42
|
||||
COLS = [0.40, 3.58, 6.76, 9.94]; CW = 2.98
|
||||
|
||||
# Spalte 1: Integrationsserver (hoch)
|
||||
tile(COLS[0], CY, CW, CH, "Integrationsserver", persys['Integrationsserver'],
|
||||
CORAL, isize=9, sa=1.5, name_max=30)
|
||||
# Spalte 2: Order Entry (hoch)
|
||||
tile(COLS[1], CY, CW, CH, "Order Entry", persys['Order Entry'],
|
||||
BLUE, isize=10.5, sa=5, name_max=30)
|
||||
|
||||
# Spalten 3 & 4: je 3 kleine Kacheln
|
||||
SH3 = 1.68; GAP = 0.19
|
||||
ys = [CY, CY + SH3 + GAP, CY + 2 * (SH3 + GAP)]
|
||||
small3 = ['AB+M', 'Consens', 'R. LabOps']
|
||||
small4 = ['PVT', 'Sysmex', 'SAP']
|
||||
for name, y in zip(small3, ys):
|
||||
tile(COLS[2], y, CW, SH3, name, persys[name], TEAL, isize=9.5, sa=3, name_max=30)
|
||||
for name, y in zip(small4, ys):
|
||||
tile(COLS[3], y, CW, SH3, name, persys[name], TEAL, isize=9.5, sa=3, name_max=30)
|
||||
|
||||
out = os.path.join(HERE, "Folie8.pptx")
|
||||
prs.save(out)
|
||||
print("saved", out)
|
||||
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Folie 9 – Golden Master (adesso-Stil, deutsch, dunkelblau).
|
||||
Was ist das? · Vorgehen (3 Schritte) · Nutzen 1 + Nutzen 2."""
|
||||
|
||||
import os
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
|
||||
from pptx.enum.shapes import MSO_SHAPE, MSO_CONNECTOR
|
||||
from pptx.oxml.ns import qn
|
||||
from adesso_style import (WHITE, INK, BLUE, TEAL, GREEN, CORAL, LIGHT, MUTE, RECF,
|
||||
F, FC, chrome)
|
||||
|
||||
BG = RGBColor(0x0A, 0x3D, 0x6B)
|
||||
|
||||
prs = Presentation(); prs.slide_width = Inches(13.333); prs.slide_height = Inches(7.5)
|
||||
SW, SH = prs.slide_width, prs.slide_height
|
||||
s = prs.slides.add_slide(prs.slide_layouts[6])
|
||||
|
||||
|
||||
def shp(kind, x, y, w, h, fill=None, line=None, lw=Pt(1), adj=None):
|
||||
sh = s.shapes.add_shape(kind, Inches(x), Inches(y), Inches(w), Inches(h))
|
||||
if fill is None: sh.fill.background()
|
||||
else: sh.fill.solid(); sh.fill.fore_color.rgb = fill
|
||||
if line is None: sh.line.fill.background()
|
||||
else: sh.line.color.rgb = line; sh.line.width = lw
|
||||
if adj is not None:
|
||||
try: sh.adjustments[0] = adj
|
||||
except Exception: pass
|
||||
sh.shadow.inherit = False
|
||||
return sh
|
||||
|
||||
|
||||
def txt(x, y, w, h, t, size=12, color=WHITE, bold=False, italic=False,
|
||||
align=PP_ALIGN.LEFT, font=F, anchor=MSO_ANCHOR.MIDDLE):
|
||||
tb = s.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h)); tf = tb.text_frame
|
||||
tf.word_wrap = True; tf.vertical_anchor = anchor
|
||||
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = Pt(0)
|
||||
first = True
|
||||
for line in t.split("\n"):
|
||||
p = tf.paragraphs[0] if first else tf.add_paragraph(); first = False
|
||||
p.alignment = align
|
||||
r = p.add_run(); r.text = line
|
||||
r.font.size = Pt(size); r.font.bold = bold; r.font.italic = italic
|
||||
r.font.name = font; r.font.color.rgb = color
|
||||
return tb
|
||||
|
||||
|
||||
def conn(x1, y1, x2, y2, color=LIGHT, w=2.0):
|
||||
c = s.shapes.add_connector(MSO_CONNECTOR.STRAIGHT, Inches(x1), Inches(y1),
|
||||
Inches(x2), Inches(y2))
|
||||
c.line.color.rgb = color; c.line.width = Pt(w); c.shadow.inherit = False
|
||||
ln = c.line._get_or_add_ln()
|
||||
ln.append(ln.makeelement(qn('a:tailEnd'), {'type': 'triangle'}))
|
||||
return c
|
||||
|
||||
|
||||
def heading(x, y, t):
|
||||
shp(MSO_SHAPE.RECTANGLE, x, y + 0.05, 0.16, 0.20, fill=CORAL)
|
||||
txt(x + 0.26, y - 0.04, 8.0, 0.34, t, size=15, color=WHITE, bold=True,
|
||||
anchor=MSO_ANCHOR.MIDDLE)
|
||||
|
||||
|
||||
def step(x, y, w, h, num, title, sub):
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, y, w, h, fill=WHITE, adj=0.08)
|
||||
shp(MSO_SHAPE.OVAL, x + 0.16, y + 0.16, 0.42, 0.42, fill=BLUE)
|
||||
txt(x + 0.16, y + 0.16, 0.42, 0.42, str(num), size=15, color=WHITE, bold=True,
|
||||
align=PP_ALIGN.CENTER)
|
||||
txt(x + 0.70, y + 0.14, w - 0.85, 0.34, title, size=13, color=INK, bold=True,
|
||||
anchor=MSO_ANCHOR.TOP)
|
||||
txt(x + 0.70, y + 0.50, w - 0.85, h - 0.60, sub, size=10.5, color=MUTE,
|
||||
anchor=MSO_ANCHOR.TOP)
|
||||
|
||||
|
||||
def nutzen(x, y, w, h, title, body):
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, x, y, w, h, fill=WHITE, adj=0.05)
|
||||
shp(MSO_SHAPE.RECTANGLE, x, y + 0.16, 0.13, h - 0.32, fill=CORAL)
|
||||
txt(x + 0.34, y + 0.20, w - 0.55, 0.40, title, size=15, color=INK, bold=True,
|
||||
anchor=MSO_ANCHOR.TOP)
|
||||
txt(x + 0.34, y + 0.70, w - 0.6, h - 0.85, body, size=12, color=INK,
|
||||
anchor=MSO_ANCHOR.TOP)
|
||||
|
||||
|
||||
# ---- Hintergrund + Header --------------------------------------------------
|
||||
shp(MSO_SHAPE.RECTANGLE, 0, 0, SW.inches, SH.inches, fill=BG)
|
||||
chrome(s, "Golden Master", 10)
|
||||
|
||||
# ---- Was ist das? ----------------------------------------------------------
|
||||
heading(0.50, 1.22, "Was ist das?")
|
||||
shp(MSO_SHAPE.ROUNDED_RECTANGLE, 0.50, 1.58, 12.33, 0.82, fill=WHITE, adj=0.06)
|
||||
txt(0.78, 1.58, 11.8, 0.82,
|
||||
"Ein umfassender Acceptance-/Approval-Test der Software: Das System wird als Ganzes gegen einen "
|
||||
"einmal erfassten, freigegebenen Referenz-Stand („Golden Master“) geprüft — weicht ein "
|
||||
"Ergebnis ab, schlägt der Test an.",
|
||||
size=12.5, color=INK)
|
||||
|
||||
# ---- Vorgehen --------------------------------------------------------------
|
||||
heading(0.50, 2.64, "Vorgehen")
|
||||
SY, SH_ = 3.00, 1.06
|
||||
step(0.50, SY, 3.70, SH_, 1, "Code- & Ergebnis-Analyse",
|
||||
"Prüfen, wie die Software arbeitet und wie/wo Ergebnisse abgelegt werden.")
|
||||
step(4.82, SY, 3.70, SH_, 2, "Testtool aufbauen",
|
||||
"Werkzeug, das Referenz-Ergebnisse erfasst und bei jedem Lauf vergleicht.")
|
||||
step(9.13, SY, 3.70, SH_, 3, "Test-Suite (Fachseite)",
|
||||
"Die FS baut die fachlichen Testfälle / Szenarien auf.")
|
||||
conn(4.24, SY + SH_ / 2, 4.78, SY + SH_ / 2)
|
||||
conn(8.56, SY + SH_ / 2, 9.09, SY + SH_ / 2)
|
||||
|
||||
# ---- Nutzen ----------------------------------------------------------------
|
||||
heading(0.50, 4.34, "Nutzen")
|
||||
NY, NH = 4.70, 2.02
|
||||
nutzen(0.50, NY, 6.00, NH, "Nutzen 1 · Funktionssicherung CLAB",
|
||||
"Nach jeder Änderung lässt sich die Funktionsfähigkeit der Software prüfen — "
|
||||
"schnelle, wiederholbare Regressionssicherheit ohne manuelles Nachtesten.")
|
||||
nutzen(6.83, NY, 6.00, NH, "Nutzen 2 · Vollständigkeit bei LIS-Migration",
|
||||
"Ein Ziel-LIS, auf das migriert werden soll, lässt sich hart gegen die eigenen "
|
||||
"Anforderungen testen.\n\n⚠ Setzt ein neues Aufsetzen des Testtools voraus.")
|
||||
|
||||
out = os.path.join(os.path.dirname(os.path.abspath(__file__)), "Folie9.pptx")
|
||||
prs.save(out)
|
||||
print("saved", out)
|
||||
@@ -0,0 +1,139 @@
|
||||
<mxfile host="Electron">
|
||||
<diagram id="event-sourcing" name="TO-BE (Event Sourcing)">
|
||||
<mxGraphModel dx="1037" dy="425" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1320" pageHeight="900" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="es_title" parent="1" style="text;html=1;align=left;fontStyle=1;fontSize=16;" value="TO-BE (Variante) — Event-Sourcing-Integration" vertex="1">
|
||||
<mxGeometry height="26" width="700" x="60" y="10" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_leg" parent="1" style="text;html=1;align=left;fontStyle=1;" value="Legend" vertex="1">
|
||||
<mxGeometry height="20" width="60" x="60" y="82" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_leg_own" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="own" vertex="1">
|
||||
<mxGeometry height="24" width="80" x="120" y="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_leg_tp" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;" value="third-party" vertex="1">
|
||||
<mxGeometry height="24" width="90" x="210" y="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_leg_ev" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFF2CC;strokeColor=#D6B656;" value="Event-Store" vertex="1">
|
||||
<mxGeometry height="24" width="110" x="310" y="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_abm" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="AB+M
(Order Entry)" vertex="1">
|
||||
<mxGeometry height="56" width="160" x="130" y="244" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_lac" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="LabAccess
(Order Entry I)" vertex="1">
|
||||
<mxGeometry height="56" width="160" x="60" y="154" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_mdn" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="MDN
(Order Entry II)" vertex="1">
|
||||
<mxGeometry height="56" width="160" x="240" y="154" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_mds" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="Stammdaten-Quellen<br>SinaCRM · OTS/Znooni / Links" vertex="1">
|
||||
<mxGeometry height="56" width="230" x="360" y="300" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_admds" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Adapter
(MasterData → Event)" vertex="1">
|
||||
<mxGeometry height="44" width="230" x="360" y="400" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_store" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFF2CC;strokeColor=#D6B656;fontStyle=1;fontSize=13;" value="Event Store — append-only Event-Log
kanonische Wahrheit · Projektionen abgeleitet · Replay-fähig" vertex="1">
|
||||
<mxGeometry height="70" width="940" x="70" y="559" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_pgrp" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#EAF0FB;strokeColor=#6C8EBF;verticalAlign=top;fontStyle=1;" value="Event-Prozessoren" vertex="1">
|
||||
<mxGeometry height="170" width="200" x="980" y="380" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_pmap" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Mapping / Transformation" vertex="1">
|
||||
<mxGeometry height="46" width="160" x="1000" y="415" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_proute" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Routing Engine" vertex="1">
|
||||
<mxGeometry height="46" width="160" x="1000" y="480" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_jgrp" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#6C8EBF;dashed=1;verticalAlign=top;fontStyle=1;" value="Projektionen / Read-Models" vertex="1">
|
||||
<mxGeometry height="107" width="470" x="751" y="726" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_jorder" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#EAF0FB;strokeColor=#6C8EBF;" value="Auftrags-Status" vertex="1">
|
||||
<mxGeometry height="58" width="130" x="771" y="758" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_jmd" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#EAF0FB;strokeColor=#6C8EBF;" value="Konsolidierte Stammdaten
(Single Point of Truth)" vertex="1">
|
||||
<mxGeometry height="58" width="170" x="916" y="758" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_jcat" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#EAF0FB;strokeColor=#6C8EBF;" value="Leistungs-
verzeichnis" vertex="1">
|
||||
<mxGeometry height="58" width="110" x="1096" y="758" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_mon" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;" value="Monitoring (Roche Analytics)" vertex="1">
|
||||
<mxGeometry height="50" width="250" x="603" y="835" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_adclab" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="CLAB-Adapter" vertex="1">
|
||||
<mxGeometry height="50" width="160" x="130" y="448" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_addev" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Device- / Middle Ware- Adapter<br>Sysmex IPU · Myla/Maestria · LabOps · Desuri · Liason" vertex="1">
|
||||
<mxGeometry height="50" width="280" x="283" y="699" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_clab" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontStyle=1;" value="CLAB (LIS)" vertex="1">
|
||||
<mxGeometry height="56" width="160" x="130" y="356" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_dev" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="Devices
Sysmex-Straße · Atras SL · Analyzer" vertex="1">
|
||||
<mxGeometry height="56" width="280" x="290" y="829" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_e_abm" edge="1" parent="1" source="es_abm" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" target="es_clab">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="210" y="344" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="es_e_lac" edge="1" parent="1" source="es_lac" style="endArrow=classic;html=1;rounded=0;entryX=0.306;entryY=-0.018;entryDx=0;entryDy=0;entryPerimeter=0;" target="es_abm">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_e_mdn" edge="1" parent="1" source="es_mdn" style="endArrow=classic;html=1;rounded=0;entryX=0.75;entryY=0;entryDx=0;entryDy=0;" target="es_abm">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_e_mds" edge="1" parent="1" source="es_mds" style="endArrow=classic;html=1;rounded=0;" target="es_admds">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_p_mds" edge="1" parent="1" source="es_admds" style="endArrow=classic;html=1;rounded=0;fontStyle=2;entryX=0.435;entryY=0.014;entryDx=0;entryDy=0;entryPerimeter=0;" target="es_store" value="publish">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_x_map" edge="1" parent="1" source="es_store" style="endArrow=classic;startArrow=classic;html=1;rounded=0;dashed=1;fontStyle=2;" target="es_pmap" value="consume / publish">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_x_route" edge="1" parent="1" source="es_store" style="endArrow=classic;startArrow=classic;html=1;rounded=0;dashed=1;" target="es_proute">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_s_order" edge="1" parent="1" source="es_store" style="endArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_jorder" value="subscribe">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_s_md" edge="1" parent="1" source="es_store" style="endArrow=classic;html=1;rounded=0;" target="es_jmd">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_s_cat" edge="1" parent="1" source="es_store" style="endArrow=classic;html=1;rounded=0;" target="es_jcat">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_s_mon" edge="1" parent="1" source="es_store" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_mon" value="subscribe">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="600" y="737" />
|
||||
<mxPoint x="720" y="737" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="es_x_clab" edge="1" parent="1" source="es_store" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.173;exitY=0.014;exitDx=0;exitDy=0;exitPerimeter=0;" target="es_adclab" value="publish / subscribe">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="230" y="541.5384615384614" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="es_x_dev" edge="1" parent="1" source="es_store" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" target="es_addev">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_n_clab" edge="1" parent="1" source="es_adclab" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_clab" value="LDT / natives Protokoll">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_n_dev" edge="1" parent="1" source="es_addev" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_dev" value="natives Protokoll">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="hm9u5WX3jjkNatpctnB4-2" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="Prop - limbach" vertex="1">
|
||||
<mxGeometry height="24" width="80" x="440" y="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="TgiG7C2EhwjrXGmr-nUM-1" parent="1" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;" value="" vertex="1">
|
||||
<mxGeometry height="40" width="40" x="120" y="574" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
@@ -0,0 +1,474 @@
|
||||
<mxfile host="Electron" pages="4">
|
||||
<diagram id="as-is" name="AS-IS (heute)">
|
||||
<mxGraphModel dx="1171" dy="929" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1500" pageHeight="1000" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="title" parent="1" style="text;html=1;align=left;fontStyle=1;fontSize=16;" value="AS-IS — heutige Landschaft (MVZ Ludwigsburg)" vertex="1">
|
||||
<mxGeometry height="26" width="700" x="60" y="20" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="abm" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;" value="AB+M
Order Entry
30% Musterschein / 70% digital" vertex="1">
|
||||
<mxGeometry height="72" width="190" x="80" y="70" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="laccess" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;" value="LabAccess
(Order Entry I)" vertex="1">
|
||||
<mxGeometry height="72" width="160" x="300" y="70" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="mdn" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;" value="MDN
(Order Entry II)" vertex="1">
|
||||
<mxGeometry height="72" width="160" x="500" y="70" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="bottleneck" parent="1" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#F8CECC;strokeColor=#B85450;fontStyle=2;" value="Nur 1 LDT an CLAB · AB+M muss zuerst abgeschlossen sein → Engpass" vertex="1">
|
||||
<mxGeometry height="34" width="580" x="80" y="180" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="clab" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#F5F5F5;strokeColor=#666666;fontStyle=1;fontSize=14;" value="CLAB
(LIS)" vertex="1">
|
||||
<mxGeometry height="90" width="240" x="300" y="320" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="ipu" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E1D5E7;strokeColor=#9673A6;" value="Sysmex
Extended IPU" vertex="1">
|
||||
<mxGeometry height="60" width="150" x="60" y="520" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="myla" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E1D5E7;strokeColor=#9673A6;" value="Myla → Maestria" vertex="1">
|
||||
<mxGeometry height="60" width="150" x="230" y="520" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="labops" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E1D5E7;strokeColor=#9673A6;" value="LabOps" vertex="1">
|
||||
<mxGeometry height="60" width="120" x="400" y="520" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="mwrest" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#E1D5E7;strokeColor=#9673A6;" value="Desuri (bidir.) · Biomerieux
Liason · Firetransfer
(je eigene P2P-Anbindung)" vertex="1">
|
||||
<mxGeometry height="60" width="240" x="540" y="520" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="devs" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;" value="Geräte: Sysmex-Straße · Atras SL (1)/(2) Schüttgutsortierer · Analyzer" vertex="1">
|
||||
<mxGeometry height="50" width="720" x="60" y="650" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="sdgroup" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#B85450;dashed=1;verticalAlign=top;fontStyle=1;fontColor=#B85450;" value="Stammdaten-Inseln — Doppelpflege" vertex="1">
|
||||
<mxGeometry height="210" width="380" x="820" y="300" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="sd1" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#F8CECC;strokeColor=#B85450;" value="CLAB-Stammdaten
(selbst generiert)" vertex="1">
|
||||
<mxGeometry height="55" width="160" x="840" y="340" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="sd2" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#F8CECC;strokeColor=#B85450;" value="SinaCRM
(separate Pflege z. LIS)" vertex="1">
|
||||
<mxGeometry height="55" width="160" x="1020" y="340" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="sd3" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#F8CECC;strokeColor=#B85450;" value="MySQL
(Support-Requests)" vertex="1">
|
||||
<mxGeometry height="55" width="160" x="840" y="430" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="sd4" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#F8CECC;strokeColor=#B85450;" value="OTS / Znooni
(Leistungsverzeichnis)" vertex="1">
|
||||
<mxGeometry height="55" width="160" x="1020" y="430" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rgroup" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#82B366;dashed=1;verticalAlign=top;fontStyle=1;fontColor=#82B366;" value="Roche / Analytics" vertex="1">
|
||||
<mxGeometry height="260" width="380" x="820" y="650" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="ccm" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#D5E8D4;strokeColor=#82B366;" value="2 × CCM" vertex="1">
|
||||
<mxGeometry height="50" width="120" x="840" y="690" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="navify" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#D5E8D4;strokeColor=#82B366;" value="Roche Navify LabOps
(auch Archivierung)" vertex="1">
|
||||
<mxGeometry height="50" width="200" x="980" y="690" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="ranalytics" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#D5E8D4;strokeColor=#82B366;" value="Monitoring von Roche · Analytics (CCM-Daten)
Roche Integrater · Average of normals" vertex="1">
|
||||
<mxGeometry height="60" width="340" x="840" y="760" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="sinabi" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#D5E8D4;strokeColor=#82B366;" value="SinaBI (PowerBI)" vertex="1">
|
||||
<mxGeometry height="45" width="160" x="840" y="840" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e1" edge="1" parent="1" source="abm" style="endArrow=classic;html=1;fontStyle=2;" target="clab" value="LDT">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e2" edge="1" parent="1" source="laccess" style="endArrow=classic;html=1;" target="clab">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e3" edge="1" parent="1" source="mdn" style="endArrow=classic;html=1;" target="clab">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e4" edge="1" parent="1" source="ipu" style="endArrow=classic;html=1;" target="clab">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e5" edge="1" parent="1" source="myla" style="endArrow=classic;html=1;" target="clab">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e6" edge="1" parent="1" source="labops" style="endArrow=classic;html=1;" target="clab">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e7" edge="1" parent="1" source="mwrest" style="endArrow=classic;startArrow=classic;html=1;" target="clab">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e8" edge="1" parent="1" source="devs" style="endArrow=classic;html=1;dashed=1;" target="ipu">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="e9" edge="1" parent="1" source="devs" style="endArrow=classic;html=1;dashed=1;" target="mwrest">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="r1" edge="1" parent="1" source="clab" style="endArrow=classic;startArrow=classic;html=1;dashed=1;strokeColor=#B85450;fontColor=#B85450;fontStyle=2;" target="sd2" value="separate Pflege">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="r2" edge="1" parent="1" source="clab" style="endArrow=classic;startArrow=classic;html=1;dashed=1;strokeColor=#B85450;" target="sd1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="r3" edge="1" parent="1" source="sd2" style="endArrow=classic;startArrow=classic;html=1;dashed=1;strokeColor=#B85450;fontColor=#B85450;fontStyle=2;" target="sd4" value="manuelles Mapping (Links)">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="r4" edge="1" parent="1" source="sd1" style="endArrow=classic;startArrow=classic;html=1;dashed=1;strokeColor=#B85450;fontColor=#B85450;fontStyle=2;" target="sd3" value="Doppelpflege">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="g1" edge="1" parent="1" source="clab" style="endArrow=classic;startArrow=classic;html=1;" target="navify">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="g2" edge="1" parent="1" source="ccm" style="endArrow=classic;html=1;" target="ranalytics">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
<diagram id="to-be" name="TO-BE (Ziel)">
|
||||
<mxGraphModel dx="1240" dy="1964" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1000" pageHeight="980" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="t_title" parent="1" style="text;html=1;align=left;fontStyle=1;fontSize=16;" value="TO-BE — Integration Server mit Single Point of Truth" vertex="1">
|
||||
<mxGeometry height="26" width="700" x="60" y="-30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="leg_t" parent="1" style="text;html=1;align=left;fontStyle=1;" value="Legend" vertex="1">
|
||||
<mxGeometry height="20" width="70" x="60" y="18" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="leg_e" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="own" vertex="1">
|
||||
<mxGeometry height="24" width="80" x="125" y="16" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="leg_f" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;" value="third-party" vertex="1">
|
||||
<mxGeometry height="24" width="90" x="215" y="16" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gC0" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="LabAccess
(Order Entry I)" vertex="1">
|
||||
<mxGeometry height="64" width="170" x="120" y="90" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gB0" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="MDN
(Order Entry II)" vertex="1">
|
||||
<mxGeometry height="64" width="170" x="400" y="90" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="gA0" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="AB+M
(Order Entry)" vertex="1">
|
||||
<mxGeometry height="64" width="170" x="700" y="90" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="srv" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#F8F8F8;strokeColor=#999999;verticalAlign=top;fontStyle=1;fontSize=14;" value="Integration Server" vertex="1">
|
||||
<mxGeometry height="420" width="850" x="60" y="250" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="absC" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Abstraction" vertex="1">
|
||||
<mxGeometry height="44" width="170" x="120" y="300" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="absB" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Abstraction" vertex="1">
|
||||
<mxGeometry height="44" width="170" x="400" y="300" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="absA" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Order Abstraction" vertex="1">
|
||||
<mxGeometry height="44" width="170" x="700" y="300" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="db" parent="1" style="shape=cylinder3;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;boundedLbl=1;backgroundOutline=1;size=14;verticalAlign=middle;" value="<b>Single Point of Truth</b><br>canonical store<br>konsolidiert: Stammdaten · SinaCRM · Leistungsverzeichnis (OTS/Znooni)" vertex="1">
|
||||
<mxGeometry height="115" width="350" x="320" y="390" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="zd" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#EAF0FB;strokeColor=#6C8EBF;verticalAlign=top;fontStyle=1;" value="Central Services" vertex="1">
|
||||
<mxGeometry height="105" width="560" x="210" y="545" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="zd1" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Routing Engine" vertex="1">
|
||||
<mxGeometry height="50" width="160" x="230" y="580" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="zd2" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Mapping / Transformation" vertex="1">
|
||||
<mxGeometry height="50" width="180" x="405" y="580" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="zd3" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Monitoring
(Roche Analytics)" vertex="1">
|
||||
<mxGeometry height="50" width="150" x="600" y="580" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="lis" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="LIS (CLAB)" vertex="1">
|
||||
<mxGeometry height="60" width="170" x="120" y="730" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="ga" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Device Abstraction
Sysmex IPU · Myla/Maestria · LabOps · Desuri · Liason" vertex="1">
|
||||
<mxGeometry height="70" width="210" x="680" y="725" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="ger" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="Devices
Sysmex-Straße · Atras SL · Analyzer" vertex="1">
|
||||
<mxGeometry height="60" width="210" x="680" y="850" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="eC" edge="1" parent="1" source="gC0" style="endArrow=classic;html=1;rounded=0;" target="absC">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="eB" edge="1" parent="1" source="gB0" style="endArrow=classic;html=1;rounded=0;" target="absB">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="eA" edge="1" parent="1" source="gA0" style="endArrow=classic;html=1;rounded=0;" target="absA">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="nC" edge="1" parent="1" source="absC" style="endArrow=classic;html=1;rounded=0;" target="db">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="nB" edge="1" parent="1" source="absB" style="endArrow=classic;html=1;rounded=0;fontStyle=2;" target="db" value="normalize">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="nA" edge="1" parent="1" source="absA" style="endArrow=classic;html=1;rounded=0;" target="db">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="uni" edge="1" parent="1" source="db" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;" target="zd" value="canonical">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="bLis" edge="1" parent="1" source="lis" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.15;entryY=1;entryDx=0;entryDy=0;" target="db" value="direct DB access">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="bGa" edge="1" parent="1" source="ga" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.85;entryY=1;entryDx=0;entryDy=0;" target="db" value="direct DB access">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="bGaGer" edge="1" parent="1" source="ga" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" target="ger">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="bLisGer" edge="1" parent="1" source="lis" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" target="ger">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
<diagram id="event-sourcing" name="TO-BE (Event Sourcing)">
|
||||
<mxGraphModel dx="1240" dy="984" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1320" pageHeight="900" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="es_title" parent="1" style="text;html=1;align=left;fontStyle=1;fontSize=16;" value="TO-BE (Variante) — Event-Sourcing-Integration" vertex="1">
|
||||
<mxGeometry height="26" width="700" x="60" y="10" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_leg" parent="1" style="text;html=1;align=left;fontStyle=1;" value="Legend" vertex="1">
|
||||
<mxGeometry height="20" width="60" x="60" y="46" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_leg_own" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="own" vertex="1">
|
||||
<mxGeometry height="24" width="80" x="120" y="44" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_leg_tp" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;" value="third-party" vertex="1">
|
||||
<mxGeometry height="24" width="90" x="210" y="44" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_leg_ev" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFF2CC;strokeColor=#D6B656;" value="Event-Store" vertex="1">
|
||||
<mxGeometry height="24" width="110" x="310" y="44" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_abm" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="AB+M
(Order Entry)" vertex="1">
|
||||
<mxGeometry height="56" width="160" x="70" y="90" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_lac" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="LabAccess
(Order Entry I)" vertex="1">
|
||||
<mxGeometry height="56" width="160" x="260" y="90" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_mdn" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="MDN
(Order Entry II)" vertex="1">
|
||||
<mxGeometry height="56" width="160" x="450" y="90" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_mds" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="Stammdaten-Quellen
SinaCRM · OTS/Znooni" vertex="1">
|
||||
<mxGeometry height="56" width="230" x="650" y="90" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_adabm" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Adapter
(Order → Event)" vertex="1">
|
||||
<mxGeometry height="44" width="160" x="70" y="190" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_adlac" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Adapter
(Order → Event)" vertex="1">
|
||||
<mxGeometry height="44" width="160" x="260" y="190" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_admdn" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Adapter
(Order → Event)" vertex="1">
|
||||
<mxGeometry height="44" width="160" x="450" y="190" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_admds" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Adapter
(MasterData → Event)" vertex="1">
|
||||
<mxGeometry height="44" width="230" x="650" y="190" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_store" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFF2CC;strokeColor=#D6B656;fontStyle=1;fontSize=13;" value="Event Store — append-only Event-Log
kanonische Wahrheit · Projektionen abgeleitet · Replay-fähig" vertex="1">
|
||||
<mxGeometry height="70" width="940" x="70" y="290" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_pgrp" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#EAF0FB;strokeColor=#6C8EBF;verticalAlign=top;fontStyle=1;" value="Event-Prozessoren" vertex="1">
|
||||
<mxGeometry height="170" width="200" x="1050" y="270" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_pmap" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Mapping / Transformation" vertex="1">
|
||||
<mxGeometry height="46" width="160" x="1070" y="305" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_proute" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Routing Engine" vertex="1">
|
||||
<mxGeometry height="46" width="160" x="1070" y="370" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_jgrp" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=none;strokeColor=#6C8EBF;dashed=1;verticalAlign=top;fontStyle=1;" value="Projektionen / Read-Models" vertex="1">
|
||||
<mxGeometry height="107" width="470" x="751" y="457" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_jorder" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#EAF0FB;strokeColor=#6C8EBF;" value="Auftrags-Status" vertex="1">
|
||||
<mxGeometry height="58" width="130" x="771" y="489" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_jmd" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#EAF0FB;strokeColor=#6C8EBF;" value="Konsolidierte Stammdaten
(Single Point of Truth)" vertex="1">
|
||||
<mxGeometry height="58" width="170" x="916" y="489" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_jcat" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#EAF0FB;strokeColor=#6C8EBF;" value="Leistungs-
verzeichnis" vertex="1">
|
||||
<mxGeometry height="58" width="110" x="1096" y="489" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_mon" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;" value="Monitoring (Roche Analytics)" vertex="1">
|
||||
<mxGeometry height="50" width="250" x="603" y="566" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_adclab" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="CLAB-Adapter" vertex="1">
|
||||
<mxGeometry height="50" width="160" x="90" y="430" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_addev" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Device-Adapter
Sysmex IPU · Myla/Maestria · LabOps · Desuri · Liason" vertex="1">
|
||||
<mxGeometry height="50" width="280" x="290" y="430" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_clab" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="CLAB (LIS)" vertex="1">
|
||||
<mxGeometry height="56" width="160" x="90" y="560" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_dev" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="Devices
Sysmex-Straße · Atras SL · Analyzer" vertex="1">
|
||||
<mxGeometry height="56" width="280" x="290" y="560" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_e_abm" edge="1" parent="1" source="es_abm" style="endArrow=classic;html=1;rounded=0;" target="es_adabm">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_e_lac" edge="1" parent="1" source="es_lac" style="endArrow=classic;html=1;rounded=0;" target="es_adlac">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_e_mdn" edge="1" parent="1" source="es_mdn" style="endArrow=classic;html=1;rounded=0;" target="es_admdn">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_e_mds" edge="1" parent="1" source="es_mds" style="endArrow=classic;html=1;rounded=0;" target="es_admds">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_p_abm" edge="1" parent="1" source="es_adabm" style="endArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_store" value="publish">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_p_lac" edge="1" parent="1" source="es_adlac" style="endArrow=classic;html=1;rounded=0;" target="es_store">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_p_mdn" edge="1" parent="1" source="es_admdn" style="endArrow=classic;html=1;rounded=0;" target="es_store">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_p_mds" edge="1" parent="1" source="es_admds" style="endArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_store" value="publish">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_x_map" edge="1" parent="1" source="es_store" style="endArrow=classic;startArrow=classic;html=1;rounded=0;dashed=1;fontStyle=2;" target="es_pmap" value="consume / publish">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_x_route" edge="1" parent="1" source="es_store" style="endArrow=classic;startArrow=classic;html=1;rounded=0;dashed=1;" target="es_proute">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_s_order" edge="1" parent="1" source="es_store" style="endArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_jorder" value="subscribe">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_s_md" edge="1" parent="1" source="es_store" style="endArrow=classic;html=1;rounded=0;" target="es_jmd">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_s_cat" edge="1" parent="1" source="es_store" style="endArrow=classic;html=1;rounded=0;" target="es_jcat">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_s_mon" edge="1" parent="1" source="es_store" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_mon" value="subscribe">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="600" y="468" />
|
||||
<mxPoint x="720" y="468" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="es_x_clab" edge="1" parent="1" source="es_store" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_adclab" value="publish / subscribe">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_x_dev" edge="1" parent="1" source="es_store" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" target="es_addev">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_n_clab" edge="1" parent="1" source="es_adclab" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_clab" value="LDT / natives Protokoll">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_n_dev" edge="1" parent="1" source="es_addev" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_dev" value="natives Protokoll">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
<diagram id="event-driven" name="TO-BE (Empfehlung)">
|
||||
<mxGraphModel dx="1240" dy="900" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1200" pageHeight="1000" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="m_title" parent="1" style="text;html=1;align=left;fontStyle=1;fontSize=16;" value="TO-BE (Empfehlung) — Canonical Store als System of Record + Integration über Events" vertex="1">
|
||||
<mxGeometry height="26" width="900" x="60" y="10" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_leg" parent="1" style="text;html=1;align=left;fontStyle=1;" value="Legend" vertex="1">
|
||||
<mxGeometry height="20" width="60" x="60" y="46" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_leg_own" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="own" vertex="1">
|
||||
<mxGeometry height="24" width="80" x="120" y="44" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_leg_tp" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;" value="third-party" vertex="1">
|
||||
<mxGeometry height="24" width="90" x="210" y="44" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_note" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFF2CC;strokeColor=#D6B656;dashed=1;fontStyle=2;align=left;spacingLeft=8;" value="Unterschied zu Seite 2: kein direkter DB-Zugriff — Integration ausschließlich über Events.
Unterschied zu Seite 3: Store ist zustandsbasiertes System of Record, kein append-only Event-Log." vertex="1">
|
||||
<mxGeometry height="60" width="420" x="700" y="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_lac" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="LabAccess
(Order Entry I)" vertex="1">
|
||||
<mxGeometry height="56" width="170" x="80" y="90" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_mdn" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="MDN
(Order Entry II)" vertex="1">
|
||||
<mxGeometry height="56" width="170" x="290" y="90" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_abm" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="AB+M
(Order Entry)" vertex="1">
|
||||
<mxGeometry height="56" width="170" x="500" y="90" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_adlac" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Adapter" vertex="1">
|
||||
<mxGeometry height="40" width="170" x="80" y="185" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_admdn" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Adapter" vertex="1">
|
||||
<mxGeometry height="40" width="170" x="290" y="185" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_adabm" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Adapter" vertex="1">
|
||||
<mxGeometry height="40" width="170" x="500" y="185" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_srv" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#F8F8F8;strokeColor=#999999;verticalAlign=top;fontStyle=1;fontSize=14;" value="Integration Server" vertex="1">
|
||||
<mxGeometry height="360" width="1080" x="60" y="270" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_bus" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;fontStyle=1;fontSize=13;" value="Event Bus — publish / subscribe" vertex="1">
|
||||
<mxGeometry height="50" width="1020" x="90" y="320" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_route" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Routing Engine" vertex="1">
|
||||
<mxGeometry height="50" width="170" x="100" y="430" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_map" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Mapping / Transformation" vertex="1">
|
||||
<mxGeometry height="50" width="190" x="300" y="430" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_mon" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Monitoring
(Roche Analytics)" vertex="1">
|
||||
<mxGeometry height="50" width="170" x="520" y="430" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_store" parent="1" style="shape=cylinder3;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;boundedLbl=1;backgroundOutline=1;size=14;verticalAlign=middle;" value="<b>Single Point of Truth</b><br>canonical store · System of Record<br>Stammdaten · SinaCRM · Leistungsverzeichnis (OTS/Znooni)" vertex="1">
|
||||
<mxGeometry height="150" width="320" x="760" y="410" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_adclab" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="CLAB-Adapter" vertex="1">
|
||||
<mxGeometry height="50" width="170" x="120" y="700" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_addev" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Device-Adapter
Sysmex IPU · Myla/Maestria · LabOps · Desuri · Liason" vertex="1">
|
||||
<mxGeometry height="50" width="320" x="360" y="700" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_clab" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="CLAB (LIS)" vertex="1">
|
||||
<mxGeometry height="56" width="170" x="120" y="800" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_dev" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="Devices
Sysmex-Straße · Atras SL · Analyzer" vertex="1">
|
||||
<mxGeometry height="56" width="320" x="360" y="800" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_e_lac" edge="1" parent="1" source="m_lac" style="endArrow=classic;html=1;rounded=0;" target="m_adlac">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_e_mdn" edge="1" parent="1" source="m_mdn" style="endArrow=classic;html=1;rounded=0;" target="m_admdn">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_e_abm" edge="1" parent="1" source="m_abm" style="endArrow=classic;html=1;rounded=0;" target="m_adabm">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_b_lac" edge="1" parent="1" source="m_adlac" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;" target="m_bus" value="publish / subscribe">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_b_mdn" edge="1" parent="1" source="m_admdn" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" target="m_bus">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_b_abm" edge="1" parent="1" source="m_adabm" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" target="m_bus">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_b_route" edge="1" parent="1" source="m_bus" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;" target="m_route" value="consume / publish">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_b_map" edge="1" parent="1" source="m_bus" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" target="m_map">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_b_mon" edge="1" parent="1" source="m_bus" style="endArrow=classic;html=1;rounded=0;fontStyle=2;" target="m_mon" value="subscribe">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_b_store" edge="1" parent="1" source="m_bus" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;" target="m_store" value="Events → State / Read">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_b_clab" edge="1" parent="1" source="m_bus" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;exitX=0.05;exitY=1;exitDx=0;exitDy=0;" target="m_adclab" value="publish / subscribe">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_b_dev" edge="1" parent="1" source="m_bus" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;startArrow=classic;html=1;rounded=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;" target="m_addev">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_n_clab" edge="1" parent="1" source="m_adclab" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;" target="m_clab" value="LDT / natives Protokoll">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="m_n_dev" edge="1" parent="1" source="m_addev" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;" target="m_dev" value="natives Protokoll">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
Binary file not shown.
@@ -0,0 +1,181 @@
|
||||
<mxfile host="Electron">
|
||||
<diagram id="event-sourcing" name="TO-BE (Event Sourcing)">
|
||||
<mxGraphModel dx="1240" dy="984" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1320" pageHeight="900" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="rWyWgaAAbOhaxAdMFHOU-9" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="" vertex="1">
|
||||
<mxGeometry height="93" width="500" x="80" y="453" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rWyWgaAAbOhaxAdMFHOU-8" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="" vertex="1">
|
||||
<mxGeometry height="60" width="1110" x="54" y="230" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_title" parent="1" style="text;html=1;align=left;fontStyle=1;fontSize=16;" value="TO-BE (Variante) — Event-Sourcing-Integration" vertex="1">
|
||||
<mxGeometry height="26" width="700" x="60" y="10" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_leg" parent="1" style="text;html=1;align=left;fontStyle=1;" value="Legend" vertex="1">
|
||||
<mxGeometry height="20" width="60" x="60" y="89" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_leg_own" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="own" vertex="1">
|
||||
<mxGeometry height="24" width="80" x="120" y="87" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_leg_tp" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;" value="third-party" vertex="1">
|
||||
<mxGeometry height="24" width="90" x="210" y="87" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_leg_ev" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFF2CC;strokeColor=#D6B656;" value="Event-Store" vertex="1">
|
||||
<mxGeometry height="24" width="110" x="310" y="87" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_abm" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="AB+M
(Order Entry)" vertex="1">
|
||||
<mxGeometry height="56" width="160" x="70" y="140" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_lac" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="LabAccess
(Order Entry I)" vertex="1">
|
||||
<mxGeometry height="56" width="160" x="260" y="140" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_mdn" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="MDN
(Order Entry II)" vertex="1">
|
||||
<mxGeometry height="56" width="160" x="450" y="140" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_mds" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="Stammdaten-Quellen
SinaCRM · OTS/Znooni" vertex="1">
|
||||
<mxGeometry height="56" width="230" x="650" y="140" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_adabm" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;strokeWidth=2;" value="Adapter
(Order → Event)" vertex="1">
|
||||
<mxGeometry height="44" width="160" x="70" y="240" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_adlac" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;strokeWidth=2;" value="Adapter
(Order → Event)" vertex="1">
|
||||
<mxGeometry height="44" width="160" x="260" y="240" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_admdn" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;strokeWidth=2;" value="Adapter
(Order → Event)" vertex="1">
|
||||
<mxGeometry height="44" width="160" x="450" y="240" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_admds" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;strokeWidth=2;" value="Adapter
(MasterData → Event)" vertex="1">
|
||||
<mxGeometry height="44" width="230" x="650" y="240" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_store" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFF2CC;strokeColor=#D6B656;fontStyle=1;fontSize=13;" value="Event Store — append-only Event-Log
kanonische Wahrheit · Projektionen abgeleitet · Replay-fähig" vertex="1">
|
||||
<mxGeometry height="70" width="940" x="70" y="340" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_pgrp" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;verticalAlign=top;fontStyle=1;" value="Event-Prozessoren" vertex="1">
|
||||
<mxGeometry height="170" width="200" x="1050" y="320" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_pmap" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Mapping / Transformation" vertex="1">
|
||||
<mxGeometry height="46" width="160" x="1070" y="355" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_proute" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Routing Engine" vertex="1">
|
||||
<mxGeometry height="46" width="160" x="1070" y="420" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_jgrp" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;dashed=1;verticalAlign=top;fontStyle=1;" value="Projektionen / Read-Models" vertex="1">
|
||||
<mxGeometry height="107" width="470" x="751" y="507" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_jorder" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#EAF0FB;strokeColor=#6C8EBF;" value="Auftrags-Status" vertex="1">
|
||||
<mxGeometry height="58" width="130" x="771" y="539" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_jmd" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#EAF0FB;strokeColor=#6C8EBF;" value="Konsolidierte Stammdaten
(Single Point of Truth)" vertex="1">
|
||||
<mxGeometry height="58" width="170" x="916" y="539" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_jcat" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#EAF0FB;strokeColor=#6C8EBF;" value="Leistungs-
verzeichnis" vertex="1">
|
||||
<mxGeometry height="58" width="110" x="1096" y="539" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_mon" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;" value="Monitoring (Roche Analytics)" vertex="1">
|
||||
<mxGeometry height="50" width="250" x="603" y="633" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_adclab" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="CLAB-Adapter" vertex="1">
|
||||
<mxGeometry height="50" width="160" x="90" y="480" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_addev" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;" value="Device-Adapter
Sysmex IPU · Myla/Maestria · LabOps · Desuri · Liason" vertex="1">
|
||||
<mxGeometry height="50" width="280" x="290" y="480" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_clab" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="CLAB (LIS)" vertex="1">
|
||||
<mxGeometry height="56" width="160" x="90" y="627" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_dev" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="Devices
Sysmex-Straße · Atras SL · Analyzer" vertex="1">
|
||||
<mxGeometry height="56" width="280" x="290" y="627" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_e_abm" edge="1" parent="1" source="es_abm" style="endArrow=classic;html=1;rounded=0;" target="es_adabm">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_e_lac" edge="1" parent="1" source="es_lac" style="endArrow=classic;html=1;rounded=0;" target="es_adlac">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_e_mdn" edge="1" parent="1" source="es_mdn" style="endArrow=classic;html=1;rounded=0;" target="es_admdn">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_e_mds" edge="1" parent="1" source="es_mds" style="endArrow=classic;html=1;rounded=0;" target="es_admds">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_p_abm" edge="1" parent="1" source="es_adabm" style="endArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_store" value="publish">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_p_lac" edge="1" parent="1" source="es_adlac" style="endArrow=classic;html=1;rounded=0;" target="es_store">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_p_mdn" edge="1" parent="1" source="es_admdn" style="endArrow=classic;html=1;rounded=0;" target="es_store">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_p_mds" edge="1" parent="1" source="es_admds" style="endArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_store" value="publish">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_x_map" edge="1" parent="1" source="es_store" style="endArrow=classic;startArrow=classic;html=1;rounded=0;dashed=1;fontStyle=2;" target="es_pmap" value="consume / publish">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_x_route" edge="1" parent="1" source="es_store" style="endArrow=classic;startArrow=classic;html=1;rounded=0;dashed=1;" target="es_proute">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_s_order" edge="1" parent="1" source="es_store" style="endArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_jorder" value="subscribe">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_s_md" edge="1" parent="1" source="es_store" style="endArrow=classic;html=1;rounded=0;" target="es_jmd">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_s_cat" edge="1" parent="1" source="es_store" style="endArrow=classic;html=1;rounded=0;" target="es_jcat">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_s_mon" edge="1" parent="1" source="es_store" style="edgeStyle=orthogonalEdgeStyle;endArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_mon" value="subscribe">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="600" y="518" />
|
||||
<mxPoint x="720" y="518" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="es_x_clab" edge="1" parent="1" source="es_store" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_adclab" value="publish / subscribe">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_x_dev" edge="1" parent="1" source="es_store" style="endArrow=classic;startArrow=classic;html=1;rounded=0;" target="es_addev">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_n_clab" edge="1" parent="1" source="es_adclab" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_clab" value="LDT / natives Protokoll">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="es_n_dev" edge="1" parent="1" source="es_addev" style="endArrow=classic;startArrow=classic;html=1;rounded=0;fontStyle=2;" target="es_dev" value="natives Protokoll">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rWyWgaAAbOhaxAdMFHOU-1" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#FFE6CC;strokeColor=#D79B00;fontStyle=1;" value="weitere thrd. Pratry Apps<div>...</div>" vertex="1">
|
||||
<mxGeometry height="60" width="230" x="916" y="140" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rWyWgaAAbOhaxAdMFHOU-2" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#DAE8FC;strokeColor=#6C8EBF;strokeWidth=2;" value="app - adapter" vertex="1">
|
||||
<mxGeometry height="44" width="230" x="916" y="240" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rWyWgaAAbOhaxAdMFHOU-3" edge="1" parent="1" source="rWyWgaAAbOhaxAdMFHOU-2" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="790" y="340" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="rWyWgaAAbOhaxAdMFHOU-4" connectable="0" parent="rWyWgaAAbOhaxAdMFHOU-3" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" value="publish" vertex="1">
|
||||
<mxGeometry relative="1" x="-0.2089" y="2" as="geometry">
|
||||
<mxPoint as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="rWyWgaAAbOhaxAdMFHOU-5" edge="1" parent="1" source="rWyWgaAAbOhaxAdMFHOU-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" target="rWyWgaAAbOhaxAdMFHOU-2">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rWyWgaAAbOhaxAdMFHOU-10" parent="1" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;" value="Abstraktion" vertex="1">
|
||||
<mxGeometry height="24" width="110" x="437" y="87" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rWyWgaAAbOhaxAdMFHOU-11" parent="1" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#fff2cc;strokeColor=#000000;strokeWidth=2;" value="" vertex="1">
|
||||
<mxGeometry height="50" width="60" x="101" y="351" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="rWyWgaAAbOhaxAdMFHOU-13" parent="1" style="text;html=1;whiteSpace=wrap;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;rounded=0;" value="master- data" vertex="1">
|
||||
<mxGeometry height="30" width="70" x="170" y="340" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Fügt Folie2, Folie3, Folie4 zu einer Datei zusammen (Reihenfolge 2, 3, 4)."""
|
||||
|
||||
import copy
|
||||
import os
|
||||
from pptx import Presentation
|
||||
|
||||
base = os.path.dirname(os.path.abspath(__file__)) + "/"
|
||||
dst = Presentation(base + "Folie2.pptx") # Seite 1 = Folie 2
|
||||
blank = dst.slide_layouts[6]
|
||||
|
||||
for fname in ("Folie3.pptx", "Folie3b.pptx", "Folie4.pptx"): # Seiten 2, 3, 4, 5
|
||||
src = Presentation(base + fname)
|
||||
new_slide = dst.slides.add_slide(blank)
|
||||
for shape in src.slides[0].shapes:
|
||||
new_slide.shapes._spTree.append(copy.deepcopy(shape._element))
|
||||
|
||||
out = base + "Workshop_LIS.pptx"
|
||||
dst.save(out)
|
||||
print("saved", out)
|
||||
Reference in New Issue
Block a user