You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ma...@apache.org on 2018/08/21 00:00:29 UTC

[incubator-superset] branch master updated: Refactor Chord vis (#5671)

This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 683edc3  Refactor Chord vis (#5671)
683edc3 is described below

commit 683edc377ec80a88c65bdede3e22bd1c7cf917ec
Author: Krist Wongsuphasawat <kr...@gmail.com>
AuthorDate: Mon Aug 20 17:00:25 2018 -0700

    Refactor Chord vis (#5671)
    
    * refactor Chord vis
    
    * Add PropTypes
    
    * change module.exports to export default
---
 superset/assets/src/visualizations/chord.jsx | 126 +++++++++++++++++----------
 1 file changed, 80 insertions(+), 46 deletions(-)

diff --git a/superset/assets/src/visualizations/chord.jsx b/superset/assets/src/visualizations/chord.jsx
index 54b5261..2a7cdf1 100644
--- a/superset/assets/src/visualizations/chord.jsx
+++ b/superset/assets/src/visualizations/chord.jsx
@@ -1,18 +1,36 @@
 /* eslint-disable no-param-reassign */
 import d3 from 'd3';
+import PropTypes from 'prop-types';
 import { getColorFromScheme } from '../modules/colors';
 import './chord.css';
 
-function chordViz(slice, json) {
-  slice.container.html('');
-
-  const div = d3.select(slice.selector);
-  const nodes = json.data.nodes;
-  const fd = slice.formData;
-  const f = d3.format(fd.y_axis_format);
-
-  const width = slice.width();
-  const height = slice.height();
+const propTypes = {
+  data: PropTypes.shape({
+    nodes: PropTypes.arrayOf(PropTypes.string),
+    matrix: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.number)),
+  }),
+  width: PropTypes.number,
+  height: PropTypes.number,
+  numberFormat: PropTypes.string,
+  colorScheme: PropTypes.string,
+};
+
+function chordVis(element, props) {
+  PropTypes.checkPropTypes(propTypes, props, 'prop', 'ChordVis');
+
+  const {
+    data,
+    width,
+    height,
+    numberFormat,
+    colorScheme,
+  } = props;
+
+  element.innerHTML = '';
+
+  const div = d3.select(element);
+  const { nodes, matrix } = data;
+  const f = d3.format(numberFormat);
 
   const outerRadius = Math.min(width, height) / 2 - 10;
   const innerRadius = outerRadius - 24;
@@ -20,56 +38,56 @@ function chordViz(slice, json) {
   let chord;
 
   const arc = d3.svg.arc()
-  .innerRadius(innerRadius)
-  .outerRadius(outerRadius);
+    .innerRadius(innerRadius)
+    .outerRadius(outerRadius);
 
   const layout = d3.layout.chord()
-  .padding(0.04)
-  .sortSubgroups(d3.descending)
-  .sortChords(d3.descending);
+    .padding(0.04)
+    .sortSubgroups(d3.descending)
+    .sortChords(d3.descending);
 
   const path = d3.svg.chord()
-  .radius(innerRadius);
+    .radius(innerRadius);
 
   const svg = div.append('svg')
-  .attr('width', width)
-  .attr('height', height)
-  .on('mouseout', () => chord.classed('fade', false))
-  .append('g')
-  .attr('id', 'circle')
-  .attr('transform', `translate(${width / 2}, ${height / 2})`);
+    .attr('width', width)
+    .attr('height', height)
+    .on('mouseout', () => chord.classed('fade', false))
+    .append('g')
+    .attr('id', 'circle')
+    .attr('transform', `translate(${width / 2}, ${height / 2})`);
 
   svg.append('circle')
-  .attr('r', outerRadius);
+    .attr('r', outerRadius);
 
   // Compute the chord layout.
-  layout.matrix(json.data.matrix);
+  layout.matrix(matrix);
 
   const group = svg.selectAll('.group')
-  .data(layout.groups)
-  .enter().append('g')
-  .attr('class', 'group')
-  .on('mouseover', (d, i) => {
-    chord.classed('fade', p => p.source.index !== i && p.target.index !== i);
-  });
+    .data(layout.groups)
+    .enter().append('g')
+    .attr('class', 'group')
+    .on('mouseover', (d, i) => {
+      chord.classed('fade', p => p.source.index !== i && p.target.index !== i);
+    });
 
   // Add a mouseover title.
   group.append('title').text((d, i) => `${nodes[i]}: ${f(d.value)}`);
 
   // Add the group arc.
   const groupPath = group.append('path')
-  .attr('id', (d, i) => 'group' + i)
-  .attr('d', arc)
-  .style('fill', (d, i) => getColorFromScheme(nodes[i], slice.formData.color_scheme));
+    .attr('id', (d, i) => 'group' + i)
+    .attr('d', arc)
+    .style('fill', (d, i) => getColorFromScheme(nodes[i], colorScheme));
 
   // Add a text label.
   const groupText = group.append('text')
-  .attr('x', 6)
-  .attr('dy', 15);
+    .attr('x', 6)
+    .attr('dy', 15);
 
   groupText.append('textPath')
-  .attr('xlink:href', (d, i) => `#group${i}`)
-  .text((d, i) => nodes[i]);
+    .attr('xlink:href', (d, i) => `#group${i}`)
+    .text((d, i) => nodes[i]);
   // Remove the labels that don't fit. :(
   groupText.filter(function (d, i) {
     return groupPath[0][i].getTotalLength() / 2 - 16 < this.getComputedTextLength();
@@ -78,14 +96,14 @@ function chordViz(slice, json) {
 
   // Add the chords.
   chord = svg.selectAll('.chord')
-  .data(layout.chords)
-  .enter().append('path')
-  .attr('class', 'chord')
-  .on('mouseover', (d) => {
-    chord.classed('fade', p => p !== d);
-  })
-  .style('fill', d => getColorFromScheme(nodes[d.source.index], slice.formData.color_scheme))
-  .attr('d', path);
+    .data(layout.chords)
+    .enter().append('path')
+    .attr('class', 'chord')
+    .on('mouseover', (d) => {
+      chord.classed('fade', p => p !== d);
+    })
+    .style('fill', d => getColorFromScheme(nodes[d.source.index], colorScheme))
+    .attr('d', path);
 
   // Add an elaborate mouseover title for each chord.
   chord.append('title').text(function (d) {
@@ -98,4 +116,20 @@ function chordViz(slice, json) {
   });
 }
 
-module.exports = chordViz;
+chordVis.propTypes = propTypes;
+
+function adaptor(slice, payload) {
+  const { selector, formData } = slice;
+  const { y_axis_format: numberFormat, color_scheme: colorScheme } = formData;
+  const element = document.querySelector(selector);
+
+  return chordVis(element, {
+    data: payload.data,
+    width: slice.width(),
+    height: slice.height(),
+    numberFormat,
+    colorScheme,
+  });
+}
+
+export default adaptor;