mirror of
https://github.com/apache/superset.git
synced 2024-09-12 00:29:39 -04:00
[SIP-5] Refactor sankey (#5701)
* extract slice and formdata from sankey * use arrow function * reorganize imports
This commit is contained in:
parent
fcf2c756c0
commit
506cfd1450
@ -1,28 +1,47 @@
|
|||||||
/* eslint-disable no-param-reassign */
|
/* eslint-disable no-param-reassign */
|
||||||
import d3 from 'd3';
|
import d3 from 'd3';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { sankey as d3Sankey } from 'd3-sankey';
|
||||||
import { getColorFromScheme } from '../modules/colors';
|
import { getColorFromScheme } from '../modules/colors';
|
||||||
import './sankey.css';
|
import './sankey.css';
|
||||||
|
|
||||||
d3.sankey = require('d3-sankey').sankey;
|
const propTypes = {
|
||||||
|
data: PropTypes.arrayOf(PropTypes.shape({
|
||||||
|
source: PropTypes.string,
|
||||||
|
target: PropTypes.string,
|
||||||
|
value: PropTypes.number,
|
||||||
|
})),
|
||||||
|
width: PropTypes.number,
|
||||||
|
height: PropTypes.number,
|
||||||
|
colorScheme: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatNumber = d3.format(',.2f');
|
||||||
|
|
||||||
function sankeyVis(slice, payload) {
|
function Sankey(element, props) {
|
||||||
const div = d3.select(slice.selector);
|
PropTypes.checkPropTypes(propTypes, props, 'prop', 'Sankey');
|
||||||
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
colorScheme,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const div = d3.select(element);
|
||||||
const margin = {
|
const margin = {
|
||||||
top: 5,
|
top: 5,
|
||||||
right: 5,
|
right: 5,
|
||||||
bottom: 5,
|
bottom: 5,
|
||||||
left: 5,
|
left: 5,
|
||||||
};
|
};
|
||||||
const width = slice.width() - margin.left - margin.right;
|
const innerWidth = width - margin.left - margin.right;
|
||||||
const height = slice.height() - margin.top - margin.bottom;
|
const innerHeight = height - margin.top - margin.bottom;
|
||||||
|
|
||||||
const formatNumber = d3.format(',.2f');
|
|
||||||
|
|
||||||
div.selectAll('*').remove();
|
div.selectAll('*').remove();
|
||||||
const svg = div.append('svg')
|
const svg = div.append('svg')
|
||||||
.attr('width', width + margin.left + margin.right)
|
.attr('width', innerWidth + margin.left + margin.right)
|
||||||
.attr('height', height + margin.top + margin.bottom)
|
.attr('height', innerHeight + margin.top + margin.bottom)
|
||||||
.append('g')
|
.append('g')
|
||||||
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
|
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
|
||||||
|
|
||||||
@ -30,16 +49,16 @@ function sankeyVis(slice, payload) {
|
|||||||
.attr('class', 'sankey-tooltip')
|
.attr('class', 'sankey-tooltip')
|
||||||
.style('opacity', 0);
|
.style('opacity', 0);
|
||||||
|
|
||||||
const sankey = d3.sankey()
|
const sankey = d3Sankey()
|
||||||
.nodeWidth(15)
|
.nodeWidth(15)
|
||||||
.nodePadding(10)
|
.nodePadding(10)
|
||||||
.size([width, height]);
|
.size([innerWidth, innerHeight]);
|
||||||
|
|
||||||
const path = sankey.link();
|
const path = sankey.link();
|
||||||
|
|
||||||
let nodes = {};
|
let nodes = {};
|
||||||
// Compute the distinct nodes from the links.
|
// Compute the distinct nodes from the links.
|
||||||
const links = payload.data.map(function (row) {
|
const links = data.map(function (row) {
|
||||||
const link = Object.assign({}, row);
|
const link = Object.assign({}, row);
|
||||||
link.source = nodes[link.source] || (nodes[link.source] = { name: link.source });
|
link.source = nodes[link.source] || (nodes[link.source] = { name: link.source });
|
||||||
link.target = nodes[link.target] || (nodes[link.target] = { name: link.target });
|
link.target = nodes[link.target] || (nodes[link.target] = { name: link.target });
|
||||||
@ -120,13 +139,9 @@ function sankeyVis(slice, payload) {
|
|||||||
.enter()
|
.enter()
|
||||||
.append('g')
|
.append('g')
|
||||||
.attr('class', 'node')
|
.attr('class', 'node')
|
||||||
.attr('transform', function (d) {
|
.attr('transform', d => 'translate(' + d.x + ',' + d.y + ')')
|
||||||
return 'translate(' + d.x + ',' + d.y + ')';
|
|
||||||
})
|
|
||||||
.call(d3.behavior.drag()
|
.call(d3.behavior.drag()
|
||||||
.origin(function (d) {
|
.origin(d => d)
|
||||||
return d;
|
|
||||||
})
|
|
||||||
.on('dragstart', function () {
|
.on('dragstart', function () {
|
||||||
this.parentNode.appendChild(this);
|
this.parentNode.appendChild(this);
|
||||||
})
|
})
|
||||||
@ -138,31 +153,38 @@ function sankeyVis(slice, payload) {
|
|||||||
.attr('width', sankey.nodeWidth())
|
.attr('width', sankey.nodeWidth())
|
||||||
.style('fill', function (d) {
|
.style('fill', function (d) {
|
||||||
const name = d.name || 'N/A';
|
const name = d.name || 'N/A';
|
||||||
d.color = getColorFromScheme(name.replace(/ .*/, ''), slice.formData.color_scheme);
|
d.color = getColorFromScheme(name.replace(/ .*/, ''), colorScheme);
|
||||||
return d.color;
|
return d.color;
|
||||||
})
|
})
|
||||||
.style('stroke', function (d) {
|
.style('stroke', d => d3.rgb(d.color).darker(2))
|
||||||
return d3.rgb(d.color).darker(2);
|
|
||||||
})
|
|
||||||
.on('mouseover', onmouseover)
|
.on('mouseover', onmouseover)
|
||||||
.on('mouseout', onmouseout);
|
.on('mouseout', onmouseout);
|
||||||
|
|
||||||
node.append('text')
|
node.append('text')
|
||||||
.attr('x', -6)
|
.attr('x', -6)
|
||||||
.attr('y', function (d) {
|
.attr('y', d => d.dy / 2)
|
||||||
return d.dy / 2;
|
|
||||||
})
|
|
||||||
.attr('dy', '.35em')
|
.attr('dy', '.35em')
|
||||||
.attr('text-anchor', 'end')
|
.attr('text-anchor', 'end')
|
||||||
.attr('transform', null)
|
.attr('transform', null)
|
||||||
.text(function (d) {
|
.text(d => d.name)
|
||||||
return d.name;
|
.filter(d => d.x < innerWidth / 2)
|
||||||
})
|
|
||||||
.filter(function (d) {
|
|
||||||
return d.x < width / 2;
|
|
||||||
})
|
|
||||||
.attr('x', 6 + sankey.nodeWidth())
|
.attr('x', 6 + sankey.nodeWidth())
|
||||||
.attr('text-anchor', 'start');
|
.attr('text-anchor', 'start');
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = sankeyVis;
|
Sankey.propTypes = propTypes;
|
||||||
|
|
||||||
|
function adaptor(slice, payload) {
|
||||||
|
const { selector, formData } = slice;
|
||||||
|
const { color_scheme: colorScheme } = formData;
|
||||||
|
const element = document.querySelector(selector);
|
||||||
|
|
||||||
|
return Sankey(element, {
|
||||||
|
data: payload.data,
|
||||||
|
width: slice.width(),
|
||||||
|
height: slice.height(),
|
||||||
|
colorScheme,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default adaptor;
|
||||||
|
Loading…
Reference in New Issue
Block a user