You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@superset.apache.org by GitBox <gi...@apache.org> on 2018/08/22 03:49:00 UTC

[GitHub] mistercrunch closed pull request #5691: Refactor force-directed graph

mistercrunch closed pull request #5691: Refactor force-directed graph
URL: https://github.com/apache/incubator-superset/pull/5691
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/superset/assets/src/explore/controls.jsx b/superset/assets/src/explore/controls.jsx
index 56bb950961..ee3e11998f 100644
--- a/superset/assets/src/explore/controls.jsx
+++ b/superset/assets/src/explore/controls.jsx
@@ -837,6 +837,7 @@ export const controls = {
 
   link_length: {
     type: 'SelectControl',
+    renderTrigger: true,
     freeForm: true,
     label: t('Link Length'),
     default: '200',
@@ -846,6 +847,7 @@ export const controls = {
 
   charge: {
     type: 'SelectControl',
+    renderTrigger: true,
     freeForm: true,
     label: t('Charge'),
     default: '-500',
diff --git a/superset/assets/src/explore/visTypes.jsx b/superset/assets/src/explore/visTypes.jsx
index f5caae7934..193ddc9059 100644
--- a/superset/assets/src/explore/visTypes.jsx
+++ b/superset/assets/src/explore/visTypes.jsx
@@ -1398,7 +1398,7 @@ export const visTypes = {
   },
 
   directed_force: {
-    label: t('Directed Force Layout'),
+    label: t('Force-directed Graph'),
     controlPanelSections: [
       {
         label: t('Query'),
diff --git a/superset/assets/src/visualizations/directed_force.js b/superset/assets/src/visualizations/directed_force.js
index b95829f9fd..b3bf0f3b97 100644
--- a/superset/assets/src/visualizations/directed_force.js
+++ b/superset/assets/src/visualizations/directed_force.js
@@ -1,18 +1,34 @@
 /* eslint-disable no-param-reassign */
 import d3 from 'd3';
-
-require('./directed_force.css');
+import PropTypes from 'prop-types';
+import './directed_force.css';
+
+const propTypes = {
+  data: PropTypes.arrayOf(PropTypes.shape({
+    source: PropTypes.string,
+    target: PropTypes.string,
+    value: PropTypes.number,
+  })),
+  width: PropTypes.number,
+  height: PropTypes.number,
+  linkLength: PropTypes.number,
+  charge: PropTypes.number,
+};
 
 /* Modified from http://bl.ocks.org/d3noob/5141278 */
-const directedForceVis = function (slice, json) {
-  const div = d3.select(slice.selector);
-  const width = slice.width();
-  const height = slice.height();
-  const fd = slice.formData;
-  const linkLength = fd.link_length || 200;
-  const charge = fd.charge || -500;
-
-  const links = json.data;
+function ForceDirectedGraph(element, props) {
+  PropTypes.checkPropTypes(propTypes, props, 'prop', 'ForceDirectedGraph');
+
+  const {
+    data,
+    width,
+    height,
+    linkLength = 200,
+    charge = -500,
+  } = props;
+  const div = d3.select(element);
+
+  const links = data;
   const nodes = {};
   // Compute the distinct nodes from the links.
   links.forEach(function (link) {
@@ -73,73 +89,73 @@ const directedForceVis = function (slice, json) {
   /* eslint-enable no-use-before-define */
 
   const force = d3.layout.force()
-  .nodes(d3.values(nodes))
-  .links(links)
-  .size([width, height])
-  .linkDistance(linkLength)
-  .charge(charge)
-  .on('tick', tick)
-  .start();
+    .nodes(d3.values(nodes))
+    .links(links)
+    .size([width, height])
+    .linkDistance(linkLength)
+    .charge(charge)
+    .on('tick', tick)
+    .start();
 
   div.selectAll('*').remove();
   const svg = div.append('svg')
-  .attr('width', width)
-  .attr('height', height);
+    .attr('width', width)
+    .attr('height', height);
 
   // build the arrow.
   svg.append('svg:defs').selectAll('marker')
-  .data(['end']) // Different link/path types can be defined here
+    .data(['end']) // Different link/path types can be defined here
   .enter()
   .append('svg:marker') // This section adds in the arrows
-  .attr('id', String)
-  .attr('viewBox', '0 -5 10 10')
-  .attr('refX', 15)
-  .attr('refY', -1.5)
-  .attr('markerWidth', 6)
-  .attr('markerHeight', 6)
-  .attr('orient', 'auto')
+    .attr('id', String)
+    .attr('viewBox', '0 -5 10 10')
+    .attr('refX', 15)
+    .attr('refY', -1.5)
+    .attr('markerWidth', 6)
+    .attr('markerHeight', 6)
+    .attr('orient', 'auto')
   .append('svg:path')
-  .attr('d', 'M0,-5L10,0L0,5');
+    .attr('d', 'M0,-5L10,0L0,5');
 
   const edgeScale = d3.scale.linear()
   .range([0.1, 0.5]);
   // add the links and the arrows
   const path = svg.append('svg:g').selectAll('path')
-  .data(force.links())
+    .data(force.links())
   .enter()
   .append('svg:path')
-  .attr('class', 'link')
-  .style('opacity', function (d) {
-    return edgeScale(d.value / d.target.max);
-  })
-  .attr('marker-end', 'url(#end)');
+    .attr('class', 'link')
+    .style('opacity', function (d) {
+      return edgeScale(d.value / d.target.max);
+    })
+    .attr('marker-end', 'url(#end)');
 
   // define the nodes
   const node = svg.selectAll('.node')
-  .data(force.nodes())
+    .data(force.nodes())
   .enter()
-  .append('g')
-  .attr('class', 'node')
+    .append('g')
+    .attr('class', 'node')
   .on('mouseenter', function () {
     d3.select(this)
-    .select('circle')
-    .transition()
-    .style('stroke-width', 5);
+      .select('circle')
+      .transition()
+      .style('stroke-width', 5);
 
     d3.select(this)
-    .select('text')
-    .transition()
-    .style('font-size', 25);
+      .select('text')
+      .transition()
+      .style('font-size', 25);
   })
   .on('mouseleave', function () {
     d3.select(this)
-    .select('circle')
-    .transition()
-    .style('stroke-width', 1.5);
+      .select('circle')
+      .transition()
+      .style('stroke-width', 1.5);
     d3.select(this)
-    .select('text')
-    .transition()
-    .style('font-size', 12);
+      .select('text')
+      .transition()
+      .style('font-size', 12);
   })
   .call(force.drag);
 
@@ -148,21 +164,33 @@ const directedForceVis = function (slice, json) {
     return Math.sqrt(d.total);
   });
   const circleScale = d3.scale.linear()
-  .domain(ext)
-  .range([3, 30]);
+    .domain(ext)
+    .range([3, 30]);
 
   node.append('circle')
-  .attr('r', function (d) {
-    return circleScale(Math.sqrt(d.total));
-  });
+    .attr('r', function (d) {
+      return circleScale(Math.sqrt(d.total));
+    });
 
   // add the text
   node.append('text')
-  .attr('x', 6)
-  .attr('dy', '.35em')
-  .text(function (d) {
-    return d.name;
+    .attr('x', 6)
+    .attr('dy', '.35em')
+    .text(d => d.name);
+}
+
+function adaptor(slice, payload) {
+  const { selector, formData } = slice;
+  const { link_length: linkLength, charge } = formData;
+  const element = document.querySelector(selector);
+
+  return ForceDirectedGraph(element, {
+    data: payload.data,
+    width: slice.width(),
+    height: slice.height(),
+    linkLength,
+    charge,
   });
-};
+}
 
-module.exports = directedForceVis;
+export default adaptor;


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@superset.apache.org
For additional commands, e-mail: notifications-help@superset.apache.org