Repository URL to install this package:
|
Version:
2.2.1 ▾
|
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["dagDependencies"] = factory();
else
root["Airflow"] = root["Airflow"] || {}, root["Airflow"]["dagDependencies"] = factory();
})(window, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 9);
/******/ })
/************************************************************************/
/******/ ({
/***/ 9:
/***/ (function(module, exports) {
/*!
* 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.
*/
/*
global d3, localStorage, dagreD3, dagNodes, edges, arrange, document,
*/
const highlightColor = '#000000';
const upstreamColor = '#2020A0';
const downstreamColor = '#0000FF';
const initialStrokeWidth = '3px';
const highlightStrokeWidth = '5px';
const duration = 500;
let nodes = dagNodes;
const fullNodes = nodes;
const filteredNodes = nodes.filter(n => edges.some(e => e.u === n.id || e.v === n.id)); // Preparation of DagreD3 data structures
let g = new dagreD3.graphlib.Graph().setGraph({
nodesep: 15,
ranksep: 15,
rankdir: arrange
}).setDefaultEdgeLabel(() => ({
lineInterpolate: 'basis'
}));
const render = dagreD3.render();
const svg = d3.select('#graph-svg');
const innerSvg = d3.select('#graph-svg g'); // Returns true if a node's id or its children's id matches search_text
function nodeMatches(nodeId, searchText) {
if (nodeId.indexOf(searchText) > -1) return true;
return false;
}
function highlightNodes(nodesToHighlight, color, strokeWidth) {
nodesToHighlight.forEach(nodeid => {
const myNode = g.node(nodeid).elem;
d3.select(myNode).selectAll('rect,circle').style('stroke', color).style('stroke-width', strokeWidth);
});
}
let zoom = null;
function setUpZoomSupport() {
// Set up zoom support for Graph
zoom = d3.behavior.zoom().on('zoom', () => {
innerSvg.attr('transform', `translate(${d3.event.translate})scale(${d3.event.scale})`);
});
svg.call(zoom); // Centering the DAG on load
// Get Dagre Graph dimensions
const graphWidth = g.graph().width;
const graphHeight = g.graph().height; // Get SVG dimensions
const padding = 20;
const svgBb = svg.node().getBoundingClientRect();
const width = svgBb.width - padding * 2;
const height = svgBb.height - padding; // we are not centering the dag vertically
// Calculate applicable scale for zoom
const zoomScale = Math.min(Math.min(width / graphWidth, height / graphHeight), 1.5 // cap zoom level to 1.5 so nodes are not too large
);
zoom.translate([width / 2 - graphWidth * zoomScale / 2 + padding, padding]);
zoom.scale(zoomScale);
zoom.event(innerSvg);
}
function setUpNodeHighlighting(focusItem = null) {
d3.selectAll('g.node').on('mouseover', function (d) {
d3.select(this).selectAll('rect').style('stroke', highlightColor);
highlightNodes(g.predecessors(d), upstreamColor, highlightStrokeWidth);
highlightNodes(g.successors(d), downstreamColor, highlightStrokeWidth);
const adjacentNodeNames = [d, ...g.predecessors(d), ...g.successors(d)];
d3.selectAll('g.nodes g.node').filter(x => !adjacentNodeNames.includes(x)).style('opacity', 0.2);
const adjacentEdges = g.nodeEdges(d);
d3.selectAll('g.edgePath')[0] // eslint-disable-next-line no-underscore-dangle
.filter(x => !adjacentEdges.includes(x.__data__)).forEach(x => {
d3.select(x).style('opacity', 0.2);
});
});
d3.selectAll('g.node').on('mouseout', function (d) {
d3.select(this).selectAll('rect,circle').style('stroke', null);
highlightNodes(g.predecessors(d), null, initialStrokeWidth);
highlightNodes(g.successors(d), null, initialStrokeWidth);
d3.selectAll('g.node').style('opacity', 1);
d3.selectAll('g.node rect').style('stroke-width', initialStrokeWidth);
d3.selectAll('g.edgePath').style('opacity', 1);
if (focusItem) {
localStorage.removeItem(focusItem);
}
});
}
function searchboxHighlighting(s) {
let match = null;
d3.selectAll('g.nodes g.node').filter(function forEach(d) {
if (s === '') {
d3.select('g.edgePaths').transition().duration(duration).style('opacity', 1);
d3.select(this).transition().duration(duration).style('opacity', 1).selectAll('rect').style('stroke-width', initialStrokeWidth);
} else {
d3.select('g.edgePaths').transition().duration(duration).style('opacity', 0.2);
if (nodeMatches(d, s)) {
if (!match) match = this;
d3.select(this).transition().duration(duration).style('opacity', 1).selectAll('rect').style('stroke-width', highlightStrokeWidth);
} else {
d3.select(this).transition().style('opacity', 0.2).duration(duration).selectAll('rect').style('stroke-width', initialStrokeWidth);
}
}
return null;
}); // This moves the matched node to the center of the graph area
if (match) {
const transform = d3.transform(d3.select(match).attr('transform'));
const svgBb = svg.node().getBoundingClientRect();
transform.translate = [svgBb.width / 2 - transform.translate[0], svgBb.height / 2 - transform.translate[1]];
transform.scale = [1, 1];
if (zoom !== null) {
zoom.translate(transform.translate);
zoom.scale(1);
zoom.event(innerSvg);
}
}
}
d3.select('#searchbox').on('keyup', () => {
const s = document.getElementById('searchbox').value;
searchboxHighlighting(s);
});
const renderGraph = () => {
g = new dagreD3.graphlib.Graph().setGraph({
nodesep: 15,
ranksep: 15,
rankdir: arrange
}).setDefaultEdgeLabel(() => ({
lineInterpolate: 'basis'
})); // set nodes
nodes.forEach(node => {
g.setNode(node.id, node.value);
}); // Set edges
edges.forEach(edge => {
g.setEdge(edge.u, edge.v);
});
innerSvg.call(render, g);
setUpNodeHighlighting();
setUpZoomSupport();
}; // rerender graph when filtering dags with dependencies or not
document.getElementById('deps-filter').addEventListener('change', function onChange() {
// reset searchbox
document.getElementById('searchbox').value = '';
if (this.checked) {
nodes = filteredNodes;
} else {
nodes = fullNodes;
}
renderGraph();
}); // initial filter check and render
if (document.getElementById('deps-filter').checked) {
nodes = filteredNodes;
}
renderGraph();
/***/ })
/******/ });
});