Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

d3-state-visualizer

Package Overview
Dependencies
Maintainers
2
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

d3-state-visualizer - npm Package Compare versions

Comparing version 1.3.1 to 1.3.2

16

lib/charts/tree/sortAndSerialize.js

@@ -23,13 +23,7 @@ 'use strict';

if (obj && (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object') {
var _ret = function () {
var tObj = {};
Object.keys(obj).sort().forEach(function (key) {
return tObj[key] = sortObject(obj[key]);
});
return {
v: tObj
};
}();
if ((typeof _ret === 'undefined' ? 'undefined' : _typeof(_ret)) === "object") return _ret.v;
var tObj = {};
Object.keys(obj).sort().forEach(function (key) {
return tObj[key] = sortObject(obj[key]);
});
return tObj;
}

@@ -36,0 +30,0 @@

@@ -10,22 +10,21 @@ 'use strict';

var _deepmerge = (0, _deepmerge3.default)(defaultOptions, options);
var _deepmerge = (0, _deepmerge3.default)(defaultOptions, options),
id = _deepmerge.id,
style = _deepmerge.style,
size = _deepmerge.size,
aspectRatio = _deepmerge.aspectRatio,
initialZoom = _deepmerge.initialZoom,
margin = _deepmerge.margin,
isSorted = _deepmerge.isSorted,
widthBetweenNodesCoeff = _deepmerge.widthBetweenNodesCoeff,
heightBetweenNodesCoeff = _deepmerge.heightBetweenNodesCoeff,
transitionDuration = _deepmerge.transitionDuration,
blinkDuration = _deepmerge.blinkDuration,
state = _deepmerge.state,
rootKeyName = _deepmerge.rootKeyName,
pushMethod = _deepmerge.pushMethod,
tree = _deepmerge.tree,
tooltipOptions = _deepmerge.tooltipOptions,
onClickText = _deepmerge.onClickText;
var id = _deepmerge.id;
var style = _deepmerge.style;
var size = _deepmerge.size;
var aspectRatio = _deepmerge.aspectRatio;
var initialZoom = _deepmerge.initialZoom;
var margin = _deepmerge.margin;
var isSorted = _deepmerge.isSorted;
var widthBetweenNodesCoeff = _deepmerge.widthBetweenNodesCoeff;
var heightBetweenNodesCoeff = _deepmerge.heightBetweenNodesCoeff;
var transitionDuration = _deepmerge.transitionDuration;
var state = _deepmerge.state;
var rootKeyName = _deepmerge.rootKeyName;
var pushMethod = _deepmerge.pushMethod;
var tree = _deepmerge.tree;
var tooltipOptions = _deepmerge.tooltipOptions;
var onClickText = _deepmerge.onClickText;
var width = size - margin.left - margin.right;

@@ -52,5 +51,5 @@ var height = size * aspectRatio - margin.top - margin.bottom;

var vis = root.append('svg').attr(attr).style(_extends({ cursor: '-webkit-grab' }, style)).call(zoom.on('zoom', function () {
var _d3$event = _d4.default.event;
var translate = _d3$event.translate;
var scale = _d3$event.scale;
var _d3$event = _d4.default.event,
translate = _d3$event.translate,
scale = _d3$event.scale;

@@ -71,2 +70,29 @@ vis.attr('transform', 'translate(' + translate + ')scale(' + scale + ')');

// previousNodePositionsById stores node x and y
// as well as hierarchy (id / parentId);
// helps animating transitions
var previousNodePositionsById = {
root: {
id: 'root',
parentId: null,
x: height / 2,
y: 0
}
// traverses a map with node positions by going through the chain
// of parent ids; once a parent that matches the given filter is found,
// the parent position gets returned
};function findParentNodePosition(nodePositionsById, nodeId, filter) {
var currentPosition = nodePositionsById[nodeId];
while (currentPosition) {
currentPosition = nodePositionsById[currentPosition.parentId];
if (!currentPosition) {
return null;
}
if (!filter || filter(currentPosition)) {
return currentPosition;
}
}
}
return function renderChart() {

@@ -84,15 +110,20 @@ var nextState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : tree || state;

// nodes are assigned with string ids, which reflect their location
// within the hierarcy; e.g. "root|branch|subBranch|subBranch[0]|property"
// top-level elemnt always has id "root"
(0, _utils.visit)(data, function (node) {
return maxLabelLength = Math.max(node.name.length, maxLabelLength);
maxLabelLength = Math.max(node.name.length, maxLabelLength);
node.id = node.id || 'root';
}, function (node) {
return node.children && node.children.length > 0 ? node.children : null;
return node.children && node.children.length > 0 ? node.children.map(function (c) {
c.id = (node.id || '') + '|' + c.name;
return c;
}) : null;
});
data.x0 = height / 2;
data.y0 = 0;
/*eslint-disable*/
update(data);
update();
/*eslint-enable*/
function update(source) {
function update() {
// path generator for links

@@ -114,2 +145,15 @@ var diagonal = _d4.default.svg.diagonal().projection(function (d) {

var nodePositions = nodes.map(function (n) {
return {
parentId: n.parent && n.parent.id,
id: n.id,
x: n.x,
y: n.y
};
});
var nodePositionsById = {};
nodePositions.forEach(function (node) {
return nodePositionsById[node.id] = node;
});
// process the node selection

@@ -121,7 +165,10 @@ var node = vis.selectAll('g.node').property('__oldData__', function (d) {

});
var nodeEnter = node.enter().append('g').attr({
'class': 'node',
transform: function transform(d) {
return 'translate(' + source.y0 + ',' + source.x0 + ')';
var position = findParentNodePosition(nodePositionsById, d.id, function (n) {
return previousNodePositionsById[n.id];
});
var previousPosition = position && previousNodePositionsById[position.id] || previousNodePositionsById.root;
return 'translate(' + previousPosition.y + ',' + previousPosition.x + ')';
}

@@ -132,3 +179,3 @@ }).style({

}).on({
mouseover: function mouseover(d, i) {
mouseover: function mouseover() {
_d4.default.select(this).style({

@@ -138,3 +185,3 @@ fill: style.text.colors.hover

},
mouseout: function mouseout(d, i) {
mouseout: function mouseout() {
_d4.default.select(this).style({

@@ -152,13 +199,20 @@ fill: style.text.colors.default

nodeEnter.append('circle').attr({
'class': 'nodeCircle'
// g inside node contains circle and text
// this extra wrapper helps run d3 transitions in parallel
var nodeEnterInnerGroup = nodeEnter.append('g');
nodeEnterInnerGroup.append('circle').attr({
'class': 'nodeCircle',
r: 0
}).on({
click: function click(clickedNode) {
if (_d4.default.event.defaultPrevented) return;
update((0, _utils.toggleChildren)(clickedNode));
(0, _utils.toggleChildren)(clickedNode);
update();
}
});
nodeEnter.append('text').attr({
nodeEnterInnerGroup.append('text').attr({
'class': 'nodeText',
'text-anchor': 'middle',
'transform': 'translate(0,0)',
dy: '.35em'

@@ -174,10 +228,3 @@ }).style({

// update the text to reflect whether node has children or not
node.select('text').attr({
x: function x(d) {
return d.children || d._children ? -(style.node.radius + 10) : style.node.radius + 10;
},
'text-anchor': function textAnchor(d) {
return d.children || d._children ? 'end' : 'start';
}
}).text(function (d) {
node.select('text').text(function (d) {
return d.name;

@@ -187,5 +234,3 @@ });

// change the circle fill depending on whether it has children and is collapsed
node.select('circle.nodeCircle').attr({
r: style.node.radius
}).style({
node.select('circle').style({
stroke: 'black',

@@ -205,10 +250,15 @@ 'stroke-width': '1.5px',

// fade the text in
nodeUpdate.select('text').style('fill-opacity', 1);
// ensure circle radius is correct
nodeUpdate.select('circle').attr('r', style.node.radius);
// restore the circle
nodeUpdate.select('circle').attr('r', 7);
// fade the text in and align it
nodeUpdate.select('text').style('fill-opacity', 1).attr({
transform: function transform(d) {
var x = (d.children || d._children ? -1 : 1) * (this.getBBox().width / 2 + style.node.radius + 5);
return 'translate(' + x + ',0)';
}
});
// blink updated nodes
nodeUpdate.filter(function flick(d) {
node.filter(function flick(d) {
// test whether the relevant properties of d match

@@ -218,4 +268,4 @@ // the equivalent property of the oldData

// to catch the entering elements!
return !this.__oldData__ || d.value !== this.__oldData__.value;
}).style('fill-opacity', '0.3').transition().duration(100).style('fill-opacity', '1');
return this.__oldData__ && d.value !== this.__oldData__.value;
}).select('g').style('opacity', '0.3').transition().duration(blinkDuration).style('opacity', '1');

@@ -225,3 +275,7 @@ // transition exiting nodes to the parent's new position

transform: function transform(d) {
return 'translate(' + source.y + ',' + source.x + ')';
var position = findParentNodePosition(previousNodePositionsById, d.id, function (n) {
return nodePositionsById[n.id];
});
var futurePosition = position && nodePositionsById[position.id] || nodePositionsById.root;
return 'translate(' + futurePosition.y + ',' + futurePosition.x + ')';
}

@@ -243,9 +297,9 @@ }).remove();

d: function d(_d) {
var o = {
x: source.x0,
y: source.y0
};
var position = findParentNodePosition(nodePositionsById, _d.target.id, function (n) {
return previousNodePositionsById[n.id];
});
var previousPosition = position && previousNodePositionsById[position.id] || previousNodePositionsById.root;
return diagonal({
source: o,
target: o
source: previousPosition,
target: previousPosition
});

@@ -263,9 +317,9 @@ }

d: function d(_d2) {
var o = {
x: source.x,
y: source.y
};
var position = findParentNodePosition(previousNodePositionsById, _d2.target.id, function (n) {
return nodePositionsById[n.id];
});
var futurePosition = position && nodePositionsById[position.id] || nodePositionsById.root;
return diagonal({
source: o,
target: o
source: futurePosition,
target: futurePosition
});

@@ -279,6 +333,3 @@ }

// stash the old positions for transition
nodes.forEach(function (d) {
d.x0 = d.x;
d.y0 = d.y;
});
previousNodePositionsById = nodePositionsById;
}

@@ -323,3 +374,3 @@ };

},
radius: 5
radius: 7
},

@@ -350,2 +401,3 @@ text: {

transitionDuration: 750,
blinkDuration: 100,
onClickText: function onClickText() {},

@@ -352,0 +404,0 @@ tooltipOptions: {

@@ -89,4 +89,4 @@ 'use strict';

function getTooltipString(node, i, _ref) {
var _ref$indentationSize = _ref.indentationSize;
var indentationSize = _ref$indentationSize === undefined ? 4 : _ref$indentationSize;
var _ref$indentationSize = _ref.indentationSize,
indentationSize = _ref$indentationSize === undefined ? 4 : _ref$indentationSize;

@@ -93,0 +93,0 @@ if (!(0, _ramda.is)(Object, node)) return '';

{
"name": "d3-state-visualizer",
"version": "1.3.1",
"version": "1.3.2",
"description": "Visualize your app state with a range of reusable charts",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -5,3 +5,3 @@ d3-state-visualizer

[Demo](http://romseguy.github.io/d3-state-visualizer)
[Demo](http://reduxjs.github.io/d3-state-visualizer)

@@ -8,0 +8,0 @@ ## Installation

@@ -21,3 +21,3 @@ import d3 from 'd3'

},
radius: 5
radius: 7
},

@@ -48,2 +48,3 @@ text: {

transitionDuration: 750,
blinkDuration: 100,
onClickText: () => {},

@@ -74,2 +75,3 @@ tooltipOptions: {

transitionDuration,
blinkDuration,
state,

@@ -125,2 +127,30 @@ rootKeyName,

// previousNodePositionsById stores node x and y
// as well as hierarchy (id / parentId);
// helps animating transitions
let previousNodePositionsById = {
root: {
id: 'root',
parentId: null,
x: height / 2,
y: 0
}
}
// traverses a map with node positions by going through the chain
// of parent ids; once a parent that matches the given filter is found,
// the parent position gets returned
function findParentNodePosition(nodePositionsById, nodeId, filter) {
let currentPosition = nodePositionsById[nodeId]
while (currentPosition) {
currentPosition = nodePositionsById[currentPosition.parentId]
if (!currentPosition) {
return null
}
if (!filter || filter(currentPosition)) {
return currentPosition
}
}
}
return function renderChart(nextState = tree || state) {

@@ -136,14 +166,21 @@ data = !tree ? map2tree(nextState, {key: rootKeyName, pushMethod}) : nextState

// nodes are assigned with string ids, which reflect their location
// within the hierarcy; e.g. "root|branch|subBranch|subBranch[0]|property"
// top-level elemnt always has id "root"
visit(data,
node => maxLabelLength = Math.max(node.name.length, maxLabelLength),
node => node.children && node.children.length > 0 ? node.children : null
node => {
maxLabelLength = Math.max(node.name.length, maxLabelLength)
node.id = node.id || 'root'
},
node => node.children && node.children.length > 0 ? node.children.map((c) => {
c.id = `${node.id || ''}|${c.name}`
return c
}) : null
)
data.x0 = height / 2
data.y0 = 0
/*eslint-disable*/
update(data)
update()
/*eslint-enable*/
function update(source) {
function update() {
// path generator for links

@@ -161,2 +198,11 @@ const diagonal = d3.svg.diagonal().projection(d => [d.y, d.x])

const nodePositions = nodes.map(n => ({
parentId: n.parent && n.parent.id,
id: n.id,
x: n.x,
y: n.y
}))
const nodePositionsById = {}
nodePositions.forEach(node => nodePositionsById[node.id] = node)
// process the node selection

@@ -166,7 +212,10 @@ let node = vis.selectAll('g.node')

.data(nodes, d => d.id || (d.id = ++nodeIndex))
let nodeEnter = node.enter().append('g')
.attr({
'class': 'node',
transform: d => `translate(${source.y0},${source.x0})`
transform: d => {
const position = findParentNodePosition(nodePositionsById, d.id, (n) => previousNodePositionsById[n.id])
const previousPosition = position && previousNodePositionsById[position.id] || previousNodePositionsById.root
return `translate(${previousPosition.y},${previousPosition.x})`
}
})

@@ -178,3 +227,3 @@ .style({

.on({
mouseover: function mouseover(d, i) {
mouseover: function mouseover() {
d3.select(this).style({

@@ -184,3 +233,3 @@ fill: style.text.colors.hover

},
mouseout: function mouseout(d, i) {
mouseout: function mouseout() {
d3.select(this).style({

@@ -199,5 +248,9 @@ fill: style.text.colors.default

nodeEnter.append('circle')
// g inside node contains circle and text
// this extra wrapper helps run d3 transitions in parallel
const nodeEnterInnerGroup = nodeEnter.append('g')
nodeEnterInnerGroup.append('circle')
.attr({
'class': 'nodeCircle'
'class': 'nodeCircle',
r: 0
})

@@ -207,9 +260,12 @@ .on({

if (d3.event.defaultPrevented) return
update(toggleChildren(clickedNode))
toggleChildren(clickedNode)
update()
}
})
nodeEnter.append('text')
nodeEnterInnerGroup.append('text')
.attr({
'class': 'nodeText',
'text-anchor': 'middle',
'transform': `translate(0,0)`,
dy: '.35em'

@@ -227,13 +283,6 @@ })

node.select('text')
.attr({
x: d => d.children || d._children ? -(style.node.radius + 10) : style.node.radius + 10,
'text-anchor': d => d.children || d._children ? 'end' : 'start'
})
.text(d => d.name)
// change the circle fill depending on whether it has children and is collapsed
node.select('circle.nodeCircle')
.attr({
r: style.node.radius
})
node.select('circle')
.style({

@@ -252,11 +301,18 @@ stroke: 'black',

// fade the text in
// ensure circle radius is correct
nodeUpdate.select('circle')
.attr('r', style.node.radius)
// fade the text in and align it
nodeUpdate.select('text')
.style('fill-opacity', 1)
.attr({
transform: function transform(d) {
const x = (d.children || d._children ? -1 : 1) * (this.getBBox().width / 2 + style.node.radius + 5)
return `translate(${x},0)`
}
})
// restore the circle
nodeUpdate.select('circle').attr('r', 7)
// blink updated nodes
nodeUpdate.filter(function flick(d) {
node.filter(function flick(d) {
// test whether the relevant properties of d match

@@ -266,6 +322,7 @@ // the equivalent property of the oldData

// to catch the entering elements!
return (!this.__oldData__ || d.value !== this.__oldData__.value)
return (this.__oldData__ && d.value !== this.__oldData__.value)
})
.style('fill-opacity', '0.3').transition()
.duration(100).style('fill-opacity', '1')
.select('g')
.style('opacity', '0.3').transition()
.duration(blinkDuration).style('opacity', '1')

@@ -276,3 +333,7 @@ // transition exiting nodes to the parent's new position

.attr({
transform: d => `translate(${source.y},${source.x})`
transform: d => {
const position = findParentNodePosition(previousNodePositionsById, d.id, (n) => nodePositionsById[n.id])
const futurePosition = position && nodePositionsById[position.id] || nodePositionsById.root
return `translate(${futurePosition.y},${futurePosition.x})`
}
})

@@ -296,9 +357,7 @@ .remove()

d: d => {
let o = {
x: source.x0,
y: source.y0
}
const position = findParentNodePosition(nodePositionsById, d.target.id, (n) => previousNodePositionsById[n.id])
const previousPosition = position && previousNodePositionsById[position.id] || previousNodePositionsById.root
return diagonal({
source: o,
target: o
source: previousPosition,
target: previousPosition
})

@@ -317,13 +376,12 @@ }

// transition exiting nodes to the parent's new position
link.exit().transition()
link.exit()
.transition()
.duration(transitionDuration)
.attr({
d: d => {
let o = {
x: source.x,
y: source.y
}
const position = findParentNodePosition(previousNodePositionsById, d.target.id, (n) => nodePositionsById[n.id])
const futurePosition = position && nodePositionsById[position.id] || nodePositionsById.root
return diagonal({
source: o,
target: o
source: futurePosition,
target: futurePosition
})

@@ -338,8 +396,5 @@ }

// stash the old positions for transition
nodes.forEach(d => {
d.x0 = d.x
d.y0 = d.y
})
previousNodePositionsById = nodePositionsById
}
}
}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc