Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: init optimizer trace #1187

Merged
merged 20 commits into from
Mar 10, 2022
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ui/dashboardApp/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import AppContinuousProfiling from '@lib/apps/ContinuousProfiling/index.meta'
import AppQueryEditor from '@lib/apps/QueryEditor/index.meta'
import AppConfiguration from '@lib/apps/Configuration/index.meta'
import AppDebugAPI from '@lib/apps/DebugAPI/index.meta'
import AppOptimizerTrace from '@lib/apps/OptimizerTrace/index.meta'
import { handleSSOCallback, isSSOCallback } from '@lib/utils/authSSO'
import { mustLoadAppInfo, reloadWhoAmI, NgmState } from '@lib/utils/store'
// import __APP_NAME__ from '@lib/apps/__APP_NAME__/index.meta'
Expand Down Expand Up @@ -133,6 +134,7 @@ async function webPageStart() {
.register(AppQueryEditor)
.register(AppConfiguration)
.register(AppDebugAPI)
.register(AppOptimizerTrace)
// .register(__APP_NAME__)
// NOTE: Don't remove above comment line, it is a placeholder for code generator

Expand Down
74 changes: 74 additions & 0 deletions ui/lib/apps/OptimizerTrace/components/LogicalOperatorTree.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { useEffect, useRef } from 'react'
import { graphviz } from 'd3-graphviz'

import styles from './OperatorTree.module.less'

interface LogicalOperatorTreeProps {
data: LogicalOperatorNode[]
labels?: any
className?: string
}

export interface LogicalOperatorNode {
id: number
children: number[] // children id
type: string
cost: number
selected: boolean
property: string
info: string
}

export default function LogicalOperatorTree({
data,
labels = {},
className,
}: LogicalOperatorTreeProps) {
const containerRef = useRef<HTMLDivElement>(null)

useEffect(() => {
const containerEl = containerRef.current
if (!containerEl) {
return
}

const define = data
.map(
(n) =>
`${n.id} ${createLabels({
label: `${n.type}_${n.id}`,
color: labels.color || '',
tooltip: `info: ${n.info}`,
})};\n`
)
.join('')
const link = data
.map((n) =>
(n.children || [])
.map((c) => `${n.id} -> ${c} ${createLabels(labels)};\n`)
.join('')
)
.join('')

graphviz(containerEl).renderDot(
`digraph {
node [shape=ellipse fontsize=8 fontname="Verdana"];
${define}\n${link}\n}`
)
}, [containerRef, data, labels])

return (
<div
ref={containerRef}
className={`${styles.operator_tree} ${className || ''}`}
></div>
)
}

export function createLabels(labels: { [props: string]: string } = {}): string {
const ls = Object.entries(labels).filter(([k, v]) => !!v)
if (!ls.length) {
return ''
}
return `[${ls.map(([k, v]) => `${k}="${v}"`).join(' ')}]`
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.operator_tree {
height: 300px;
width: 200px;

svg {
height: 100%;
width: 100%;
}
}
67 changes: 67 additions & 0 deletions ui/lib/apps/OptimizerTrace/components/PhysicalOperatorTree.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React, { useEffect, useRef } from 'react'
import { graphviz } from 'd3-graphviz'

import styles from './OperatorTree.module.less'
import { LogicalOperatorNode, createLabels } from './LogicalOperatorTree'

export interface PhysicalOperatorNode extends LogicalOperatorNode {
parentNode: null | PhysicalOperatorNode
childrenNodes: PhysicalOperatorNode[]
mapping: string
}

interface PhysicalOperatorTreeProps {
data: PhysicalOperatorNode
className?: string
}

export default function PhysicalOperatorTree({
data,
className,
}: PhysicalOperatorTreeProps) {
const containerRef = useRef<HTMLDivElement>(null)

useEffect(() => {
const containerEl = containerRef.current
if (!containerEl) {
return
}

const allDatas = [data, ...(data.childrenNodes || [])]
const define = allDatas
.map(
(n) =>
`${n.id} ${createLabels({
label: `${n.type}_${n.id}\ncost: ${n.cost}`,
color: n.selected ? 'blue' : '',
tooltip: `info: ${n.info}`,
})};\n`
)
.join('')
const link = allDatas
.map((n) =>
(n.children || [])
.map(
(c) =>
`${n.id} -- ${c} ${createLabels({
color: n.selected ? 'blue' : '',
})};\n`
)
.join('')
)
.join('')

graphviz(containerEl).renderDot(
`graph {
node [shape=ellipse fontsize=8 fontname="Verdana"];
${define}\n${link}\n}`
)
}, [containerRef, data])

return (
<div
ref={containerRef}
className={`${styles.operator_tree} ${className || ''}`}
></div>
)
}
8 changes: 8 additions & 0 deletions ui/lib/apps/OptimizerTrace/index.meta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import translations from './translations'

export default {
id: 'optimizer_trace',
routerPrefix: '/optimizer_trace',
translations,
reactRoot: () => import(/* webpackChunkName: "app_optimizer_trace" */ '.'),
shhdgit marked this conversation as resolved.
Show resolved Hide resolved
}
35 changes: 35 additions & 0 deletions ui/lib/apps/OptimizerTrace/index.module.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
.container {
overflow: auto;
}
.operator_tree {
flex-shrink: 0;
}

.logical_optimize {
display: flex;
align-items: center;
}

.arrow {
margin: 0 10px;
}

.physical_operator_tree_container {
display: flex;
align-items: center;
}

.unselected_candidates {
border: dashed 1px #ccc;
margin-left: 10px;
padding: 5px;
}

.steps {
width: 200px;
}

.step_info {
max-height: 100px;
overflow-y: auto;
}
Loading