Feature: Auto-refresh Graph view chart (#11534)
This commit is contained in:
Родитель
e7dc964619
Коммит
13959df540
|
@ -105,22 +105,25 @@ g.node.skipped rect {
|
|||
stroke: pink;
|
||||
}
|
||||
|
||||
div#svg_container {
|
||||
.svg-wrapper {
|
||||
border-radius: 4px;
|
||||
background-color: #f0f0f0;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
#refresh_button {
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
.refresh-actions {
|
||||
float: right;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#loading {
|
||||
margin: auto;
|
||||
display: none;
|
||||
position: relative;
|
||||
width: 100px;
|
||||
top: -550px;
|
||||
.refresh-actions > .switch-label {
|
||||
margin: 0 10px 0 20px;
|
||||
}
|
||||
|
||||
.loading-dots.refresh-loading {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
@keyframes loadingDotBlink {
|
||||
0% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
40% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
.loading-dots {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.loading-dot {
|
||||
display: inline-block;
|
||||
margin-left: 0.5rem;
|
||||
border-radius: 50%;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-color: currentColor;
|
||||
animation: loadingDotBlink 1.2s infinite;
|
||||
animation-fill-mode: both;
|
||||
will-change: opacity;
|
||||
}
|
||||
|
||||
.loading-dot:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.loading-dot:nth-child(2) {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
.loading-dot:nth-child(3) {
|
||||
animation-delay: 0.4s;
|
||||
}
|
|
@ -21,6 +21,7 @@
|
|||
display: inline-block;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.switch-input {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
{% block head_css %}
|
||||
{{ super() }}
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for_asset('graph.css') }}">
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for_asset('loadingDots.css') }}">
|
||||
<style type="text/css">
|
||||
{% for state, state_color in state_color_mapping.items() %}
|
||||
g.node.{{state}} rect {
|
||||
|
@ -99,17 +100,30 @@
|
|||
<span id="error_msg">Oops.</span>
|
||||
</div>
|
||||
<br>
|
||||
<button class="btn btn-default pull-right" id="refresh_button">
|
||||
<span class="material-icons" aria-hidden="true">refresh</span>
|
||||
</button>
|
||||
<div id="svg_container">
|
||||
<svg id="graph-svg" width="{{ width }}" height="{{ height }}">
|
||||
<g id='dig' transform="translate(20,20)"></g>
|
||||
<filter id="blur-effect-1">
|
||||
<feGaussianBlur stdDeviation="3"></feGaussianBlur>
|
||||
</filter>
|
||||
</svg>
|
||||
<img id="loading" alt="spinner" src="{{ url_for('static', filename='loading.gif') }}">
|
||||
<div class="refresh-actions">
|
||||
<span class="loading-dots refresh-loading" id="loading-dots" >
|
||||
<span class="loading-dot"></span>
|
||||
<span class="loading-dot"></span>
|
||||
<span class="loading-dot"></span>
|
||||
</span>
|
||||
<label class="switch-label">
|
||||
<input class="switch-input" id="auto_refresh" type="checkbox" checked>
|
||||
<span class="switch" aria-hidden="true"></span>
|
||||
Auto-refresh
|
||||
</label>
|
||||
<button class="btn btn-default btn-sm" id="refresh_button">
|
||||
<span class="material-icons" aria-hidden="true">refresh</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="svg-wrapper">
|
||||
<div class="graph-svg-wrap">
|
||||
<svg id="graph-svg" width="{{ width }}" height="{{ height }}">
|
||||
<g id="dig" transform="translate(20,20)"></g>
|
||||
<filter id="blur-effect-1">
|
||||
<feGaussianBlur stdDeviation="3"></feGaussianBlur>
|
||||
</filter>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
@ -453,27 +467,54 @@
|
|||
return false
|
||||
}
|
||||
|
||||
function initRefreshButton() {
|
||||
d3.select("#refresh_button").on("click", () => {
|
||||
$("#loading").css("display", "block");
|
||||
$("div#svg_container").css("opacity", "0.2");
|
||||
$.get(getTaskInstanceURL)
|
||||
.done(
|
||||
(tis) => {
|
||||
task_instances = JSON.parse(tis)
|
||||
updateNodesStates(task_instances);
|
||||
$("#loading").hide();
|
||||
$("div#svg_container").css("opacity", "1");
|
||||
$('#error').hide();
|
||||
}
|
||||
).fail((_, textStatus, err) => {
|
||||
$('#error_msg').html(`${textStatus}: ${err}`);
|
||||
$('#error').show();
|
||||
$('#loading').hide();
|
||||
$('#chart_section').hide(1000);
|
||||
$('#datatable_section').hide(1000);
|
||||
});
|
||||
});
|
||||
function handleRefresh() {
|
||||
$('#loading-dots').css('display', 'inline-block');
|
||||
$.get(getTaskInstanceURL)
|
||||
.done(
|
||||
(tis) => {
|
||||
task_instances = JSON.parse(tis)
|
||||
updateNodesStates(task_instances);
|
||||
setTimeout(function() { $('#loading-dots').hide(); }, 500);
|
||||
$('#error').hide();
|
||||
}
|
||||
).fail((_, textStatus, err) => {
|
||||
$('#error_msg').text(`${textStatus}: ${err}`);
|
||||
$('#error').show();
|
||||
setTimeout(function() { $('#loading-dots').hide(); }, 500);
|
||||
$('#chart_section').hide(1000);
|
||||
$('#datatable_section').hide(1000);
|
||||
});
|
||||
}
|
||||
|
||||
var refreshInterval;
|
||||
|
||||
function startOrStopRefresh() {
|
||||
if ($('#auto_refresh').is(':checked')) {
|
||||
refreshInterval = setInterval(function() {
|
||||
handleRefresh();
|
||||
}, 3000); // run refresh every 3 seconds
|
||||
} else {
|
||||
clearInterval(refreshInterval);
|
||||
}
|
||||
}
|
||||
|
||||
$('#auto_refresh').change(function() {
|
||||
if ($('#auto_refresh').is(':checked')) {
|
||||
// Run an initial refesh before starting interval if manually turned on
|
||||
handleRefresh();
|
||||
localStorage.removeItem('disableAutoRefresh');
|
||||
} else {
|
||||
localStorage.setItem('disableAutoRefresh', 'true');
|
||||
}
|
||||
startOrStopRefresh();
|
||||
});
|
||||
|
||||
function initRefresh() {
|
||||
if (!!localStorage.getItem('disableAutoRefresh')) {
|
||||
$('#auto_refresh').removeAttr('checked');
|
||||
}
|
||||
startOrStopRefresh();
|
||||
d3.select('#refresh_button').on('click', () => handleRefresh());
|
||||
}
|
||||
|
||||
// Generate tooltip for a group node
|
||||
|
@ -715,7 +756,6 @@
|
|||
|
||||
expand_group(null, nodes)
|
||||
|
||||
initRefreshButton();
|
||||
|
||||
initRefresh();
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -42,6 +42,7 @@ const config = {
|
|||
ganttChartD3v2: `${STATIC_DIR}/js/gantt-chart-d3v2.js`,
|
||||
graph: `${STATIC_DIR}/css/graph.css`,
|
||||
ie: `${STATIC_DIR}/js/ie.js`,
|
||||
loadingDots: `${STATIC_DIR}/css/loading-dots.css`,
|
||||
main: `${STATIC_DIR}/css/main.css`,
|
||||
materialIcons: `${STATIC_DIR}/css/material-icons.css`,
|
||||
moment: 'moment-timezone',
|
||||
|
|
Загрузка…
Ссылка в новой задаче