|
6 | 6 | Dagre,
|
7 | 7 | Group,
|
8 | 8 | Html,
|
| 9 | + Line, |
| 10 | + Rect, |
9 | 11 | Spline,
|
10 | 12 | Svg,
|
| 13 | + Text, |
11 | 14 | Tooltip,
|
12 | 15 | ancestors,
|
13 | 16 | descendants
|
|
156 | 159 | <Separator fullWidthExtend={true} wide={true} />
|
157 | 160 |
|
158 | 161 | <div class="flex-1 flex py-4">
|
159 |
| - <div class="flex-1 border rounded"> |
| 162 | + <div class="flex-1 border rounded grid grid-stack"> |
160 | 163 | <Chart
|
161 | 164 | data={chartData}
|
162 | 165 | transform={{
|
|
166 | 169 | }}
|
167 | 170 | padding={{ top: 60, bottom: 20, left: 20, right: 20 }}
|
168 | 171 | let:tooltip
|
| 172 | + let:width |
| 173 | + let:height |
169 | 174 | >
|
170 | 175 | <TransformControls />
|
171 | 176 |
|
|
308 | 313 | </Dagre>
|
309 | 314 | </div>
|
310 | 315 |
|
| 316 | + <!-- Put legend in separate SVG layer to not be affected by transform (pan/zoom) --> |
| 317 | + <Svg ignoreTransform> |
| 318 | + {@const legendWidth = 200} |
| 319 | + {@const legendHeight = 90} |
| 320 | + {@const legendPadding = 20} |
| 321 | + {@const legendLabelWidth = 72} |
| 322 | + {@const legendItems = [ |
| 323 | + { |
| 324 | + label: 'Batch', |
| 325 | + class: |
| 326 | + 'stroke-purple-500 stroke-[2] [stroke-dasharray:30_100] [stroke-dashoffset:130] animate-dashoffset-0.5x' |
| 327 | + }, |
| 328 | + { |
| 329 | + label: 'Streaming', |
| 330 | + class: |
| 331 | + 'stroke-blue-500 stroke-[2] [stroke-dasharray:10_10] [stroke-dashoffset:20] animate-dashoffset-2x' |
| 332 | + } |
| 333 | + ]} |
| 334 | + |
| 335 | + <Group x={width - legendWidth} y={height - legendHeight}> |
| 336 | + <Rect |
| 337 | + x={0} |
| 338 | + y={0} |
| 339 | + width={legendWidth} |
| 340 | + height={legendHeight} |
| 341 | + class="fill-neutral-100 stroke-border" |
| 342 | + rx={8} |
| 343 | + /> |
| 344 | + <Text |
| 345 | + value="Legend" |
| 346 | + x={legendPadding} |
| 347 | + y={24} |
| 348 | + width={legendWidth} |
| 349 | + textAnchor="start" |
| 350 | + class="text-sm fill-surface-content font-bold" |
| 351 | + /> |
| 352 | + <Group y={24}> |
| 353 | + {#each legendItems as item, i (item.label)} |
| 354 | + <Text |
| 355 | + value={item.label} |
| 356 | + x={legendPadding} |
| 357 | + y={24 + i * 24} |
| 358 | + class="text-xs fill-surface-content/50" |
| 359 | + /> |
| 360 | + <Line |
| 361 | + x1={legendPadding + legendLabelWidth} |
| 362 | + y1={20 + i * 24} |
| 363 | + x2={legendWidth - legendPadding} |
| 364 | + y2={20 + i * 24} |
| 365 | + class={item.class} |
| 366 | + /> |
| 367 | + {/each} |
| 368 | + </Group> |
| 369 | + </Group> |
| 370 | + </Svg> |
| 371 | + |
311 | 372 | {#if !hideTooltip}
|
312 | 373 | <Tooltip.Root {...tooltipProps.root} contained="window" xOffset={0} yOffset={30} let:data>
|
313 | 374 | <Tooltip.List {...tooltipProps.list}>
|
|
338 | 399 | {/if}
|
339 | 400 |
|
340 | 401 | <!-- EntitySource -->
|
341 |
| - |
342 | 402 | {#each ['table', 'snapshotTable', 'mutationTable', 'mutationTopic'] as prop}
|
343 | 403 | {#if data.value.conf[prop] !== undefined}
|
344 | 404 | <Tooltip.Item
|
|
0 commit comments