Remove a lot of un-used code that I still want to keep

This commit is contained in:
Simon Howe
2016-07-28 09:20:12 +02:00
parent 29e67683b3
commit f83e0f1a48
9 changed files with 44 additions and 314 deletions

View File

@@ -12,7 +12,8 @@ import { DETAILS_PANEL_WIDTH } from '../constants/styles';
import Logo from '../components/logo';
import { doLayout } from './nodes-layout';
import NodesChartElements from './nodes-chart-elements';
import { getActiveTopologyOptions, getAdjacentNodes } from '../utils/topology-utils';
import { getActiveTopologyOptions, getAdjacentNodes,
isSameTopology } from '../utils/topology-utils';
const log = debug('scope:nodes-chart');
@@ -40,8 +41,8 @@ class NodesChart extends React.Component {
scale: 1,
selectedNodeScale: d3.scale.linear(),
hasZoomed: false,
height: props.height || 0,
width: props.width || 0,
height: 0,
width: 0,
zoomCache: {}
};
}
@@ -60,7 +61,7 @@ class NodesChart extends React.Component {
// re-apply cached canvas zoom/pan to d3 behavior (or set defaul values)
const defaultZoom = { scale: 1, panTranslateX: 0, panTranslateY: 0, hasZoomed: false };
const nextZoom = this.state.zoomCache[nextProps.topologyId] || defaultZoom;
if (this.zoom && nextZoom) {
if (nextZoom) {
this.zoom.scale(nextZoom.scale);
this.zoom.translate([nextZoom.panTranslateX, nextZoom.panTranslateY]);
}
@@ -78,13 +79,11 @@ class NodesChart extends React.Component {
}
// reset layout dimensions only when forced
// state.height = nextProps.height;
// state.width = nextProps.width;
state.height = nextProps.forceRelayout ? nextProps.height : (state.height || nextProps.height);
state.width = nextProps.forceRelayout ? nextProps.width : (state.width || nextProps.width);
// _.assign(state, this.updateGraphState(nextProps, state));
if (nextProps.forceRelayout || nextProps.nodes !== this.props.nodes) {
if (nextProps.forceRelayout || !isSameTopology(nextProps.nodes, this.props.nodes)) {
_.assign(state, this.updateGraphState(nextProps, state));
}
@@ -100,10 +99,6 @@ class NodesChart extends React.Component {
componentDidMount() {
// distinguish pan/zoom from click
if (this.props.noZoom) {
return;
}
this.isZooming = false;
this.zoom = d3.behavior.zoom()
@@ -115,10 +110,6 @@ class NodesChart extends React.Component {
}
componentWillUnmount() {
if (this.props.noZoom) {
return;
}
// undoing .call(zoom)
d3.select('.nodes-chart svg')
.on('mousedown.zoom', null)
@@ -294,10 +285,8 @@ class NodesChart extends React.Component {
restoreLayout(state) {
// undo any pan/zooming that might have happened
if (this.zoom) {
this.zoom.scale(state.scale);
this.zoom.translate([state.panTranslateX, state.panTranslateY]);
}
this.zoom.scale(state.scale);
this.zoom.translate([state.panTranslateX, state.panTranslateY]);
const nodes = state.nodes.map(node => node.merge({
x: node.get('px'),
@@ -326,10 +315,6 @@ class NodesChart extends React.Component {
const stateEdges = this.initEdges(props.nodes, stateNodes);
const nodeScale = this.getNodeScale(props.nodes, state.width, state.height);
const nextState = { nodeScale };
const nodeOrder = props.nodeOrder || makeMap(stateNodes
.toList()
.sortBy(n => n.get('label'))
.map((n, i) => [n.get('id'), i]));
const options = {
width: state.width,
@@ -338,8 +323,7 @@ class NodesChart extends React.Component {
margins: props.margins,
forceRelayout: props.forceRelayout,
topologyId: this.props.topologyId,
topologyOptions: this.props.topologyOptions,
nodeOrder
topologyOptions: this.props.topologyOptions
};
const timedLayouter = timely(doLayout);
@@ -366,12 +350,10 @@ class NodesChart extends React.Component {
const zoomFactor = Math.min(xFactor, yFactor);
let zoomScale = this.state.scale;
if (!this.props.noZoom && !state.hasZoomed && zoomFactor > 0 && zoomFactor < 1) {
if (!state.hasZoomed && zoomFactor > 0 && zoomFactor < 1) {
zoomScale = zoomFactor;
// saving in d3's behavior cache
if (this.zoom) {
this.zoom.scale(zoomFactor);
}
this.zoom.scale(zoomFactor);
}
nextState.scale = zoomScale;
@@ -390,7 +372,7 @@ class NodesChart extends React.Component {
const nodeSize = expanse / 3; // single node should fill a third of the screen
const maxNodeSize = expanse / 10;
const normalizedNodeSize = Math.min(nodeSize / Math.sqrt(nodes.size), maxNodeSize);
return this.state.nodeScale.copy().range([0, this.props.nodeSize || normalizedNodeSize]);
return this.state.nodeScale.copy().range([0, normalizedNodeSize]);
}
zoomed() {

View File

@@ -54,20 +54,19 @@ function getColumns(nodes) {
function renderIdCell(props) {
const style = {
const iconStyle = {
width: 16,
flex: 'none',
color: getNodeColor(props.rank, props.label_major)
};
const showSubLabel = Boolean(props.pseudo);
return (
<div className="nodes-grid-id-column">
<div className="content">
<div style={style}><i className="fa fa-square" /></div>
<div className="truncate">
{props.label} {props.pseudo &&
<span className="nodes-grid-label-minor">{props.label_minor}</span>}
</div>
<div style={iconStyle}><i className="fa fa-square" /></div>
<div className="truncate">
{props.label} {showSubLabel &&
<span className="nodes-grid-label-minor">{props.label_minor}</span>}
</div>
</div>
);
@@ -79,33 +78,18 @@ class NodesGrid extends React.Component {
constructor(props, context) {
super(props, context);
this.renderIdCell = this.renderIdCell.bind(this);
this.clickRow = this.clickRow.bind(this);
this.onClickRow = this.onClickRow.bind(this);
this.onSortChange = this.onSortChange.bind(this);
this.onMouseEnterRow = this.onMouseEnterRow.bind(this);
this.onMouseLeaveRow = this.onMouseLeaveRow.bind(this);
}
clickRow(ev, node, el) {
onClickRow(ev, node, el) {
// TODO: do this better
if (ev.target.className === 'node-details-table-node-link') {
return;
}
this.props.clickNode(node.id, node.label, el.getBoundingClientRect());
}
renderIdCell(props) {
return renderIdCell(props);
}
onMouseEnterRow() {
this.props.clickPauseUpdate();
}
onMouseLeaveRow() {
this.props.clickResumeUpdate();
}
onSortChange(sortBy, sortedDesc) {
this.props.sortOrderChanged(sortBy, sortedDesc);
}
@@ -140,16 +124,17 @@ class NodesGrid extends React.Component {
<NodeDetailsTable
style={cmpStyle}
className={className}
renderIdCell={this.renderIdCell}
renderIdCell={renderIdCell}
tbodyStyle={tbodyStyle}
topologyId={this.props.topologyId}
onSortChange={this.onSortChange}
onClickRow={this.clickRow}
{...detailsData}
onClickRow={this.onClickRow}
sortBy={gridSortBy}
sortedDesc={gridSortedDesc}
selectedNodeId={this.props.selectedNodeId}
limit={1000} />
limit={1000}
{...detailsData}
/>
</div>
);
}

View File

@@ -1,6 +1,5 @@
import dagre from 'dagre';
import debug from 'debug';
import d3 from 'd3';
import { fromJS, Map as makeMap, Set as ImmSet } from 'immutable';
import { EDGE_ID_SEPARATOR } from '../constants/naming';
@@ -50,9 +49,7 @@ function runLayoutEngine(graph, imNodes, imEdges, opts) {
// configure node margins
graph.setGraph({
nodesep,
ranksep,
// rankdir: 'LR',
// align: 'UL'
ranksep
});
// add nodes to the graph if not already there
@@ -179,17 +176,18 @@ function layoutSingleNodes(layout, opts) {
offsetY = offsetY || margins.top + nodeHeight / 2;
const columns = Math.ceil(Math.sqrt(singleNodes.size));
const rows = Math.ceil(singleNodes.size / columns);
let row = 0;
let col = 0;
let singleX;
let singleY;
nodes = nodes.sortBy(node => node.get('rank')).map(node => {
if (singleNodes.has(node.get('id'))) {
if (col === columns) {
col = 0;
row++;
}
const singleX = col * (nodesep + nodeWidth) + offsetX;
const singleY = row * (ranksep + nodeHeight) + offsetY;
singleX = col * (nodesep + nodeWidth) + offsetX;
singleY = row * (ranksep + nodeHeight) + offsetY;
col++;
return node.merge({
x: singleX,
@@ -200,8 +198,8 @@ function layoutSingleNodes(layout, opts) {
});
// adjust layout dimensions if graph is now bigger
result.width = Math.max(layout.width, columns * nodeWidth + (columns - 1) * nodesep);
result.height = Math.max(layout.height, rows * nodeHeight + (rows - 1) * ranksep);
result.width = Math.max(layout.width, singleX + nodeWidth / 2 + nodesep);
result.height = Math.max(layout.height, singleY + nodeHeight / 2 + ranksep);
result.nodes = nodes;
}
@@ -246,7 +244,6 @@ function shiftLayoutToCenter(layout, opts) {
return result;
}
/**
* Adds `points` array to edge based on location of source and target
* @param {Map} edge new edge
@@ -262,39 +259,6 @@ function setSimpleEdgePoints(edge, nodeCache) {
]));
}
export function uniqueRowConstraint(layout, options) {
const result = Object.assign({}, layout);
const scale = options.scale || DEFAULT_SCALE;
const nodeHeight = scale(NODE_SIZE_FACTOR);
const nodeWidth = scale(NODE_SIZE_FACTOR);
const margins = options.margins || DEFAULT_MARGINS;
const rowHeight = options.height / layout.nodes.size;
const nodeOrder = options.nodeOrder || makeMap(layout.nodes
.toList()
.sortBy(n => n.get('y'))
.map((n, i) => [n.get('id'), i]));
const nodeXs = layout.nodes.map(n => n.get('x')).toList().toJS();
const xScale = d3.scale.linear()
.domain(d3.extent(nodeXs))
.range([nodeWidth, options.width - nodeWidth])
.clamp(false);
result.nodes = layout.nodes.map(node => node.merge({
x: xScale(node.get('x')),
y: nodeOrder.get(node.get('id')) * rowHeight + nodeHeight * 0.5 + margins.top + 2
}));
result.edges = layout.edges.map(edge => (
setSimpleEdgePoints(edge, result.nodes)
));
return result;
}
/**
* Determine if nodes were added between node sets
* @param {Map} nodes new Map of nodes
@@ -391,7 +355,6 @@ export function doLayout(immNodes, immEdges, opts) {
let layout;
++layoutRuns;
// if (false && !options.forceRelayout && cachedLayout && nodeCache && edgeCache
if (!options.forceRelayout && cachedLayout && nodeCache && edgeCache
&& !hasUnseenNodes(immNodes, nodeCache)) {
log('skip layout, trivial adjustment', ++layoutRunsTrivial, layoutRuns);
@@ -407,7 +370,6 @@ export function doLayout(immNodes, immEdges, opts) {
}
layout = layoutSingleNodes(layout, opts);
layout = shiftLayoutToCenter(layout, opts);
// layout = uniqueRowConstraint(layout, opts);
}
// cache results

View File

@@ -184,7 +184,7 @@ class DebugToolbar extends React.Component {
addNodes(n, prefix = 'zing') {
const ns = this.props.nodes;
const nodeNames = ns.keySeq().toJS();
const newNodeNames = _.range(nodeNames.length, nodeNames.length + n).map(i => (
const newNodeNames = _.range(ns.size, ns.size + n).map(i => (
// `${randomLetter()}${randomLetter()}-zing`
`${prefix}${i}`
));

View File

@@ -1,150 +0,0 @@
/* eslint no-unused-vars: "off" */
import React from 'react';
import _ from 'lodash';
import NodesChart from '../charts/nodes-chart';
import NodesGrid from '../charts/nodes-grid';
import { deltaAdd, makeNodes } from './debug-toolbar';
import { fromJS, Map as makeMap, Set as makeSet } from 'immutable';
function clog(v) {
console.log(v);
return v;
}
function randomGraph(n) {
return makeMap(makeNodes(n, 'ewq', 4, 'hexagon').map(d => [d.id, fromJS(d)]));
}
function deltaAddSimple(name, adjacency = []) {
return deltaAdd(name, adjacency, 'circle', false, 1, '');
}
function makeIds(n) {
return _.range(n).map(i => `n${i}`);
}
function disconnectedGraph(n) {
return makeMap(makeIds(n)
.map((id) => deltaAddSimple(id))
.map(d => [d.id, fromJS(d)]));
}
function completeGraph(n) {
const ids = makeIds(n);
const allEdges = _.flatMap(ids, i => ids.filter(ii => i !== ii).map(ii => [i, ii]));
const oneWayEdges = allEdges.filter(edge => _.isEqual(edge, _.sortBy(edge)));
const adjacencyMap = _(oneWayEdges)
.groupBy(e => e[0])
.mapValues(edges => edges.map(e => e[1]))
.value();
return makeMap(ids
.map((id) => deltaAddSimple(id, adjacencyMap[id] || []))
.map(d => [d.id, fromJS(d)]));
}
function completeGraphBi(n) {
const ids = makeIds(n);
const adjacency = (id) => ids.filter(_id => _id !== id);
return makeMap(ids
.map((id) => deltaAddSimple(id, adjacency(id)))
.map(d => [d.id, fromJS(d)]));
}
function flatTree(n) {
const ids = makeIds(n + 1);
const p = ids.pop();
const adjacency = id => id === p ? ids : [];
return makeMap(ids.concat([p])
.map((id) => deltaAddSimple(id, adjacency(id)))
.map(d => [d.id, fromJS(d)]));
}
function proxyGraph(n) {
const ids = makeIds(n * 2 + 1);
const p = ids.pop();
const topIds = _.take(ids, n);
const bottomIds = _.drop(ids, n);
const adjacencyMap = Object.assign({
[p]: bottomIds
}, _.fromPairs(topIds.map(id => [id, [p]])));
return makeMap(ids.concat([p])
.map((id) => deltaAddSimple(id, adjacencyMap[id] || []))
.map(d => [d.id, fromJS(d)]));
}
function chart(nodes,
n,
style = { width: 250, height: 250 },
margins = { top: 0, left: 0, right: 0, bottom: 0 },
nodeSize = null) {
return (
<div key={n} className="example-chart" style={style}>
<NodesChart
nodes={nodes}
width={style.width}
height={style.height}
margins={margins}
highlightedNodeIds={makeSet()}
highlightedEdgeIds={makeSet()}
layoutPrecision="3"
topologyId={Math.random()}
noZoom="true"
nodeSize={nodeSize}
/>
</div>
);
}
function variants() {
const nCharts = 5;
const width = 250;
const style = {width: nCharts * (width + 16)};
const generators = [
{ id: 'disconnectedGraph', fn: disconnectedGraph },
{ id: 'completeGraphBi', fn: completeGraphBi },
{ id: 'completeGraph', fn: completeGraph },
{ id: 'flatTree', fn: flatTree },
{ id: 'proxyGraph', fn: proxyGraph }
];
return (
<div>
{_.reverse(generators).map(({id, fn}) => (
<div key={id} className="nodes-chart-examples" style={style}>
{_.range(1, nCharts + 1).map(i => (
chart(fn(i), i)
))}
</div>
))}
</div>
);
}
function gridView() {
const nodes = randomGraph(50).map(node => node.remove('label').remove('label_minor'));
const nodeSize = 24;
return (
<NodesGrid width="500" height="500" nodeSize={nodeSize} nodes={nodes} />
);
}
export class Examples extends React.Component {
render() {
return (
<div className="examples">
{gridView()}
{false && variants()}
</div>
);
}
}

View File

@@ -1,6 +1,5 @@
import _ from 'lodash';
import React from 'react';
import { Map as makeMap } from 'immutable';
import classNames from 'classnames';
import ShowMore from '../show-more';
@@ -69,7 +68,6 @@ function getValueForSortBy(sortBy) {
}
/*
function getMetaDataSorters(nodes) {
// returns an array of sorters that will take a node
return _.get(nodes, [0, 'metadata'], []).map((field, index) => node => {
@@ -83,15 +81,14 @@ function getMetaDataSorters(nodes) {
return null;
});
}
*/
function getSortedNodes(nodes, columns, sortBy, sortedDesc) {
const sortedNodes = _.sortBy(
nodes,
getValueForSortBy(sortBy || getDefaultSortBy(columns, nodes)),
'label'
// getMetaDataSorters(nodes)
'label',
getMetaDataSorters(nodes)
);
if (sortedDesc) {
sortedNodes.reverse();
@@ -217,12 +214,6 @@ export default class NodeDetailsTable extends React.Component {
nodes = nodes.slice(0, this.state.limit);
}
const nodeOrderJS = (nodes || []).map((n, i) => [n.id, i]);
const nodeOrder = makeMap(nodeOrderJS);
const childrenWithProps = React.Children.map(this.props.children, (child) => (
React.cloneElement(child, { nodeOrder })
));
const className = classNames('node-details-table-wrapper-wrapper', this.props.className);
return (
@@ -257,7 +248,6 @@ export default class NodeDetailsTable extends React.Component {
expanded={expanded}
notShown={notShown} />
</div>
{childrenWithProps}
</div>
);
}

View File

@@ -1,10 +0,0 @@
require('../styles/main.less');
require('../../node_modules/fixed-data-table/dist/fixed-data-table.css');
require('../images/favicon.ico');
import React from 'react';
import ReactDOM from 'react-dom';
import { Examples } from './components/examples.js';
ReactDOM.render(<Examples />, document.getElementById('app'));

View File

@@ -1508,24 +1508,9 @@ h2 {
}
//
// Examples
// Nodes grid.
//
.examples {
background-color: @background-average-color;
.example-chart {
position: relative;
}
}
.nodes-chart-examples {
.example-chart {
margin: 8px;
display: inline-block;
border: 1px solid steelBlue;
}
}
.nodes-grid {
tr {
@@ -1538,19 +1523,16 @@ h2 {
&-id-column {
margin: -3px -4px;
padding: 2px 2px;
.content {
display: flex;
div {
flex: 1;
}
padding: 2px 4px;
display: flex;
div {
flex: 1;
}
}
.node-details-table-wrapper-wrapper {
flex: 1;
flex: 1;
display: flex;
flex-direction: row;
width: 100%;

View File

@@ -15,13 +15,7 @@ var HtmlWebpackPlugin = require('html-webpack-plugin');
*/
// Inject websocket url to dev backend
var WEBPACK_SERVER_HOST = process.env.WEBPACK_SERVER_HOST || 'localhost';
var COMMON_DEPS = [
'webpack-dev-server/client?http://' + WEBPACK_SERVER_HOST + ':4041',
'webpack/hot/only-dev-server',
'./app/scripts/debug'
];
var WEBPACK_SERVER_HOST = process.env.WEBPACK_SERVER_HOST || 'localhost';
module.exports = {
@@ -69,11 +63,6 @@ module.exports = {
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.IgnorePlugin(/^\.\/locale$/, [/moment$/]),
new HtmlWebpackPlugin({
chunks: ['vendors', 'examples-app'],
template: 'app/html/index.html',
filename: 'examples.html'
}),
new HtmlWebpackPlugin({
chunks: ['vendors', 'contrast-app'],
template: 'app/html/index.html',
@@ -115,7 +104,7 @@ module.exports = {
loader: 'json-loader'
},
{
test: /(\.css|\.less)$/,
test: /\.less$/,
loader: 'style-loader!css-loader!postcss-loader!less-loader'
},
{