mirror of
https://github.com/reduxjs/redux-devtools.git
synced 2025-07-22 22:19:48 +03:00
Updates
This commit is contained in:
parent
046c69c5f7
commit
166ee67057
|
@ -1,4 +1,4 @@
|
|||
import d3, { ZoomEvent, Primitive } from 'd3';
|
||||
import d3, { ZoomEvent } from 'd3';
|
||||
import { isEmpty } from 'ramda';
|
||||
import { map2tree } from 'map2tree';
|
||||
import deepmerge from 'deepmerge';
|
||||
|
@ -9,6 +9,7 @@ import {
|
|||
getNodeGroupByDepthCount,
|
||||
} from './utils';
|
||||
import { tooltip } from 'd3tooltip';
|
||||
import type { StyleValue } from 'd3tooltip';
|
||||
|
||||
// TODO Can we remove InputOptions?
|
||||
export interface InputOptions {
|
||||
|
@ -20,7 +21,7 @@ export interface InputOptions {
|
|||
rootKeyName: string;
|
||||
pushMethod: 'push' | 'unshift';
|
||||
id: string;
|
||||
chartStyles: { [key: string]: Primitive };
|
||||
chartStyles: { [key: string]: StyleValue };
|
||||
nodeStyleOptions: {
|
||||
colors: {
|
||||
default: string;
|
||||
|
@ -35,7 +36,7 @@ export interface InputOptions {
|
|||
hover: string;
|
||||
};
|
||||
};
|
||||
linkStyles: { [key: string]: Primitive };
|
||||
linkStyles: { [key: string]: StyleValue };
|
||||
size: number;
|
||||
aspectRatio: number;
|
||||
initialZoom: number;
|
||||
|
@ -59,7 +60,7 @@ export interface InputOptions {
|
|||
left: number;
|
||||
top: number;
|
||||
};
|
||||
style?: { [key: string]: Primitive } | undefined;
|
||||
style?: { [key: string]: StyleValue } | undefined;
|
||||
indentationSize?: number;
|
||||
};
|
||||
}
|
||||
|
@ -73,7 +74,7 @@ interface Options {
|
|||
rootKeyName: string;
|
||||
pushMethod: 'push' | 'unshift';
|
||||
id: string;
|
||||
chartStyles: { [key: string]: Primitive };
|
||||
chartStyles: { [key: string]: StyleValue };
|
||||
nodeStyleOptions: {
|
||||
colors: {
|
||||
default: string;
|
||||
|
@ -88,7 +89,7 @@ interface Options {
|
|||
hover: string;
|
||||
};
|
||||
};
|
||||
linkStyles: { [key: string]: Primitive };
|
||||
linkStyles: { [key: string]: StyleValue };
|
||||
size: number;
|
||||
aspectRatio: number;
|
||||
initialZoom: number;
|
||||
|
@ -112,7 +113,7 @@ interface Options {
|
|||
left: number;
|
||||
top: number;
|
||||
};
|
||||
style: { [key: string]: Primitive } | undefined;
|
||||
style: { [key: string]: StyleValue } | undefined;
|
||||
indentationSize?: number;
|
||||
};
|
||||
}
|
||||
|
@ -241,12 +242,11 @@ export default function (
|
|||
|
||||
svgElement = svgElement.style('cursor', '-webkit-grab');
|
||||
|
||||
const vis = root
|
||||
.append('svg')
|
||||
.attr(attr)
|
||||
.style({ cursor: '-webkit-grab', ...chartStyles } as unknown as {
|
||||
[key: string]: Primitive;
|
||||
})
|
||||
for (const [key, value] of Object.entries(chartStyles)) {
|
||||
svgElement = svgElement.style(key, value);
|
||||
}
|
||||
|
||||
const vis = svgElement
|
||||
.call(
|
||||
zoom.on('zoom', () => {
|
||||
const { translate, scale } = d3.event as ZoomEvent;
|
||||
|
@ -257,11 +257,12 @@ export default function (
|
|||
})
|
||||
)
|
||||
.append('g')
|
||||
.attr({
|
||||
transform: `translate(${margin.left + nodeStyleOptions.radius}, ${
|
||||
.attr(
|
||||
'transform',
|
||||
`translate(${margin.left + nodeStyleOptions.radius}, ${
|
||||
margin.top
|
||||
}) scale(${initialZoom})`,
|
||||
});
|
||||
}) scale(${initialZoom})`
|
||||
);
|
||||
|
||||
let layout = d3.layout.tree().size([width, height]);
|
||||
let data: NodeWithId;
|
||||
|
@ -384,24 +385,20 @@ export default function (
|
|||
const nodeEnter = node
|
||||
.enter()
|
||||
.append('g')
|
||||
.attr({
|
||||
class: 'node',
|
||||
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!})`;
|
||||
},
|
||||
})
|
||||
.style({
|
||||
fill: textStyleOptions.colors.default,
|
||||
cursor: 'pointer',
|
||||
.attr('class', 'node')
|
||||
.attr('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!})`;
|
||||
})
|
||||
.style('fill', textStyleOptions.colors.default)
|
||||
.style('cursor', 'pointer')
|
||||
.on('mouseover', function mouseover(this: EventTarget) {
|
||||
d3.select(this).style({
|
||||
fill: textStyleOptions.colors.hover,
|
||||
|
@ -426,10 +423,8 @@ export default function (
|
|||
const nodeEnterInnerGroup = nodeEnter.append('g');
|
||||
nodeEnterInnerGroup
|
||||
.append('circle')
|
||||
.attr({
|
||||
class: 'nodeCircle',
|
||||
r: 0,
|
||||
})
|
||||
.attr('class', 'nodeCircle')
|
||||
.attr('r', 0)
|
||||
.on('click', (clickedNode) => {
|
||||
if ((d3.event as Event).defaultPrevented) return;
|
||||
toggleChildren(clickedNode);
|
||||
|
@ -438,15 +433,11 @@ export default function (
|
|||
|
||||
nodeEnterInnerGroup
|
||||
.append('text')
|
||||
.attr({
|
||||
class: 'nodeText',
|
||||
'text-anchor': 'middle',
|
||||
transform: 'translate(0,0)',
|
||||
dy: '.35em',
|
||||
})
|
||||
.style({
|
||||
'fill-opacity': 0,
|
||||
})
|
||||
.attr('class', 'nodeText')
|
||||
.attr('text-anchor', 'middle')
|
||||
.attr('transform', 'translate(0,0)')
|
||||
.attr('dy', '.35em')
|
||||
.style('fill-opacity', 0)
|
||||
.text((d) => d.name)
|
||||
.on('click', onClickText);
|
||||
|
||||
|
@ -454,24 +445,23 @@ export default function (
|
|||
node.select('text').text((d) => d.name);
|
||||
|
||||
// change the circle fill depending on whether it has children and is collapsed
|
||||
node.select('circle').style({
|
||||
stroke: 'black',
|
||||
'stroke-width': '1.5px',
|
||||
fill: (d) =>
|
||||
node
|
||||
.select('circle')
|
||||
.style('stroke', 'black')
|
||||
.style('stroke-width', '1.5px')
|
||||
.style('fill', (d) =>
|
||||
d._children
|
||||
? nodeStyleOptions.colors.collapsed
|
||||
: d.children
|
||||
? nodeStyleOptions.colors.parent
|
||||
: nodeStyleOptions.colors.default,
|
||||
});
|
||||
: nodeStyleOptions.colors.default
|
||||
);
|
||||
|
||||
// transition nodes to their new position
|
||||
const nodeUpdate = node
|
||||
.transition()
|
||||
.duration(transitionDuration)
|
||||
.attr({
|
||||
transform: (d) => `translate(${d.y!},${d.x!})`,
|
||||
});
|
||||
.attr('transform', (d) => `translate(${d.y!},${d.x!})`);
|
||||
|
||||
// ensure circle radius is correct
|
||||
nodeUpdate.select('circle').attr('r', nodeStyleOptions.radius);
|
||||
|
@ -480,13 +470,11 @@ export default function (
|
|||
nodeUpdate
|
||||
.select('text')
|
||||
.style('fill-opacity', 1)
|
||||
.attr({
|
||||
transform: function transform(this: SVGGraphicsElement, d) {
|
||||
const x =
|
||||
(d.children || d._children ? -1 : 1) *
|
||||
(this.getBBox().width / 2 + nodeStyleOptions.radius + 5);
|
||||
return `translate(${x},0)`;
|
||||
},
|
||||
.attr('transform', function transform(this: SVGGraphicsElement, d) {
|
||||
const x =
|
||||
(d.children || d._children ? -1 : 1) *
|
||||
(this.getBBox().width / 2 + nodeStyleOptions.radius + 5);
|
||||
return `translate(${x},0)`;
|
||||
});
|
||||
|
||||
// blink updated nodes
|
||||
|
@ -509,18 +497,16 @@ export default function (
|
|||
.exit()
|
||||
.transition()
|
||||
.duration(transitionDuration)
|
||||
.attr({
|
||||
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!})`;
|
||||
},
|
||||
.attr('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!})`;
|
||||
})
|
||||
.remove();
|
||||
|
||||
|
@ -537,53 +523,44 @@ export default function (
|
|||
link
|
||||
.enter()
|
||||
.insert('path', 'g')
|
||||
.attr({
|
||||
class: 'link',
|
||||
d: (d) => {
|
||||
const position = findParentNodePosition(
|
||||
nodePositionsById,
|
||||
(d.target as NodeWithId).id,
|
||||
(n) => !!previousNodePositionsById[n.id]
|
||||
);
|
||||
const previousPosition =
|
||||
(position && previousNodePositionsById[position.id]) ||
|
||||
previousNodePositionsById.root;
|
||||
return diagonal({
|
||||
source: previousPosition,
|
||||
target: previousPosition,
|
||||
} as d3.svg.diagonal.Link<NodePosition>);
|
||||
},
|
||||
.attr('class', 'link')
|
||||
.attr('d', (d) => {
|
||||
const position = findParentNodePosition(
|
||||
nodePositionsById,
|
||||
(d.target as NodeWithId).id,
|
||||
(n) => !!previousNodePositionsById[n.id]
|
||||
);
|
||||
const previousPosition =
|
||||
(position && previousNodePositionsById[position.id]) ||
|
||||
previousNodePositionsById.root;
|
||||
return diagonal({
|
||||
source: previousPosition,
|
||||
target: previousPosition,
|
||||
} as d3.svg.diagonal.Link<NodePosition>);
|
||||
})
|
||||
.style(linkStyles);
|
||||
|
||||
// transition links to their new position
|
||||
link
|
||||
.transition()
|
||||
.duration(transitionDuration)
|
||||
.attr({
|
||||
d: diagonal as unknown as Primitive,
|
||||
});
|
||||
link.transition().duration(transitionDuration).attr('d', diagonal);
|
||||
|
||||
// transition exiting nodes to the parent's new position
|
||||
link
|
||||
.exit()
|
||||
.transition()
|
||||
.duration(transitionDuration)
|
||||
.attr({
|
||||
d: (d) => {
|
||||
const position = findParentNodePosition(
|
||||
previousNodePositionsById,
|
||||
(d.target as NodeWithId).id,
|
||||
(n) => !!nodePositionsById[n.id]
|
||||
);
|
||||
const futurePosition =
|
||||
(position && nodePositionsById[position.id]) ||
|
||||
nodePositionsById.root;
|
||||
return diagonal({
|
||||
source: futurePosition,
|
||||
target: futurePosition,
|
||||
});
|
||||
},
|
||||
.attr('d', (d) => {
|
||||
const position = findParentNodePosition(
|
||||
previousNodePositionsById,
|
||||
(d.target as NodeWithId).id,
|
||||
(n) => !!nodePositionsById[n.id]
|
||||
);
|
||||
const futurePosition =
|
||||
(position && nodePositionsById[position.id]) ||
|
||||
nodePositionsById.root;
|
||||
return diagonal({
|
||||
source: futurePosition,
|
||||
target: futurePosition,
|
||||
});
|
||||
})
|
||||
.remove();
|
||||
|
||||
|
@ -595,5 +572,3 @@ export default function (
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
export { Primitive };
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export { tree } from './charts';
|
||||
export type { InputOptions, NodeWithId, Primitive } from './charts';
|
||||
export type { InputOptions, NodeWithId } from './charts';
|
||||
|
|
|
@ -24,7 +24,7 @@ const defaultOptions: Options<ContainerElement, unknown, BaseType, unknown> = {
|
|||
root: undefined,
|
||||
};
|
||||
|
||||
type StyleValue = string | number | boolean;
|
||||
export type StyleValue = string | number | boolean;
|
||||
|
||||
interface Tip<
|
||||
GElement extends ContainerElement,
|
||||
|
@ -62,7 +62,7 @@ export function tooltip<
|
|||
index?: number,
|
||||
outerIndex?: number
|
||||
) => string = () => '';
|
||||
let styles = {};
|
||||
let styles: { [key: string]: StyleValue } = {};
|
||||
|
||||
let el: Selection<HTMLDivElement, Datum, BaseType, PDatum>;
|
||||
const anchor: Selection<GElement, Datum, BaseType, PDatum> =
|
||||
|
@ -85,7 +85,7 @@ export function tooltip<
|
|||
.style('top', `${y}px`);
|
||||
|
||||
for (const [key, value] of Object.entries(styles)) {
|
||||
el = el.style(key, value as StyleValue);
|
||||
el = el.style(key, value);
|
||||
}
|
||||
|
||||
el = el.html(() => text(node));
|
||||
|
|
Loading…
Reference in New Issue
Block a user