Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[KED-1638] Update colour scheme, improve print/export styles #169

Merged
merged 17 commits into from
May 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/export-modal/export-graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const exportGraph = ({ format, theme, graphSize, mockFn }) => {
// Create clone of graph SVG to avoid breaking the original
const svg = document.querySelector('#pipeline-graph');
const clone = svg.parentNode.appendChild(svg.cloneNode(true));
clone.classList.add('kedro', `kui-theme--${theme}`);
clone.classList.add('kedro', `kui-theme--${theme}`, 'pipeline-graph--export');

// Reset zoom/translate
let width = graphSize.width + graphSize.marginx * 2;
Expand Down
42 changes: 22 additions & 20 deletions src/components/flowchart/draw.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ const drawLayers = function() {
const { layers, visibleLayers } = this.props;

this.el.layers = this.el.layerGroup
.selectAll('.layer')
.selectAll('.pipeline-layer')
.data(visibleLayers ? layers : [], layer => layer.id);

const enterLayers = this.el.layers
.enter()
.append('rect')
.attr('class', 'layer');
.attr('class', 'pipeline-layer');

this.el.layers.exit().remove();

Expand Down Expand Up @@ -46,13 +46,13 @@ const drawLayerNames = function() {
.style('transform', `translateX(${sidebarWidth}px)`);

this.el.layerNames = this.el.layerNameGroup
.selectAll('.layer-name')
.selectAll('.pipeline-layer-name')
.data(visibleLayers ? layers : [], layer => layer.id);

const enterLayerNames = this.el.layerNames
.enter()
.append('li')
.attr('class', 'layer-name')
.attr('class', 'pipeline-layer-name')
.style('opacity', 0)
.transition('enter-layer-names')
.duration(this.DURATION)
Expand Down Expand Up @@ -85,14 +85,14 @@ const drawNodes = function() {
} = this.props;

this.el.nodes = this.el.nodeGroup
.selectAll('.node')
.selectAll('.pipeline-node')
.data(nodes, node => node.id);

const enterNodes = this.el.nodes
.enter()
.append('g')
.attr('tabindex', '0')
.attr('class', 'node');
.attr('class', 'pipeline-node');

enterNodes
.attr('transform', node => `translate(${node.x}, ${node.y})`)
Expand All @@ -119,15 +119,17 @@ const drawNodes = function() {
this.el.nodes = this.el.nodes
.merge(enterNodes)
.attr('data-id', node => node.id)
.classed('node--parameters', node => node.type === 'parameters')
.classed('node--data', node => node.type === 'data')
.classed('node--task', node => node.type === 'task')
.classed('node--icon', !textLabels)
.classed('node--text', textLabels)
.classed('node--active', node => nodeActive[node.id])
.classed('node--selected', node => nodeSelected[node.id])
.classed('node--highlight', node => centralNode && linkedNodes[node.id])
.classed('node--faded', node => centralNode && !linkedNodes[node.id])
.classed('pipeline-node--parameters', node => node.type === 'parameters')
.classed('pipeline-node--data', node => node.type === 'data')
.classed('pipeline-node--task', node => node.type === 'task')
.classed('pipeline-node--icon', !textLabels)
.classed('pipeline-node--text', textLabels)
.classed('pipeline-node--active', node => nodeActive[node.id])
.classed('pipeline-node--selected', node => nodeSelected[node.id])
.classed(
'pipeline-node--faded',
node => centralNode && !linkedNodes[node.id]
)
.on('click', this.handleNodeClick)
.on('mouseover', this.handleNodeMouseOver)
.on('mouseout', this.handleNodeMouseOut)
Expand Down Expand Up @@ -156,7 +158,7 @@ const drawNodes = function() {
.attr('rx', node => (node.type === 'task' ? 0 : node.height / 2));

this.el.nodes
.select('.node__icon')
.select('.pipeline-node__icon')
.transition('node-icon-offset')
.duration(150)
.attr('width', node => node.iconSize)
Expand All @@ -172,7 +174,7 @@ const drawEdges = function() {
const { edges, centralNode, linkedNodes } = this.props;

this.el.edges = this.el.edgeGroup
.selectAll('.edge')
.selectAll('.pipeline-edge')
.data(edges, edge => edge.id);

// Set up line shape function
Expand All @@ -185,10 +187,10 @@ const drawEdges = function() {
const enterEdges = this.el.edges
.enter()
.append('g')
.attr('class', 'edge')
.attr('class', 'pipeline-edge')
.attr('opacity', 0);

enterEdges.append('path').attr('marker-end', d => `url(#arrowhead)`);
enterEdges.append('path').attr('marker-end', d => `url(#pipeline-arrowhead)`);

this.el.edges
.exit()
Expand All @@ -202,7 +204,7 @@ const drawEdges = function() {
this.el.edges
.attr('data-id', edge => edge.id)
.classed(
'edge--faded',
'pipeline-edge--faded',
({ source, target }) =>
centralNode && (!linkedNodes[source] || !linkedNodes[target])
)
Expand Down
2 changes: 1 addition & 1 deletion src/components/flowchart/flowchart.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ describe('FlowChart', () => {

it('renders nodes with D3', () => {
const wrapper = setup.mount(<FlowChart />);
const nodes = wrapper.render().find('.node');
const nodes = wrapper.render().find('.pipeline-node');
const nodeNames = nodes.map((i, el) => $(el).text()).get();
const mockNodes = getNodeIDs(mockState.lorem);
const mockNodeNames = mockNodes.map(d => getNodeName(mockState.lorem)[d]);
Expand Down
2 changes: 1 addition & 1 deletion src/components/flowchart/icon.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default node => {
const svgNode = document.createElementNS('http://www.w3.org/2000/svg', 'svg');

const svg = select(svgNode)
.attr('class', 'node__icon')
.attr('class', 'pipeline-node__icon')
.attr('viewBox', '0 0 24 24');

paths[node.type].forEach(path => {
Expand Down
48 changes: 38 additions & 10 deletions src/components/flowchart/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { Component } from 'react';
import { connect } from 'react-redux';
import classnames from 'classnames';
import 'd3-transition';
import { select, event } from 'd3-selection';
import { zoom, zoomIdentity } from 'd3-zoom';
Expand Down Expand Up @@ -47,11 +48,11 @@ export class FlowChart extends Component {
this.initZoomBehaviour();
this.drawChart();
this.zoomChart();
this.addResizeObserver();
this.addGlobalEventListeners();
}

componentWillUnmount() {
this.removeResizeObserver();
this.removeGlobalEventListeners();
}

componentDidUpdate(prevProps) {
Expand Down Expand Up @@ -89,10 +90,11 @@ export class FlowChart extends Component {
}

/**
* Add ResizeObserver to listen for any changes in the container's width/height
* (with event listener fallback)
* Add window event listeners on mount
*/
addResizeObserver() {
addGlobalEventListeners() {
// Add ResizeObserver to listen for any changes in the container's width/height
// (with event listener fallback)
if (window.ResizeObserver) {
this.resizeObserver =
this.resizeObserver ||
Expand All @@ -101,17 +103,24 @@ export class FlowChart extends Component {
} else {
window.addEventListener('resize', this.handleWindowResize);
}
// Print event listeners
window.addEventListener('beforeprint', this.handleBeforePrint);
window.addEventListener('afterprint', this.handleAfterPrint);
}

/**
* Remove ResizeObserver (or event listener fallback) on unmount
* Remove window event listeners on unmount
*/
removeResizeObserver() {
removeGlobalEventListeners() {
// ResizeObserver
if (window.ResizeObserver) {
this.resizeObserver.unobserve(this.containerRef.current);
} else {
window.removeEventListener('resize', this.handleWindowResize);
}
// Print event listeners
window.removeEventListener('beforeprint', this.handleBeforePrint);
window.removeEventListener('afterprint', this.handleAfterPrint);
}

/**
Expand All @@ -121,6 +130,23 @@ export class FlowChart extends Component {
this.updateChartSize();
};

/**
* Add viewBox on window print so that the SVG can be scaled to fit
*/
handleBeforePrint = () => {
const gs = this.props.graphSize;
const width = gs.width + gs.marginx * 2;
const height = gs.height + gs.marginy * 2;
this.el.svg.attr('viewBox', `0 0 ${width} ${height}`);
};

/**
* Remove viewBox once printing is done
*/
handleAfterPrint = () => {
this.el.svg.attr('viewBox', null);
};

/**
* Setup D3 zoom behaviour on component mount
*/
Expand Down Expand Up @@ -264,7 +290,7 @@ export class FlowChart extends Component {
* Render React elements
*/
render() {
const { chartSize } = this.props;
const { chartSize, visibleLayers } = this.props;
const { outerWidth = 0, outerHeight = 0 } = chartSize;

return (
Expand All @@ -280,7 +306,7 @@ export class FlowChart extends Component {
ref={this.svgRef}>
<defs>
<marker
id="arrowhead"
id="pipeline-arrowhead"
className="pipeline-flowchart__arrowhead"
viewBox="0 0 10 10"
refX="7"
Expand All @@ -303,7 +329,9 @@ export class FlowChart extends Component {
</g>
</svg>
<ul
className="pipeline-flowchart__layer-names"
className={classnames('pipeline-flowchart__layer-names', {
'pipeline-flowchart__layer-names--visible': visibleLayers
})}
ref={this.layerNamesRef}
/>
<Tooltip chartSize={chartSize} {...this.state.tooltip} />
Expand Down
24 changes: 20 additions & 4 deletions src/components/flowchart/styles/_edges.scss
Original file line number Diff line number Diff line change
@@ -1,29 +1,45 @@
@import './variables';

.edge path {
.pipeline-edge path {
pointer-events: none;
fill: none;
stroke-width: 1.5px;

.kui-theme--light & {
stroke: $edge-light;

@media print {
stroke: $edge-light-export;
}
}

.pipeline-graph--export.kui-theme--light & {
stroke: $edge-light-export;
}

.kui-theme--dark & {
stroke: $edge-dark;
}
}

.edge--faded {
.pipeline-edge--faded {
opacity: 0.1;
}

.pipeline-flowchart__arrowhead {
.kui-theme--light & {
fill: $edge-light;
fill: $edge-arrowhead-light;

@media print {
fill: $edge-light-export;
}
}

.pipeline-graph--export.kui-theme--light & {
fill: $edge-light-export;
}

.kui-theme--dark & {
fill: $edge-dark;
fill: $edge-arrowhead-dark;
}
}
38 changes: 32 additions & 6 deletions src/components/flowchart/styles/_layers.scss
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
@import './variables';

.layer {
.pipeline-layer {
opacity: 0;
transition: opacity ease 0.5s;

.kui-theme--dark & {
fill: rgba(white, 0.05);
fill: $layer-dark;
}

.kui-theme--light & {
fill: rgba(black, 0.05);
fill: $layer-light;
}

&:hover {
opacity: 1;
}

.pipeline-graph--export & {
display: none;
}

@media print {
display: none;
}
}

.pipeline-flowchart__layer-names {
Expand All @@ -26,18 +34,36 @@
margin: 0;
padding: 0;
list-style: none;
opacity: 0;
transition: opacity ease 0.7s;
pointer-events: none;

&--visible {
opacity: 1;
}

.kui-theme--dark & {
background: linear-gradient(to right, $color-bg-dark, transparent);
background: linear-gradient(
to right,
$color-bg-dark-1,
rgba($color-bg-dark-1, 0)
);
}

.kui-theme--light & {
background: linear-gradient(to right, $color-bg-light, transparent);
background: linear-gradient(
to right,
$color-bg-light-1,
rgba($color-bg-light-1, 0)
);
}

@media print {
display: none;
}
}

.layer-name {
.pipeline-layer-name {
position: absolute;
top: -10px;
display: flex;
Expand Down
Loading