mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
Merge pull request #26067 from ClickHouse/play-graphs
Render pipelines in Play UI
This commit is contained in:
commit
72e3abfef7
@ -53,5 +53,6 @@ macro(clickhouse_embed_binaries)
|
|||||||
set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/${ASSEMBLY_FILE_NAME}" APPEND PROPERTY INCLUDE_DIRECTORIES "${EMBED_RESOURCE_DIR}")
|
set_property(SOURCE "${CMAKE_CURRENT_BINARY_DIR}/${ASSEMBLY_FILE_NAME}" APPEND PROPERTY INCLUDE_DIRECTORIES "${EMBED_RESOURCE_DIR}")
|
||||||
|
|
||||||
target_sources("${EMBED_TARGET}" PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${ASSEMBLY_FILE_NAME}")
|
target_sources("${EMBED_TARGET}" PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${ASSEMBLY_FILE_NAME}")
|
||||||
|
set_target_properties("${EMBED_TARGET}" PROPERTIES OBJECT_DEPENDS "${RESOURCE_FILE}")
|
||||||
endforeach()
|
endforeach()
|
||||||
endmacro()
|
endmacro()
|
||||||
|
@ -283,6 +283,29 @@
|
|||||||
color: var(--link-color);
|
color: var(--link-color);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is for graph in svg */
|
||||||
|
text
|
||||||
|
{
|
||||||
|
font-size: 14px;
|
||||||
|
fill: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.node rect
|
||||||
|
{
|
||||||
|
fill: var(--element-background-color);
|
||||||
|
filter: drop-shadow(.2rem .2rem .2rem var(--shadow-color));
|
||||||
|
}
|
||||||
|
|
||||||
|
.edgePath path
|
||||||
|
{
|
||||||
|
stroke: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
marker
|
||||||
|
{
|
||||||
|
fill: var(--text-color);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@ -305,6 +328,7 @@
|
|||||||
<table class="monospace shadow" id="data-table"></table>
|
<table class="monospace shadow" id="data-table"></table>
|
||||||
<pre class="monospace shadow" id="data-unparsed"></pre>
|
<pre class="monospace shadow" id="data-unparsed"></pre>
|
||||||
</div>
|
</div>
|
||||||
|
<svg id="graph" fill="none"></svg>
|
||||||
<p id="error" class="monospace shadow">
|
<p id="error" class="monospace shadow">
|
||||||
</p>
|
</p>
|
||||||
</body>
|
</body>
|
||||||
@ -447,6 +471,12 @@
|
|||||||
table.removeChild(table.lastChild);
|
table.removeChild(table.lastChild);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let graph = document.getElementById('graph');
|
||||||
|
while (graph.firstChild) {
|
||||||
|
graph.removeChild(graph.lastChild);
|
||||||
|
}
|
||||||
|
graph.style.display = 'none';
|
||||||
|
|
||||||
document.getElementById('data-unparsed').innerText = '';
|
document.getElementById('data-unparsed').innerText = '';
|
||||||
document.getElementById('data-unparsed').style.display = 'none';
|
document.getElementById('data-unparsed').style.display = 'none';
|
||||||
|
|
||||||
@ -461,12 +491,21 @@
|
|||||||
|
|
||||||
function renderResult(response)
|
function renderResult(response)
|
||||||
{
|
{
|
||||||
//console.log(response);
|
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
let stats = document.getElementById('stats');
|
let stats = document.getElementById('stats');
|
||||||
stats.innerText = 'Elapsed: ' + response.statistics.elapsed.toFixed(3) + " sec, read " + response.statistics.rows_read + " rows.";
|
stats.innerText = 'Elapsed: ' + response.statistics.elapsed.toFixed(3) + " sec, read " + response.statistics.rows_read + " rows.";
|
||||||
|
|
||||||
|
/// We can also render graphs if user performed EXPLAIN PIPELINE graph=1.
|
||||||
|
if (response.data.length > 3 && response.data[0][0] === "digraph" && document.getElementById('query').value.match(/^\s*EXPLAIN/i)) {
|
||||||
|
renderGraph(response);
|
||||||
|
} else {
|
||||||
|
renderTable(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTable(response)
|
||||||
|
{
|
||||||
let thead = document.createElement('thead');
|
let thead = document.createElement('thead');
|
||||||
for (let idx in response.meta) {
|
for (let idx in response.meta) {
|
||||||
let th = document.createElement('th');
|
let th = document.createElement('th');
|
||||||
@ -559,6 +598,51 @@
|
|||||||
document.getElementById('error').style.display = 'block';
|
document.getElementById('error').style.display = 'block';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Huge JS libraries should be loaded only if needed.
|
||||||
|
function loadJS(src) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.src = src;
|
||||||
|
script.addEventListener('load', function() { resolve(true); });
|
||||||
|
document.head.appendChild(script);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let load_dagre_promise;
|
||||||
|
function loadDagre() {
|
||||||
|
if (load_dagre_promise) { return load_dagre_promise; }
|
||||||
|
|
||||||
|
load_dagre_promise = Promise.all([
|
||||||
|
loadJS('https://dagrejs.github.io/project/dagre/v0.8.5/dagre.min.js'),
|
||||||
|
loadJS('https://dagrejs.github.io/project/graphlib-dot/v0.6.4/graphlib-dot.min.js'),
|
||||||
|
loadJS('https://dagrejs.github.io/project/dagre-d3/v0.6.4/dagre-d3.min.js'),
|
||||||
|
loadJS('https://cdn.jsdelivr.net/npm/d3@7.0.0'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return load_dagre_promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function renderGraph(response)
|
||||||
|
{
|
||||||
|
await loadDagre();
|
||||||
|
|
||||||
|
/// https://github.com/dagrejs/dagre-d3/issues/131
|
||||||
|
const dot = response.data.reduce((acc, row) => acc + '\n' + row[0].replace(/shape\s*=\s*box/g, 'shape=rect'));
|
||||||
|
|
||||||
|
let graph = graphlibDot.read(dot);
|
||||||
|
graph.graph().rankdir = 'TB';
|
||||||
|
|
||||||
|
let render = new dagreD3.render();
|
||||||
|
|
||||||
|
let svg = document.getElementById('graph');
|
||||||
|
svg.style.display = 'block';
|
||||||
|
|
||||||
|
render(d3.select("#graph"), graph);
|
||||||
|
|
||||||
|
svg.style.width = graph.graph().width;
|
||||||
|
svg.style.height = graph.graph().height;
|
||||||
|
}
|
||||||
|
|
||||||
function setColorTheme(theme)
|
function setColorTheme(theme)
|
||||||
{
|
{
|
||||||
window.localStorage.setItem('theme', theme);
|
window.localStorage.setItem('theme', theme);
|
||||||
|
Loading…
Reference in New Issue
Block a user