Signed-off-by: Ke Xu <xuke@microsoft.com>
This commit is contained in:
xuke444 2021-05-11 14:07:43 -07:00 коммит произвёл GitHub
Родитель e7785e5fb3
Коммит 44690a9bc4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 64 добавлений и 57 удалений

Просмотреть файл

@ -65,7 +65,7 @@ export class TreeLegend extends React.Component<ITreeLegendProps> {
<circle
r="26"
className={classNames.node}
style={this.props.nodeDetail.errorColor}
style={{ fill: this.props.nodeDetail.errorColor }}
/>
<g
style={this.props.nodeDetail.maskDown}

Просмотреть файл

@ -1,9 +1,9 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { SVGToolTip } from "@responsible-ai/core-ui";
import { getRandomId, SVGToolTip } from "@responsible-ai/core-ui";
import { HierarchyPointNode } from "d3-hierarchy";
import { IProcessedStyleSet } from "office-ui-fabric-react";
import { getTheme, IProcessedStyleSet } from "office-ui-fabric-react";
import React from "react";
import { isColorDark } from "../../ColorPalette";
@ -32,6 +32,8 @@ export class TreeViewNode extends React.Component<ITreeViewNodeProps> {
public render(): React.ReactNode {
const { node } = this.props;
const classNames = treeViewRendererStyles();
const gradientFillId = getRandomId();
const theme = getTheme();
return (
<>
<g
@ -40,10 +42,47 @@ export class TreeViewNode extends React.Component<ITreeViewNodeProps> {
pointerEvents="all"
ref={this.ref}
>
<linearGradient id={gradientFillId} x1="0.5" y1="1" x2="0.5" y2="0">
<stop
offset="0%"
stopOpacity="1"
stopColor={this.props.node.data.errorColor}
/>
<stop
offset={`${
(this.props.node.data.error /
this.props.node.data.rootErrorSize) *
100
}%`}
stopOpacity="1"
stopColor={this.props.node.data.errorColor}
/>
<stop
offset={`${
(this.props.node.data.error /
this.props.node.data.rootErrorSize) *
100
}%`}
stopOpacity="1"
stopColor={theme.semanticColors.bodyBackgroundChecked}
/>
<stop
offset="100%"
stopOpacity="1"
stopColor={theme.semanticColors.bodyBackgroundChecked}
/>
</linearGradient>
<circle
r={node.data.r}
className={classNames.node}
style={node.data.nodeState.errorStyle}
style={{
color: "black",
stroke: this.props.node.data.nodeState.onSelectedPath
? theme.semanticColors.link
: this.props.node.data.errorColor,
strokeWidth: this.props.node.data.nodeState.onSelectedPath ? 3 : 2
}}
fill={`url(#${gradientFillId})`}
/>
{node.data.nodeState.onSelectedPath && (
<circle
@ -55,19 +94,12 @@ export class TreeViewNode extends React.Component<ITreeViewNodeProps> {
}
/>
)}
<g
style={node.data.fillstyleDown}
mask="url(#Mask)"
className={classNames.nopointer}
>
<circle r="26" style={node.data.fillstyleUp} />
</g>
<text
textAnchor="middle"
className={this.getNodeClassName(
classNames,
node.data.filterProps.errorCoverage,
node.data.errorColor.fill
node.data.errorColor
)}
>
{node.data.error}/{node.data.size}

Просмотреть файл

@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { Property } from "csstype";
import {
IStyle,
mergeStyleSets,
@ -14,7 +15,6 @@ import { ColorPalette } from "../../ColorPalette";
export interface ITreeViewRendererStyles {
clickedNodeDashed: IStyle;
clickedNodeFull: IStyle;
detailLines: IStyle;
filledNodeText: IStyle;
legend: IStyle;
linkLabel: IStyle;
@ -26,9 +26,10 @@ export interface ITreeViewRendererStyles {
treeDescription: IStyle;
}
export const treeViewRendererStyles: () => IProcessedStyleSet<
ITreeViewRendererStyles
> = () => {
export const treeViewRendererStyles = (props?: {
onSelectedPath?: boolean;
fill?: Property.Color;
}): IProcessedStyleSet<ITreeViewRendererStyles> => {
const theme = getTheme();
const nodeTextStyle = {
fontSize: "10px",
@ -48,13 +49,6 @@ export const treeViewRendererStyles: () => IProcessedStyleSet<
stroke: "#0078D4",
strokeWidth: 2
},
detailLines: {
fill: theme.semanticColors.inputBackground,
fontWeight: "bold",
pointerEvents: "none",
textAnchor: "start",
transform: "translate(0px, 10px)"
},
filledNodeText: mergeStyles([
nodeTextStyle,
{
@ -71,12 +65,13 @@ export const treeViewRendererStyles: () => IProcessedStyleSet<
},
node: {
":hover": {
strokeWidth: "3px"
stroke: `${theme.semanticColors.link} !important`,
strokeWidth: "3px !important"
},
cursor: "pointer",
opacity: "1",
stroke: "#089acc",
strokeWidth: "0px"
stroke: props?.onSelectedPath ? theme.semanticColors.link : props?.fill,
strokeWidth: props?.onSelectedPath ? 3 : 2
},
nodeText: mergeStyles([
nodeTextStyle,

Просмотреть файл

@ -12,6 +12,7 @@ import {
getRandomId
} from "@responsible-ai/core-ui";
import { localization } from "@responsible-ai/localization";
import { Property } from "csstype";
import { max as d3max } from "d3-array";
import {
stratify as d3stratify,
@ -216,17 +217,8 @@ export class TreeViewRenderer extends React.PureComponent<
// The code below generates the circular nodes in the tree view.
const nodeData: Array<HierarchyPointNode<ITreeNode>> = rootDescendants.map(
(d: HierarchyPointNode<ITreeNode>): HierarchyPointNode<ITreeNode> => {
let selectedStyle: Record<string, number | string | undefined> = {
fill: d.data.errorColor.fill
};
if (d.data.nodeState.onSelectedPath) {
selectedStyle = { fill: d.data.errorColor.fill, strokeWidth: 3 };
}
// Update node state based on new user actions
d.data.nodeState = {
errorStyle: selectedStyle,
isSelectedLeaf: d.data.nodeState.isSelectedLeaf,
onSelectedPath: d.data.nodeState.onSelectedPath,
style: {
@ -402,7 +394,7 @@ export class TreeViewRenderer extends React.PureComponent<
const minColor = ColorPalette.MinColor;
const maxColor = ColorPalette.MaxColor;
const colorgrad = d3scaleLinear<string>()
const colorgrad = d3scaleLinear<Property.Color>()
.domain([min, max])
.interpolate(d3interpolateHcl)
.range([minColor, maxColor]);
@ -416,12 +408,10 @@ export class TreeViewRenderer extends React.PureComponent<
const calcMaskShift = globalErrorPerc * 52;
const filterProps = this.calculateFilterProps(node, rootErrorSize);
let heatmapStyle: { fill: string | undefined } = {
fill: errorAvgColor
};
let heatmapStyle: Property.Color = errorAvgColor;
if (node.error / node.size > rootLocalError * errorRatioThreshold) {
heatmapStyle = { fill: colorgrad(localErrorPerc) };
heatmapStyle = colorgrad(localErrorPerc) || errorAvgColor;
}
return {
@ -429,13 +419,6 @@ export class TreeViewRenderer extends React.PureComponent<
condition: node.condition,
error: node.error,
errorColor: heatmapStyle,
fillstyleDown: {
transform: `translate(0px, -${calcMaskShift}px)`
},
fillstyleUp: {
fill: ColorPalette.FillStyle,
transform: `translate(0px, ${calcMaskShift}px)`
},
filterProps,
id: node.id,
maskShift: calcMaskShift,
@ -443,7 +426,6 @@ export class TreeViewRenderer extends React.PureComponent<
nodeIndex: node.nodeIndex,
nodeName: node.nodeName,
nodeState: {
errorStyle: undefined,
isSelectedLeaf: false,
onSelectedPath: false,
style: undefined
@ -452,6 +434,7 @@ export class TreeViewRenderer extends React.PureComponent<
parentNodeName: node.parentNodeName,
pathFromRoot: node.pathFromRoot,
r: 28,
rootErrorSize,
size: node.size,
sourceRowKeyHash: node.sourceRowKeyHash,
success: node.success

Просмотреть файл

@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { Property } from "csstype";
import { HierarchyPointNode } from "d3-hierarchy";
import { FilterProps } from "./FilterProps";
@ -24,7 +25,7 @@ export interface INodeDetail {
instanceInfo: string;
errorInfo: string;
successInfo: string;
errorColor: IErrorColorStyle;
errorColor: Property.Color;
maskDown: ITransform;
maskUp: ITransform;
}
@ -46,6 +47,7 @@ export interface ITreeNode {
arg: number;
condition: string;
error: number;
rootErrorSize: number;
id: string;
method: string;
nodeIndex: number;
@ -56,9 +58,7 @@ export interface ITreeNode {
size: number;
sourceRowKeyHash: string;
success: number;
errorColor: IErrorColorStyle;
fillstyleUp: IFillStyleUp;
fillstyleDown: ITransform;
errorColor: Property.Color;
filterProps: FilterProps;
maskShift: number;
r: number;
@ -72,7 +72,6 @@ export interface IFillStyleUp {
// Contains node state that changes with UI clicks
export interface INodeState {
errorStyle: Record<string, number | string | undefined> | undefined;
onSelectedPath: boolean;
isSelectedLeaf: boolean;
style: ITransform | undefined;
@ -81,9 +80,7 @@ export interface INodeState {
export function createInitialTreeViewState(): ITreeViewRendererState {
return {
nodeDetail: {
errorColor: {
fill: "#eaeaea"
},
errorColor: "#eaeaea",
errorInfo: "0 Errors",
globalError: "0",
instanceInfo: "0 Instances",