Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/CD.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ env:
blob_container_for_js: latest
blob_container_for_raiwidget: raiwidgets
blob_path_for_pull_request: ${{ github.event.pull_request.head.repo.full_name }}/${{ github.head_ref }}
node-version: 16.x
node-version: 20.x
widgetDirectory: raiwidgets
raiDirectory: responsibleai
dashboardDirectory: dashboard
Expand Down
3 changes: 1 addition & 2 deletions .github/workflows/CI-rai_core_flask-pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ jobs:
# to avoid having to rerun all jobs several times
fail-fast: false
matrix:
operatingSystem:
[ubuntu-latest, macos-latest, windows-latest]
operatingSystem: [ubuntu-latest, macos-latest, windows-latest]
pythonVersion: ["3.9", "3.10", "3.11"]
exclude:
- operatingSystem: macos-latest
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/CI-typescript.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:

strategy:
matrix:
node-version: [16.x]
node-version: [16.x, 20.x]

steps:
- uses: actions/checkout@v4
Expand Down
Original file line number Diff line number Diff line change
@@ -1,53 +1,57 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { ScatterChart } from "../../../util/ScatterChart";
import { IInterpretData } from "../IInterpretData";

import { describeSubBarChart } from "./describeSubBarChart";
import { describeSubLineChart } from "./describeSubLineChart";

export function describeDataPointChart(dataShape: IInterpretData): void {
describe("Individual datapoints chart", () => {
const props = {
chart: undefined as unknown as ScatterChart,
dataShape
};
beforeEach(() => {
props.chart = new ScatterChart("#IndividualFeatureImportanceChart");
});
it("should render right number of points", () => {
expect(props.chart.Elements.length).equals(dataShape.datapoint);
});

describe("Scatter chart clickable", () => {
it("should select none by default", () => {
cy.get(
'#IndividualFeatureContainer div[class^="legendAndText"] div[class^="clickTarget"]'
).should("not.exist");
});
it("should show message on sub chart", () => {
const message =
!dataShape.noLocalImportance && !dataShape.noFeatureImportance
? "Select a datapoint in the table above to view its local feature importances"
: "Provide local feature importances to see how each feature impacts individual predictions.";
cy.get("#subPlotContainer").should("contain.text", message);
});
it("should select the first point", () => {
props.chart.clickNthPoint(0);
cy.get(
'#IndividualFeatureContainer div[class^="legendAndText"] div[class^="clickTarget"]'
).should("contain.text", "Row");
cy.get("#noPointSelectedInfo").should("not.exist");
props.chart.clickNthPoint(0);
});
});

if (!dataShape.noLocalImportance && !dataShape.noFeatureImportance) {
describeSubBarChart(dataShape);
}
if (!dataShape.noPredict) {
describeSubLineChart(dataShape);
}
});
}
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import { ScatterChart } from "../../../util/ScatterChart";
import { IInterpretData } from "../IInterpretData";

import { describeSubBarChart } from "./describeSubBarChart";
import { describeSubLineChart } from "./describeSubLineChart";

