[AIRFLOW-2782][Airflow 2782] Upgrades the Dagre D3 version
Closes #3634 from verdan/AIRFLOW-2782-upgrade- dagre-d3
This commit is contained in:
Родитель
53933c0a49
Коммит
c3f4af5998
|
@ -1887,6 +1887,40 @@
|
|||
"d3-selection": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"dagre": {
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/dagre/-/dagre-0.7.4.tgz",
|
||||
"integrity": "sha1-3nLw50pVDOEc5jjwoTb+1xI5gCI=",
|
||||
"requires": {
|
||||
"graphlib": "^1.0.5",
|
||||
"lodash": "^3.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
|
||||
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
|
||||
}
|
||||
}
|
||||
},
|
||||
"dagre-d3": {
|
||||
"version": "0.4.18",
|
||||
"resolved": "https://registry.npmjs.org/dagre-d3/-/dagre-d3-0.4.18.tgz",
|
||||
"integrity": "sha512-7tRltaOfNTIkNEZYMCL8N3Q8bCre99x/mAJL2RbuUfPu5d+4f0KOHglZm+AzOG2Z/+S2HBDYciE6iDcDtki6Tg==",
|
||||
"requires": {
|
||||
"d3": "^3.3.8",
|
||||
"dagre": "^0.7.3",
|
||||
"graphlib": "^1.0.5",
|
||||
"lodash": "^3.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
|
||||
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
|
||||
}
|
||||
}
|
||||
},
|
||||
"datatables.net": {
|
||||
"version": "1.10.19",
|
||||
"resolved": "https://registry.npmjs.org/datatables.net/-/datatables.net-1.10.19.tgz",
|
||||
|
@ -3240,6 +3274,21 @@
|
|||
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
|
||||
"dev": true
|
||||
},
|
||||
"graphlib": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/graphlib/-/graphlib-1.0.7.tgz",
|
||||
"integrity": "sha1-DKst8P/mq+BwsmJb+h7bbslnuLE=",
|
||||
"requires": {
|
||||
"lodash": "^3.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"lodash": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
|
||||
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
|
||||
}
|
||||
}
|
||||
},
|
||||
"handlebars": {
|
||||
"version": "4.0.11",
|
||||
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz",
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
"bootstrap-toggle": "^2.2.2",
|
||||
"d3": "^3.4.4",
|
||||
"d3-tip": "^0.9.1",
|
||||
"dagre-d3": "^0.4.18",
|
||||
"datatables.net": "^1.10.19",
|
||||
"datatables.net-bs": "^1.10.19",
|
||||
"npm": "^6.1.0",
|
||||
|
|
|
@ -34,14 +34,17 @@ svg {
|
|||
.edgePath {
|
||||
stroke: #333;
|
||||
stroke-width: 1px;
|
||||
fill: none;
|
||||
}
|
||||
|
||||
g.node rect {
|
||||
stroke-width: 3;
|
||||
stroke-width: 3px;
|
||||
stroke: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
g.node .label {
|
||||
font-size: inherit;
|
||||
font-weight: normal;
|
||||
}
|
||||
g.node text {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -94,14 +94,14 @@
|
|||
{{ super() }}
|
||||
|
||||
<script src="{{ url_for_asset('d3.min.js') }}"></script>
|
||||
{# It's an old or custom dagre-d3 library not supported with webpack 4. #}
|
||||
{# TODO: Fix this using NPM version #}
|
||||
<script src="{{ url_for_asset('dagreD3.js') }}"></script>
|
||||
<script src="{{ url_for_asset('dagre-d3.min.js') }}"></script>
|
||||
<script>
|
||||
|
||||
var highlight_color = "#000000";
|
||||
var upstream_color = "#2020A0";
|
||||
var downstream_color = "#0000FF";
|
||||
var initialStrokeWidth = '3px';
|
||||
var highlightStrokeWidth = '5px';
|
||||
|
||||
var nodes = {{ nodes|safe }};
|
||||
var edges = {{ edges|safe }};
|
||||
|
@ -109,16 +109,49 @@
|
|||
var task_instances = {{ task_instances|safe }};
|
||||
var execution_date = "{{ execution_date }}";
|
||||
var arrange = "{{ arrange }}";
|
||||
var g = dagreD3.json.decode(nodes, edges);
|
||||
|
||||
var duration = 500;
|
||||
var stateFocusMap = {
|
||||
'no status':false, 'failed':false, 'running':false,
|
||||
'queued': false, 'success': false};
|
||||
|
||||
// Preparation of DagreD3 data structures
|
||||
var g = new dagreD3.graphlib.Graph().setGraph({
|
||||
nodesep: 15,
|
||||
ranksep: 15,
|
||||
rankdir: arrange,
|
||||
})
|
||||
.setDefaultEdgeLabel(function() { return { lineInterpolate: 'basis' } });
|
||||
|
||||
var layout = dagreD3.layout().rankDir(arrange).nodeSep(15).rankSep(15);
|
||||
var renderer = new dagreD3.Renderer();
|
||||
renderer.layout(layout).run(g, d3.select("#dig"));
|
||||
// Set all nodes and styles
|
||||
nodes.forEach(function(node) {
|
||||
g.setNode(node.id, node.value)
|
||||
});
|
||||
|
||||
// Set edges
|
||||
edges.forEach(function(edge) {
|
||||
g.setEdge(edge.u, edge.v)
|
||||
});
|
||||
|
||||
var render = dagreD3.render(),
|
||||
svg = d3.select("svg"),
|
||||
innerSvg = d3.select("svg g");
|
||||
|
||||
innerSvg.call(render, g);
|
||||
|
||||
function setUpZoomSupport() {
|
||||
// Set up zoom support for Graph
|
||||
var zoom = d3.behavior.zoom().on("zoom", function() {
|
||||
innerSvg.attr("transform", "translate(" + d3.event.translate + ")" +
|
||||
"scale(" + d3.event.scale + ")");
|
||||
});
|
||||
svg.call(zoom);
|
||||
}
|
||||
|
||||
// Centering the DAG on load (Not implemented yet)
|
||||
// https://github.com/dagrejs/dagre-d3/issues/245
|
||||
|
||||
setUpZoomSupport();
|
||||
inject_node_ids(tasks);
|
||||
update_nodes_states(task_instances);
|
||||
|
||||
|
@ -133,14 +166,14 @@
|
|||
|
||||
function highlight_nodes(nodes, color) {
|
||||
nodes.forEach (function (nodeid) {
|
||||
my_node = d3.select('#' + nodeid + ' rect');
|
||||
my_node.style("stroke", color) ;
|
||||
my_node = d3.select('#' + nodeid).node().parentNode;
|
||||
d3.select(my_node).selectAll("rect").style("stroke", color) ;
|
||||
})
|
||||
}
|
||||
|
||||
d3.selectAll("g.node").on("mouseover", function(d){
|
||||
d3.select(this).selectAll("rect").style("stroke", highlight_color) ;
|
||||
highlight_nodes(g.predecessors(d), upstream_color)
|
||||
highlight_nodes(g.predecessors(d), upstream_color);
|
||||
highlight_nodes(g.successors(d), downstream_color)
|
||||
|
||||
});
|
||||
|
@ -209,7 +242,7 @@
|
|||
.transition().duration(duration)
|
||||
.style("opacity", 1)
|
||||
.selectAll("rect")
|
||||
.style("stroke-width", "2px");
|
||||
.style("stroke-width", initialStrokeWidth);
|
||||
}
|
||||
else{
|
||||
d3.select("g.edgePaths")
|
||||
|
@ -222,17 +255,21 @@
|
|||
.transition().duration(duration)
|
||||
.style("opacity", 1)
|
||||
.selectAll("rect")
|
||||
.style("stroke-width", "10px");
|
||||
.style("stroke-width", highlightStrokeWidth);
|
||||
}
|
||||
else {
|
||||
d3.select(this)
|
||||
.transition()
|
||||
.style("opacity", 0.2).duration(duration)
|
||||
.selectAll("rect")
|
||||
.style("stroke-width", "2px");
|
||||
.style("stroke-width", initialStrokeWidth);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// This moves the matched node in the center of the graph area
|
||||
// ToDo: Should we keep this here as it has no added value
|
||||
// and does not fit the graph on small screens, and has to scroll
|
||||
if(match) {
|
||||
var transform = d3.transform(d3.select(match).attr("transform"));
|
||||
transform.translate = [
|
||||
|
@ -244,8 +281,8 @@
|
|||
d3.select("g.zoom")
|
||||
.transition()
|
||||
.attr("transform", transform.toString());
|
||||
renderer.zoom_obj.translate(transform.translate);
|
||||
renderer.zoom_obj.scale(1);
|
||||
innerSvg.attr("transform", "translate(" + transform.translate + ")" +
|
||||
"scale(1)");
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -266,7 +303,7 @@
|
|||
function update_nodes_states(task_instances) {
|
||||
$.each(task_instances, function(task_id, ti) {
|
||||
$('tspan').filter(function(index) { return $(this).text() === task_id; })
|
||||
.parent().parent().parent()
|
||||
.parent().parent().parent().parent()
|
||||
.attr("class", "node enter " + ti.state)
|
||||
.attr("data-toggle", "tooltip")
|
||||
.attr("data-original-title", function(d) {
|
||||
|
@ -293,7 +330,7 @@
|
|||
.style("opacity", 1);
|
||||
d3.selectAll("g.node rect")
|
||||
.transition(duration)
|
||||
.style("stroke-width", "2px");
|
||||
.style("stroke-width", initialStrokeWidth);
|
||||
d3.select("g.edgePaths")
|
||||
.transition().duration(duration)
|
||||
.style("opacity", 1);
|
||||
|
@ -310,7 +347,7 @@
|
|||
.style("opacity", 1);
|
||||
d3.selectAll("g.node." + state + " rect")
|
||||
.transition(duration)
|
||||
.style("stroke-width", "10px")
|
||||
.style("stroke-width", highlightStrokeWidth)
|
||||
.style("opacity", 1);
|
||||
d3.select("g.edgePaths")
|
||||
.transition().duration(duration)
|
||||
|
@ -337,34 +374,33 @@
|
|||
return false
|
||||
}
|
||||
|
||||
function error(msg){
|
||||
$('#error_msg').html(msg);
|
||||
$('#error').show();
|
||||
$('#loading').hide();
|
||||
$('#chart_section').hide(1000);
|
||||
$('#datatable_section').hide(1000);
|
||||
function initRefreshButton() {
|
||||
d3.select("#refresh_button").on("click",
|
||||
function() {
|
||||
$("#loading").css("display", "block");
|
||||
$("div#svg_container").css("opacity", "0.2");
|
||||
$.get(
|
||||
"{{ url_for('Airflow.task_instances') }}",
|
||||
{dag_id : "{{ dag.dag_id }}", execution_date : "{{ execution_date }}"})
|
||||
.done(
|
||||
function(task_instances) {
|
||||
update_nodes_states(JSON.parse(task_instances));
|
||||
$("#loading").hide();
|
||||
$("div#svg_container").css("opacity", "1");
|
||||
$('#error').hide();
|
||||
}
|
||||
).fail(function(jqxhr, textStatus, err) {
|
||||
$('#error_msg').html(textStatus + ': ' + err);
|
||||
$('#error').show();
|
||||
$('#loading').hide();
|
||||
$('#chart_section').hide(1000);
|
||||
$('#datatable_section').hide(1000);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
d3.select("#refresh_button").on("click",
|
||||
function() {
|
||||
$("#loading").css("display", "block");
|
||||
$("div#svg_container").css("opacity", "0.2");
|
||||
$.get(
|
||||
"{{ url_for('Airflow.task_instances') }}",
|
||||
{dag_id : "{{ dag.dag_id }}", execution_date : "{{ execution_date }}"})
|
||||
.done(
|
||||
function(task_instances) {
|
||||
update_nodes_states(JSON.parse(task_instances));
|
||||
$("#loading").hide();
|
||||
$("div#svg_container").css("opacity", "1");
|
||||
$('#error').hide();
|
||||
}
|
||||
).fail(function(jqxhr, textStatus, err) {
|
||||
error(textStatus + ': ' + err);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
initRefreshButton();
|
||||
</script>
|
||||
|
||||
|
||||
|
|
|
@ -1255,6 +1255,8 @@ class Airflow(AirflowBaseView):
|
|||
'label': task.task_id,
|
||||
'labelStyle': "fill:{0};".format(task.ui_fgcolor),
|
||||
'style': "fill:{0};".format(task.ui_color),
|
||||
'rx': 5,
|
||||
'ry': 5,
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -115,6 +115,7 @@ const config = {
|
|||
{from: 'node_modules/nvd3/build/\*.min.\*',flatten:true},
|
||||
// Update this when upgrade d3 package, as the path in new D3 is different
|
||||
{from: 'node_modules/d3/d3.min.\*', flatten:true},
|
||||
{from: 'node_modules/dagre-d3/dist/\*.min.\*', flatten:true},
|
||||
{from: 'node_modules/d3-tip/dist/index.js', to:'d3-tip.js', flatten:true},
|
||||
{from: 'node_modules/bootstrap-3-typeahead/\*min.\*', flatten:true},
|
||||
{from: 'node_modules/bootstrap-toggle/**/*bootstrap-toggle.min.\*',
|
||||
|
|
Загрузка…
Ссылка в новой задаче