From 478a4a6d6658893d640dfbfc8919fefeee9ef180 Mon Sep 17 00:00:00 2001 From: David Kaltschmidt Date: Wed, 25 May 2016 11:26:31 +0200 Subject: [PATCH] Remove common prefix from networks to increase color separation --- .../scripts/components/network-selector-item.js | 2 +- client/app/scripts/reducers/root.js | 15 +++++++++++++++ .../scripts/utils/__tests__/string-utils-test.js | 11 +++++++++++ client/app/scripts/utils/string-utils.js | 6 +++++- client/package.json | 1 + 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/client/app/scripts/components/network-selector-item.js b/client/app/scripts/components/network-selector-item.js index ac7321697..fe69fd676 100644 --- a/client/app/scripts/components/network-selector-item.js +++ b/client/app/scripts/components/network-selector-item.js @@ -39,7 +39,7 @@ class NetworkSelectorItem extends React.Component { 'network-selector-action-selected': isSelected }); const style = { - borderBottomColor: getNodeColor(id) + borderBottomColor: getNodeColor(network.get('colorKey', id)) }; return ( diff --git a/client/app/scripts/reducers/root.js b/client/app/scripts/reducers/root.js index 8ab87ff16..f304d1a5b 100644 --- a/client/app/scripts/reducers/root.js +++ b/client/app/scripts/reducers/root.js @@ -6,6 +6,7 @@ import { fromJS, is as isDeepEqual, List as makeList, Map as makeMap, import ActionTypes from '../constants/action-types'; import { EDGE_ID_SEPARATOR } from '../constants/naming'; import { applyPinnedSearches, updateNodeMatches } from '../utils/search-utils'; +import { longestCommonPrefix } from '../utils/string-utils'; import { findTopologyById, getAdjacentNodes, setTopologyUrlsById, updateTopologyIds, filterHiddenTopologies } from '../utils/topology-utils'; @@ -539,6 +540,20 @@ export function rootReducer(state = initialState, action) { .sort() .map(n => makeMap({id: n, label: n}))); + // optimize color coding for networks + const networkPrefix = longestCommonPrefix(state.get('availableNetworks') + .map(n => n.get('id')).toJS()); + + if (networkPrefix) { + state = state.update('nodes', + nodes => nodes.map(node => node.update('networks', + networks => networks.map(n => n.substr(networkPrefix.length))))); + + state = state.update('availableNetworks', + networks => networks.map(network => network + .set('colorKey', network.get('id').substr(networkPrefix.length)))); + } + state = state.set('availableCanvasMetrics', state.get('nodes') .valueSeq() .flatMap(n => (n.get('metrics') || makeList()).map(m => ( diff --git a/client/app/scripts/utils/__tests__/string-utils-test.js b/client/app/scripts/utils/__tests__/string-utils-test.js index 2426d6a35..a6ffb501e 100644 --- a/client/app/scripts/utils/__tests__/string-utils-test.js +++ b/client/app/scripts/utils/__tests__/string-utils-test.js @@ -10,4 +10,15 @@ describe('StringUtils', () => { expect(formatMetric(0)).toBe('0.00'); }); }); + + describe('longestCommonPrefix', () => { + const fun = StringUtils.longestCommonPrefix; + + it('it should return the longest common prefix', () => { + expect(fun(['interspecies', 'interstellar'])).toBe('inters'); + expect(fun(['space', 'space'])).toBe('space'); + expect(fun([''])).toBe(''); + expect(fun(['prefix', 'suffix'])).toBe(''); + }); + }); }); diff --git a/client/app/scripts/utils/string-utils.js b/client/app/scripts/utils/string-utils.js index 5f8d180d5..788431693 100644 --- a/client/app/scripts/utils/string-utils.js +++ b/client/app/scripts/utils/string-utils.js @@ -1,7 +1,7 @@ import React from 'react'; import filesize from 'filesize'; import d3 from 'd3'; - +import LCP from 'lcp'; const formatLargeValue = d3.format('s'); @@ -69,3 +69,7 @@ const CLEAN_LABEL_REGEX = /\W/g; export function slugify(label) { return label.replace(CLEAN_LABEL_REGEX, '').toLowerCase(); } + +export function longestCommonPrefix(strArr) { + return (new LCP(strArr)).lcp(); +} diff --git a/client/package.json b/client/package.json index f09870513..f2d2a888e 100644 --- a/client/package.json +++ b/client/package.json @@ -15,6 +15,7 @@ "font-awesome": "4.5.0", "font-awesome-webpack": "0.0.4", "immutable": "~3.7.4", + "lcp": "1.0.0", "lodash": "~4.6.1", "materialize-css": "0.97.5", "moment": "2.12.0",