export function describeDataPointChart(dataShape: IInterpretData): void {
describe("Individual datapoints chart", () => {
const props = {
chart: undefined as unknown as ScatterChart,
dataShape
};
beforeEach(() => {
props.chart = new ScatterChart("#IndividualFeatureImportanceChart");
});
it("should render right number of points", () => {
// Wait for the chart to be fully rendered by checking for the scatter plot points
// Using the same selector pattern as ScatterChart.Elements getter
cy.get("#IndividualFeatureImportanceChart .trace.scatter .points path", {
timeout: 10000
}).should("have.length", dataShape.datapoint);
});

describe("Scatter chart clickable", () => {
it("should select none by default", () => {
cy.get(
'#IndividualFeatureContainer div[class^="legendAndText"] div[class^="clickTarget"]'
).should("not.exist");
});
it("should show message on sub chart", () => {
const message =
!dataShape.noLocalImportance && !dataShape.noFeatureImportance
? "Select a datapoint in the table above to view its local feature importances"
: "Provide local feature importances to see how each feature impacts individual predictions.";
cy.get("#subPlotContainer").should("contain.text", message);
});
it("should select the first point", () => {
props.chart.clickNthPoint(0);
cy.get(
'#IndividualFeatureContainer div[class^="legendAndText"] div[class^="clickTarget"]'
).should("contain.text", "Row");
cy.get("#noPointSelectedInfo").should("not.exist");
props.chart.clickNthPoint(0);
});
});

if (!dataShape.noLocalImportance && !dataShape.noFeatureImportance) {
describeSubBarChart(dataShape);
}
if (!dataShape.noPredict) {
describeSubLineChart(dataShape);
}
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Licensed under the MIT License.

export const bostonData = {
datapoint: 102,
datapoint: 103,
datasetBarLabel: ["0 - 20", "21 - 40", "41 - 60", "61 - 80", "81 - 101"],
defaultXAxis: "Index",
defaultYAxis: "CRIM",
Expand All @@ -23,7 +23,7 @@ export const bostonData = {
]
};
export const bostonDataGlobal = {
datapoint: 102,
datapoint: 103,
datasetBarLabel: ["0 - 20", "21 - 40", "41 - 60", "61 - 80", "81 - 101"],
defaultXAxis: "Index",
defaultYAxis: "CRIM",
Expand All @@ -50,7 +50,7 @@ export const bostonDataNoDataset = {
noDataset: true
};
export const bostonDataNoPredict = {
datapoint: 102,
datapoint: 103,
datasetBarLabel: ["0 - 20", "21 - 40", "41 - 60", "61 - 80", "81 - 101"],
featureNames: [
"LSTAT",
Expand All @@ -70,7 +70,7 @@ export const bostonDataNoPredict = {
noPredict: true
};
export const bostonDataNoY = {
datapoint: 102,
datapoint: 103,
datasetBarLabel: ["0 - 20", "21 - 40", "41 - 60", "61 - 80", "81 - 101"],
defaultXAxis: "Index",
defaultYAxis: "CRIM",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const interpretDatasets = {
bostonDataNoPredict,
bostonDataNoY,
breastCancerData: {
datapoint: 114,
datapoint: 115,
datasetBarLabel: ["0 - 22", "23 - 45", "46 - 67", "68 - 90", "91 - 113"],
defaultXAxis: "Index",
defaultYAxis: "mean radius",
Expand Down Expand Up @@ -84,7 +84,7 @@ const interpretDatasets = {
isClassification: true
},
ebmData: {
datapoint: 2,
datapoint: 3,
datasetBarLabel: ["0", "1"],
defaultXAxis: "Index",
defaultYAxis: "Age",
Expand All @@ -93,7 +93,7 @@ const interpretDatasets = {
noY: true
},
ibmData: {
datapoint: 20,
datapoint: 21,
datasetBarLabel: ["0 - 3", "4 - 7", "8 - 11", "12 - 15", "16 - 19"],
defaultXAxis: "Index",
defaultYAxis: "Age",
Expand Down Expand Up @@ -132,7 +132,7 @@ const interpretDatasets = {
isClassification: true
},
ibmDataInconsistent: {
datapoint: 20,
datapoint: 21,
datasetBarLabel: ["0 - 3", "4 - 7", "8 - 11", "12 - 15", "16 - 19"],
defaultXAxis: "Index",
defaultYAxis: "Age",
Expand Down Expand Up @@ -172,7 +172,7 @@ const interpretDatasets = {
]
},
ibmNoClass: {
datapoint: 20,
datapoint: 21,
datasetBarLabel: ["0 - 3", "4 - 7", "8 - 11", "12 - 15", "16 - 19"],
defaultXAxis: "Index",
defaultYAxis: "Age",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const irisData = {
"Class: versicolor": 0.365,
"Class: virginica": 0.236
},
datapoint: 30,
datapoint: 31,
datasetBarLabel: ["0 - 5", "6 - 11", "12 - 17", "18 - 23", "24 - 29"],
defaultXAxis: "Index",
defaultYAxis: "sepal length (cm)",
Expand All @@ -22,7 +22,7 @@ export const irisData = {
isMulticlass: true
};
export const irisDataNoLocal = {
datapoint: 30,
datapoint: 31,
datasetBarLabel: ["0 - 5", "6 - 11", "12 - 17", "18 - 23", "24 - 29"],
defaultXAxis: "Index",
defaultYAxis: "sepal length (cm)",
Expand Down Expand Up @@ -64,7 +64,7 @@ export const irisNoData = {
noY: true
};
export const irisNoFeatures = {
datapoint: 30,
datapoint: 31,
datasetBarLabel: ["0 - 5", "6 - 11", "12 - 17", "18 - 23", "24 - 29"],
defaultXAxis: "Index",
defaultYAxis: "Feature 0",
Expand Down
17 changes: 15 additions & 2 deletions apps/dashboard-e2e/src/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,23 @@
// the project's config changing)

const { preprocessTypescript } = require("@nrwl/cypress/plugins/preprocessor");

// Custom webpack config to ignore CSS files that some dependencies require
// (CSS is not needed for e2e tests) and disable caching for Node 20 compatibility
const customizeWebpackConfig = (webpackConfig) => {
webpackConfig.module.rules.push({
loader: "null-loader",
test: /\.css$/
});
// Disable webpack caching to ensure fresh transpilation
webpackConfig.cache = false;
return webpackConfig;
};

module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config

// Preprocess Typescript file using Nx helper
on("file:preprocessor", preprocessTypescript(config));
// Preprocess Typescript file using Nx helper with custom webpack config
on("file:preprocessor", preprocessTypescript(config, customizeWebpackConfig));
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
"jszip": "3.10.1",
"moment-timezone": "0.5.35",
"node-fetch": "2.6.1",
"null-loader": "^4.0.1",
"patch-package": "^8.0.1",
"postinstall-postinstall": "^2.1.0",
"prettier": "2.3.1",
Expand Down
20 changes: 20 additions & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
const nrwlConfig = require("@nrwl/react/plugins/webpack.js"); // require the main @nrwl/react/plugins/webpack configuration function.
const crypto = require("crypto");

// Check if we need legacy OpenSSL provider workaround for Node 17+
// This sets the hash function to one that works without legacy OpenSSL
const nodeMajorVersion = parseInt(process.versions.node.split(".")[0], 10);
const needsHashWorkaround = nodeMajorVersion >= 17;

module.exports = (config) => {
nrwlConfig(config); // first call it so that it @nrwl/react plugin adds its configs,

// Fix for Node 17+ OpenSSL compatibility issue with webpack 4
// Instead of requiring --openssl-legacy-provider, we use md5 hash which is available
if (needsHashWorkaround) {
// Try to use md4, fall back gracefully
try {
crypto.createHash("md4");
} catch (e) {
// md4 not available, use sha256 instead
const originalCreateHash = crypto.createHash;
crypto.createHash = (algorithm) =>
originalCreateHash(algorithm === "md4" ? "sha256" : algorithm);
}
}

config.node = {
module: "empty",
dgram: "empty",
Expand Down
Loading
Loading