dotdata_widgets 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +19 -7
  2. package/css/colors.css +120 -0
  3. package/css/typography.css +35 -0
  4. package/css/widget.css +53 -3
  5. package/dist/index.js +2 -2
  6. package/lib/components/accordion/Accordion.js +18 -0
  7. package/lib/components/accordion/index.js +1 -0
  8. package/lib/components/input/index.js +1 -0
  9. package/lib/components/input/input.js +6 -0
  10. package/lib/extension.js +1 -14
  11. package/lib/feature-descriptor/feature-details/FeatureCorrelatedFeaturesTable.js +14 -0
  12. package/lib/feature-descriptor/feature-details/FeatureDistributionChart.js +190 -0
  13. package/lib/feature-descriptor/feature-details/FeatureStatisticsTable.js +36 -0
  14. package/lib/feature-descriptor/feature-details/index.js +3 -0
  15. package/lib/feature-descriptor/feature-explanation/FeatureExplanation.js +40 -0
  16. package/lib/feature-descriptor/feature-explanation/components/ColoredExplanationBlock.js +28 -0
  17. package/lib/feature-descriptor/feature-explanation/components/ColumnExplanationBlock.js +4 -0
  18. package/lib/feature-descriptor/feature-explanation/components/DataSlotExplanationBlock.js +4 -0
  19. package/lib/feature-descriptor/feature-explanation/components/PetExplanationBlock.js +3 -0
  20. package/lib/feature-descriptor/feature-explanation/components/TextExplanationBlock.js +2 -0
  21. package/lib/feature-descriptor/feature-explanation/components/TextWithDataSlotContextExplanationBlock.js +2 -0
  22. package/lib/feature-descriptor/feature-explanation/components/TopicExplanationBlock.js +2 -0
  23. package/lib/feature-descriptor/feature-explanation/components/UnknownExplanationBlock.js +2 -0
  24. package/lib/feature-descriptors-domain/exploration-path/exploration-path-header.js +13 -0
  25. package/lib/feature-descriptors-domain/exploration-path/exploration-path-join-list.js +8 -0
  26. package/lib/feature-descriptors-domain/exploration-path/index.js +2 -0
  27. package/lib/feature-descriptors-domain/grouped-domains-descriptions-list.js +47 -0
  28. package/lib/index.js +2 -15
  29. package/lib/models/column/column.js +1 -0
  30. package/lib/models/column/index.js +1 -0
  31. package/lib/models/feature/feature-histogram.js +16 -0
  32. package/lib/models/feature/feature-leaderboard.js +1 -0
  33. package/lib/models/feature/feature.js +12 -0
  34. package/lib/models/feature/index.js +2 -0
  35. package/lib/models/feature-descriptors-domain/fd-domain-description.js +1 -0
  36. package/lib/models/feature-descriptors-domain/fd-grouped-domain-descriptions.js +1 -0
  37. package/lib/models/feature-descriptors-domain/index.js +2 -0
  38. package/lib/models/feature-explanation/feature-explanation.model.js +26 -0
  39. package/lib/models/feature-explanation/index.js +1 -0
  40. package/lib/models/feature-leaderboard/feature-leaderboard.js +1 -0
  41. package/lib/models/feature-leaderboard/index.js +1 -0
  42. package/lib/models/feature-space/feature-space.js +1 -0
  43. package/lib/models/feature-space/index.js +1 -0
  44. package/lib/models/index.js +1 -0
  45. package/lib/plugin.js +7 -29
  46. package/lib/utils/asserations.js +5 -0
  47. package/lib/utils/index.js +3 -0
  48. package/lib/utils/localize.js +14 -0
  49. package/lib/utils/object/extract-property.js +6 -0
  50. package/lib/utils/object/index.js +2 -0
  51. package/lib/utils/object/is-set.js +6 -0
  52. package/lib/version.js +2 -6
  53. package/lib/widgets/FeatureLeaderboardWidget.js +63 -0
  54. package/lib/widgets/FeatureSpaceWidget.js +50 -0
  55. package/lib/widgets/feature-leaderboard/FeatureLeaderboardEntries.js +10 -0
  56. package/lib/widgets/feature-leaderboard/FeatureLeaderboardOverview.js +20 -0
  57. package/lib/widgets/feature-leaderboard/FeatureLeaderboardView.js +19 -0
  58. package/lib/widgets/feature-leaderboard/entry-item/FeatureLeaderboardEntryDetails.js +15 -0
  59. package/lib/widgets/feature-leaderboard/entry-item/FeatureLeaderboardEntryItem.js +20 -0
  60. package/lib/widgets/feature-space/FeatureExplorationPaths.js +37 -0
  61. package/lib/widgets/feature-space/FeatureSpaceDomainsDescriptions.js +53 -0
  62. package/lib/widgets/feature-space/FeatureSpaceView.js +9 -0
  63. package/lib/widgets/index.js +4 -0
  64. package/package.json +60 -37
package/lib/plugin.js CHANGED
@@ -1,50 +1,28 @@
1
- "use strict";
2
1
  // Copyright (c) dotdata
3
2
  // Distributed under the terms of the Modified BSD License.
4
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
- if (k2 === undefined) k2 = k;
6
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
7
- }) : (function(o, m, k, k2) {
8
- if (k2 === undefined) k2 = k;
9
- o[k2] = m[k];
10
- }));
11
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
12
- Object.defineProperty(o, "default", { enumerable: true, value: v });
13
- }) : function(o, v) {
14
- o["default"] = v;
15
- });
16
- var __importStar = (this && this.__importStar) || function (mod) {
17
- if (mod && mod.__esModule) return mod;
18
- var result = {};
19
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
20
- __setModuleDefault(result, mod);
21
- return result;
22
- };
23
- Object.defineProperty(exports, "__esModule", { value: true });
24
- const base_1 = require("@jupyter-widgets/base");
25
- const widgetExports = __importStar(require("./widget"));
26
- const version_1 = require("./version");
3
+ import { IJupyterWidgetRegistry } from '@jupyter-widgets/base';
4
+ import * as widgetExports from './widgets';
5
+ import { MODULE_NAME, MODULE_VERSION } from './version';
27
6
  const EXTENSION_ID = 'dotdata_widgets:plugin';
28
7
  /**
29
8
  * The example plugin.
30
9
  */
31
10
  const examplePlugin = {
32
11
  id: EXTENSION_ID,
33
- requires: [base_1.IJupyterWidgetRegistry],
12
+ requires: [IJupyterWidgetRegistry],
34
13
  activate: activateWidgetExtension,
35
14
  autoStart: true,
36
15
  };
37
16
  // the "as unknown as ..." typecast above is solely to support JupyterLab 1
38
17
  // and 2 in the same codebase and should be removed when we migrate to Lumino.
39
- exports.default = examplePlugin;
18
+ export default examplePlugin;
40
19
  /**
41
20
  * Activate the widget extension.
42
21
  */
43
22
  function activateWidgetExtension(app, registry) {
44
23
  registry.registerWidget({
45
- name: version_1.MODULE_NAME,
46
- version: version_1.MODULE_VERSION,
24
+ name: MODULE_NAME,
25
+ version: MODULE_VERSION,
47
26
  exports: widgetExports,
48
27
  });
49
28
  }
50
- //# sourceMappingURL=plugin.js.map
@@ -0,0 +1,5 @@
1
+ export function assertIsSet(obj, message) {
2
+ if (obj === undefined || obj === null) {
3
+ throw new Error(message ?? `Expected ${obj} to be defined`);
4
+ }
5
+ }
@@ -0,0 +1,3 @@
1
+ export * from './asserations';
2
+ export * from './object';
3
+ export * from './localize';
@@ -0,0 +1,14 @@
1
+ import { isSet } from './object';
2
+ const numberDefaultFormatter = new Intl.NumberFormat(navigator.language, {
3
+ maximumFractionDigits: 3,
4
+ useGrouping: false,
5
+ });
6
+ export var Localize;
7
+ (function (Localize) {
8
+ function formatNumber(value, unsetSymbol) {
9
+ return isSet(value)
10
+ ? numberDefaultFormatter.format(value)
11
+ : unsetSymbol ?? '';
12
+ }
13
+ Localize.formatNumber = formatNumber;
14
+ })(Localize || (Localize = {}));
@@ -0,0 +1,6 @@
1
+ // eslint-disable-next-line @typescript-eslint/ban-types
2
+ export function extractProperty(property) {
3
+ return function extractFrom(source) {
4
+ return source[property];
5
+ };
6
+ }
@@ -0,0 +1,2 @@
1
+ export * from './is-set';
2
+ export * from './extract-property';
@@ -0,0 +1,6 @@
1
+ export function isSet(obj) {
2
+ return obj !== undefined && obj !== null;
3
+ }
4
+ export function isNotSet(obj) {
5
+ return obj === undefined || obj === null;
6
+ }
package/lib/version.js CHANGED
@@ -1,8 +1,5 @@
1
- "use strict";
2
1
  // Copyright (c) dotdata
3
2
  // Distributed under the terms of the Modified BSD License.
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.MODULE_NAME = exports.MODULE_VERSION = void 0;
6
3
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
7
4
  // @ts-ignore
8
5
  // eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -13,9 +10,8 @@ const data = require('../package.json');
13
10
  * The html widget manager assumes that this is the same as the npm package
14
11
  * version number.
15
12
  */
16
- exports.MODULE_VERSION = data.version;
13
+ export const MODULE_VERSION = data.version;
17
14
  /*
18
15
  * The current package name.
19
16
  */
20
- exports.MODULE_NAME = data.name;
21
- //# sourceMappingURL=version.js.map
17
+ export const MODULE_NAME = data.name;
@@ -0,0 +1,63 @@
1
+ // Copyright (c) dotdata
2
+ // Distributed under the terms of the Modified BSD License.
3
+ import React from 'react';
4
+ import { ReactWidget, UseSignal } from '@jupyterlab/apputils';
5
+ import { DOMWidgetModel, DOMWidgetView, } from '@jupyter-widgets/base';
6
+ import { Signal } from '@lumino/signaling';
7
+ import { MODULE_NAME, MODULE_VERSION } from '../version';
8
+ import { FeatureLeaderboardView } from './feature-leaderboard/FeatureLeaderboardView';
9
+ export class FeatureLeaderboardWidgetModel extends DOMWidgetModel {
10
+ defaults() {
11
+ return {
12
+ ...super.defaults(),
13
+ _model_name: FeatureLeaderboardWidgetModel.model_name,
14
+ _model_module: FeatureLeaderboardWidgetModel.model_module,
15
+ _model_module_version: FeatureLeaderboardWidgetModel.model_module_version,
16
+ _view_name: FeatureLeaderboardWidgetModel.view_name,
17
+ _view_module: FeatureLeaderboardWidgetModel.view_module,
18
+ _view_module_version: FeatureLeaderboardWidgetModel.view_module_version,
19
+ value: { allEntries: [] },
20
+ confidence: 0.95,
21
+ max_collinearity: 0.95,
22
+ };
23
+ }
24
+ }
25
+ FeatureLeaderboardWidgetModel.serializers = {
26
+ ...DOMWidgetModel.serializers,
27
+ };
28
+ FeatureLeaderboardWidgetModel.model_name = 'FeatureLeaderboardWidgetModel';
29
+ FeatureLeaderboardWidgetModel.model_module = MODULE_NAME;
30
+ FeatureLeaderboardWidgetModel.model_module_version = MODULE_VERSION;
31
+ FeatureLeaderboardWidgetModel.view_name = 'FeatureLeaderboardWidgetView'; // Set to null if no view
32
+ FeatureLeaderboardWidgetModel.view_module = MODULE_NAME; // Set to null if no view
33
+ FeatureLeaderboardWidgetModel.view_module_version = MODULE_VERSION;
34
+ export class FeatureLeaderboardWidgetView extends DOMWidgetView {
35
+ constructor() {
36
+ super(...arguments);
37
+ this.signal = new Signal(this);
38
+ this.luminoWidget = ReactWidget.create(React.createElement("div", { className: "dotdata-widget" },
39
+ React.createElement(UseSignal, { signal: this.signal }, (_, signalData) => signalData?.value ? (React.createElement(FeatureLeaderboardView, { featureLeaderboard: signalData.value, maxCollinearity: signalData.max_collinearity, confidence: signalData.confidence, setConfidence: this.onValueChange('confidence'), setMaxCollinearity: this.onValueChange('max_collinearity') })) : null)));
40
+ }
41
+ render() {
42
+ this.model.on('change:confidence', this.onModelChange, this);
43
+ this.model.on('change:max_collinearity', this.onModelChange, this);
44
+ this.model.on('change:value', this.onModelChange, this);
45
+ setTimeout(() => {
46
+ this.onModelChange();
47
+ }, 1000);
48
+ }
49
+ onModelChange() {
50
+ const { value, confidence, max_collinearity } = this.model.get_state(false);
51
+ this.signal.emit({
52
+ value,
53
+ confidence,
54
+ max_collinearity,
55
+ });
56
+ }
57
+ onValueChange(propName) {
58
+ return (value) => {
59
+ this.model.set(propName, value);
60
+ this.model.save_changes();
61
+ };
62
+ }
63
+ }
@@ -0,0 +1,50 @@
1
+ // Copyright (c) dotdata
2
+ // Distributed under the terms of the Modified BSD License.
3
+ import React from 'react';
4
+ import { ReactWidget, UseSignal } from '@jupyterlab/apputils';
5
+ import { DOMWidgetModel, DOMWidgetView, } from '@jupyter-widgets/base';
6
+ import { Signal } from '@lumino/signaling';
7
+ import { MODULE_NAME, MODULE_VERSION } from '../version';
8
+ import { FeatureSpaceView } from './feature-space/FeatureSpaceView';
9
+ export class FeatureSpaceWidgetModel extends DOMWidgetModel {
10
+ defaults() {
11
+ return {
12
+ ...super.defaults(),
13
+ _model_name: FeatureSpaceWidgetModel.model_name,
14
+ _model_module: FeatureSpaceWidgetModel.model_module,
15
+ _model_module_version: FeatureSpaceWidgetModel.model_module_version,
16
+ _view_name: FeatureSpaceWidgetModel.view_name,
17
+ _view_module: FeatureSpaceWidgetModel.view_module,
18
+ _view_module_version: FeatureSpaceWidgetModel.view_module_version,
19
+ value: undefined,
20
+ };
21
+ }
22
+ }
23
+ FeatureSpaceWidgetModel.serializers = {
24
+ ...DOMWidgetModel.serializers,
25
+ };
26
+ FeatureSpaceWidgetModel.model_name = 'FeatureSpaceWidgetModel';
27
+ FeatureSpaceWidgetModel.model_module = MODULE_NAME;
28
+ FeatureSpaceWidgetModel.model_module_version = MODULE_VERSION;
29
+ FeatureSpaceWidgetModel.view_name = 'FeatureSpaceWidgetView'; // Set to null if no view
30
+ FeatureSpaceWidgetModel.view_module = MODULE_NAME; // Set to null if no view
31
+ FeatureSpaceWidgetModel.view_module_version = MODULE_VERSION;
32
+ export class FeatureSpaceWidgetView extends DOMWidgetView {
33
+ constructor() {
34
+ super(...arguments);
35
+ this.signal = new Signal(this);
36
+ this.luminoWidget = ReactWidget.create(React.createElement("div", { className: "dotdata-widget" },
37
+ React.createElement(UseSignal, { signal: this.signal }, (_, signalData) => signalData?.value ? (React.createElement(FeatureSpaceView, { featureSpace: signalData?.value })) : null)));
38
+ }
39
+ render() {
40
+ this.model.on('change:value', this.onModelChange, this);
41
+ setTimeout(() => {
42
+ this.onModelChange();
43
+ }, 1000);
44
+ }
45
+ onModelChange() {
46
+ this.signal.emit({
47
+ value: this.model.get('value'),
48
+ });
49
+ }
50
+ }
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { Accordion, AccordionHeader, AccordionDetails, } from '../../components/accordion';
3
+ import { FeatureExplanation } from '../../feature-descriptor/feature-explanation/FeatureExplanation';
4
+ import { FeatureLeaderboardEntryItem } from './entry-item/FeatureLeaderboardEntryItem';
5
+ export const FeatureLeaderboardEntries = ({ entriesGroups }) => {
6
+ return (React.createElement(React.Fragment, null, entriesGroups.map((entriesGroup, groupIdx) => (React.createElement(Accordion, { key: groupIdx, collapsedDetailsStyle: { padding: '0' }, expandedDetailsStyle: { padding: '0' }, expandedHeaderStyle: { background: '#F0F0F0' }, initialState: true },
7
+ React.createElement(AccordionHeader, null,
8
+ React.createElement(FeatureExplanation, { explanationBlocks: entriesGroup[0].feature.explanation.tokens })),
9
+ React.createElement(AccordionDetails, null, entriesGroup.map(entry => (React.createElement(FeatureLeaderboardEntryItem, { key: entry.feature.id, featureEntry: entry })))))))));
10
+ };
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { Input } from '../../components/input';
3
+ const sliderRowStyle = {
4
+ display: 'flex',
5
+ alignItems: 'center',
6
+ gap: '6px',
7
+ };
8
+ const maxCollinearityTooltip = 'Maximum correlation of any two features on the list';
9
+ const confidenceTooltip = 'The probability that a feature is better than a random feature';
10
+ export const FeatureLeaderboardOverview = ({ confidence, setConfidence, maxCollinearity, setMaxCollinearity }) => {
11
+ return (React.createElement("div", { style: { display: 'flex', gap: '40px', flexWrap: 'wrap' } },
12
+ React.createElement("label", { style: sliderRowStyle, htmlFor: "maxCollinearitySlider" },
13
+ React.createElement("span", { className: "grey-label label-bold", title: maxCollinearityTooltip }, "Max collinearity:"),
14
+ React.createElement(Input, { id: "maxCollinearitySlider", type: "range", min: 0.0, max: 1.0, step: 0.01, list: "sliderEdgeValues", value: maxCollinearity, onValueChange: v => setMaxCollinearity(Number(v)) }),
15
+ React.createElement(Input, { inputSize: "small", type: "number", min: 0.0, max: 1.0, step: 0.01, value: maxCollinearity, onValueChange: v => setMaxCollinearity(Number(v)) })),
16
+ React.createElement("label", { style: sliderRowStyle, htmlFor: "confidenceSlider" },
17
+ React.createElement("span", { className: "grey-label label-bold", title: confidenceTooltip }, "Confidence:"),
18
+ React.createElement(Input, { id: "confidenceSlider", type: "range", min: 0.0, max: 1.0, step: 0.01, list: "sliderEdgeValues", value: confidence, onValueChange: v => setConfidence(Number(v)) }),
19
+ React.createElement(Input, { inputSize: "small", type: "number", min: 0.0, max: 1.0, step: 0.01, value: confidence, onValueChange: v => setConfidence(Number(v)) }))));
20
+ };
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { FeatureLeaderboardOverview } from './FeatureLeaderboardOverview';
3
+ import { FeatureLeaderboardEntryItem } from './entry-item/FeatureLeaderboardEntryItem';
4
+ export const FeatureLeaderboardView = ({ featureLeaderboard, setConfidence, confidence, maxCollinearity, setMaxCollinearity, }) => {
5
+ const featureEntries = React.useMemo(() => filterFeatures(featureLeaderboard, maxCollinearity, confidence), [maxCollinearity, confidence, featureLeaderboard]);
6
+ return (React.createElement(React.Fragment, null,
7
+ React.createElement("h2", { className: "grey-label" }, "Feature Pipeline Overview:"),
8
+ React.createElement(FeatureLeaderboardOverview, { confidence: confidence, setConfidence: setConfidence, maxCollinearity: maxCollinearity, setMaxCollinearity: setMaxCollinearity }),
9
+ React.createElement("br", null),
10
+ featureEntries.map(featureEntry => (React.createElement(FeatureLeaderboardEntryItem, { key: featureEntry.feature.id, featureEntry: featureEntry })))));
11
+ };
12
+ function filterFeatures(featureLeaderboard, maxCollinearity, confidence) {
13
+ const fulfillCollinearity = (entry) => entry.maxAbsCorrelationOfSimplerFeature < maxCollinearity;
14
+ const fulfillNoise = (entry) => entry.signalConfidence >= confidence;
15
+ return featureLeaderboard.allEntries
16
+ .flat()
17
+ .filter(fulfillCollinearity)
18
+ .filter(fulfillNoise);
19
+ }
@@ -0,0 +1,15 @@
1
+ import React from 'react';
2
+ import { FeatureStatisticsTable, FeatureDistributionChart, FeatureCorrelatedFeaturesTable, } from '../../../feature-descriptor/feature-details';
3
+ export const FeatureLeaderboardEntryDetails = ({ entry }) => {
4
+ return (React.createElement("div", null,
5
+ React.createElement("div", { style: { display: 'flex', gap: '50px' } },
6
+ React.createElement("div", { className: "feature-metrics", style: { flex: 3 } },
7
+ React.createElement("h3", { className: "grey-label" }, "Feature Statistics:"),
8
+ React.createElement(FeatureStatisticsTable, { statistics: entry.stats })),
9
+ React.createElement("div", { className: "feature-histogram", style: { flex: 1 } },
10
+ React.createElement("h3", { className: "grey-label" }, "Feature Distribution:"),
11
+ React.createElement(FeatureDistributionChart, { histogram: entry.histogram }))),
12
+ React.createElement("div", { className: "correlated-features" },
13
+ React.createElement("h3", { className: "grey-label" }, "Correlated Features:"),
14
+ React.createElement(FeatureCorrelatedFeaturesTable, { correlatedFeatures: entry.topCorrelatedFeatures }))));
15
+ };
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { Accordion, AccordionHeader, AccordionDetails, } from '../../../components/accordion';
3
+ import { FeatureExplanation } from '../../../feature-descriptor/feature-explanation/FeatureExplanation';
4
+ import { FeatureLeaderboardEntryDetails } from './FeatureLeaderboardEntryDetails';
5
+ const featureNameLabelStyle = {
6
+ color: 'var(--c-grey-600)',
7
+ display: 'inline-block',
8
+ minWidth: '5rem',
9
+ };
10
+ export const FeatureLeaderboardEntryItem = ({ featureEntry }) => {
11
+ return (React.createElement(Accordion, { expandedDetailsStyle: {
12
+ borderBottom: '1px solid var(--c-grey-500)',
13
+ paddingBlockEnd: '30px',
14
+ } },
15
+ React.createElement(AccordionHeader, null,
16
+ React.createElement("span", { className: "label-bold", style: featureNameLabelStyle }, featureEntry.feature.id),
17
+ React.createElement(FeatureExplanation, { key: featureEntry.feature.id, explanationBlocks: featureEntry.feature.explanation.tokens })),
18
+ React.createElement(AccordionDetails, null,
19
+ React.createElement(FeatureLeaderboardEntryDetails, { entry: featureEntry }))));
20
+ };
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ const FeatureExplorationPathItem = props => {
3
+ return (React.createElement("div", null,
4
+ React.createElement("div", { style: { display: 'flex', alignItems: 'baseline' } },
5
+ React.createElement("h3", { className: "grey-label", style: { minWidth: '185px' } },
6
+ "Exploration Path [#",
7
+ props.explorationPathIndex,
8
+ "]"),
9
+ React.createElement("div", null,
10
+ props.explorationPath.targetTable,
11
+ "[",
12
+ React.createElement("span", { style: {
13
+ color: 'var(--c-blue-700)',
14
+ fontWeight: '500',
15
+ } }, props.explorationPath.targetColumns.join(', ')),
16
+ "] - ",
17
+ props.explorationPath.sourceTable,
18
+ "[",
19
+ React.createElement("span", { style: {
20
+ color: 'var(--c-blue-700)',
21
+ fontWeight: '500',
22
+ } }, props.explorationPath.sourceColumns.join(', ')),
23
+ "]")),
24
+ React.createElement("div", { style: { paddingLeft: '16px' } },
25
+ React.createElement("p", { className: "grey-label" }, "Joins:"),
26
+ props.explorationPath.joins.map(join => (React.createElement("div", { key: join.joinId },
27
+ "[",
28
+ join.joinId,
29
+ "] ",
30
+ join.description,
31
+ " (",
32
+ join.numFeatures,
33
+ " features)"))))));
34
+ };
35
+ export const FeatureExplorationPaths = props => {
36
+ return (React.createElement(React.Fragment, null, props.explorationPaths.map((explorationPath, idx) => (React.createElement(FeatureExplorationPathItem, { key: idx, explorationPathIndex: idx, explorationPath: explorationPath })))));
37
+ };
@@ -0,0 +1,53 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { Accordion, AccordionDetails, AccordionHeader, } from '../../components/accordion';
3
+ import { Input } from '../../components/input';
4
+ import { GroupedDomainsDescriptionsList } from '../../feature-descriptors-domain/grouped-domains-descriptions-list';
5
+ const searchInputStyle = {
6
+ width: '70%',
7
+ marginTop: '4px',
8
+ marginBottom: '16px',
9
+ };
10
+ export const FeatureSpaceDomainsDescriptions = props => {
11
+ const [aggregationSearch, setAggregationSearch] = useState(() => '');
12
+ const [filterSearch, setFilterSearch] = useState(() => '');
13
+ const [searchedAggregation, setSearchedAggregation] = useState(() => props.aggregations);
14
+ const [searchedFilters, setSearchedFilters] = useState(() => props.filters);
15
+ useEffect(() => {
16
+ const aggregations = filterDomainDescriptions(props.aggregations, aggregationSearch);
17
+ setSearchedAggregation(aggregations);
18
+ }, [aggregationSearch]);
19
+ useEffect(() => {
20
+ const filters = filterDomainDescriptions(props.filters, filterSearch);
21
+ setSearchedFilters(filters);
22
+ }, [filterSearch]);
23
+ return (React.createElement("div", null,
24
+ React.createElement(Accordion, null,
25
+ React.createElement(AccordionHeader, null,
26
+ React.createElement("h3", { className: "grey-label" }, "Filters and Aggregations")),
27
+ React.createElement(AccordionDetails, null,
28
+ React.createElement("div", { style: { display: 'flex', marginBottom: '0.5rem' } },
29
+ React.createElement("div", { style: { width: '50%' } },
30
+ React.createElement("div", { className: "grey-label" }, "Filters"),
31
+ React.createElement(Input, { style: searchInputStyle, value: filterSearch, placeholder: "Search:", onValueChange: setFilterSearch }),
32
+ React.createElement(GroupedDomainsDescriptionsList, { groupedDomain: searchedFilters })),
33
+ React.createElement("div", { style: { width: '50%' } },
34
+ React.createElement("div", { className: "grey-label" }, "Aggregations"),
35
+ React.createElement(Input, { style: searchInputStyle, value: aggregationSearch, placeholder: "Search:", onValueChange: setAggregationSearch }),
36
+ React.createElement(GroupedDomainsDescriptionsList, { groupedDomain: searchedAggregation })))))));
37
+ };
38
+ const isNotEmpty = (arr) => arr.length > 0;
39
+ function filterDomainDescriptions(domains, searchPhrase) {
40
+ return {
41
+ types: domains.types
42
+ .map(({ summary, columns }) => ({
43
+ summary,
44
+ columns: columns
45
+ .map(column => ({
46
+ summary: column.summary,
47
+ descriptions: column.descriptions.filter(({ description }) => description.toLowerCase().includes(searchPhrase.toLowerCase())),
48
+ }))
49
+ .filter(({ descriptions }) => isNotEmpty(descriptions)),
50
+ }))
51
+ .filter(({ columns }) => isNotEmpty(columns)),
52
+ };
53
+ }
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { FeatureSpaceDomainsDescriptions } from './FeatureSpaceDomainsDescriptions';
3
+ import { FeatureExplorationPaths } from './FeatureExplorationPaths';
4
+ export const FeatureSpaceView = props => {
5
+ return (React.createElement(React.Fragment, null,
6
+ React.createElement("h2", { className: "grey-label" }, "Feature Space Overview:"),
7
+ props.featureSpace.explorationPaths ? (React.createElement(FeatureExplorationPaths, { explorationPaths: props.featureSpace.explorationPaths })) : null,
8
+ props.featureSpace.filters ? (React.createElement(FeatureSpaceDomainsDescriptions, { filters: props.featureSpace.filters, aggregations: props.featureSpace.aggregations })) : null));
9
+ };
@@ -0,0 +1,4 @@
1
+ // Import the CSS
2
+ import '../../css/widget.css';
3
+ export * from './FeatureLeaderboardWidget';
4
+ export * from './FeatureSpaceWidget';
package/package.json CHANGED
@@ -1,21 +1,22 @@
1
1
  {
2
2
  "name": "dotdata_widgets",
3
- "version": "0.1.0",
4
- "description": "A Custom Jupyter Widget Library",
3
+ "version": "0.1.1",
4
+ "description": "A dotdata widget",
5
5
  "keywords": [
6
+ "dotdata",
7
+ "widgets",
6
8
  "jupyter",
7
9
  "jupyterlab",
8
- "jupyterlab-extension",
9
- "widgets"
10
+ "jupyterlab-extension"
10
11
  ],
11
12
  "files": [
12
13
  "lib/**/*.js",
13
14
  "dist/*.js",
14
15
  "css/*.css"
15
16
  ],
16
- "homepage": "https://github.com/dotdata/dotdata_widgets",
17
+ "homepage": "https://github.com/ramencloud/dotdata-core",
17
18
  "bugs": {
18
- "url": "https://github.com/dotdata/dotdata_widgets/issues"
19
+ "url": "https://github.com/ramencloud/dotdata-core/issues"
19
20
  },
20
21
  "license": "BSD-3-Clause",
21
22
  "author": {
@@ -26,14 +27,14 @@
26
27
  "types": "./lib/index.d.ts",
27
28
  "repository": {
28
29
  "type": "git",
29
- "url": "https://github.com/dotdata/dotdata_widgets"
30
+ "url": "https://github.com/ramencloud/dotdata-core"
30
31
  },
31
32
  "scripts": {
32
33
  "build": "yarn run build:lib && yarn run build:nbextension && yarn run build:labextension:dev",
33
34
  "build:prod": "yarn run build:lib && yarn run build:nbextension && yarn run build:labextension",
34
35
  "build:labextension": "jupyter labextension build .",
35
36
  "build:labextension:dev": "jupyter labextension build --development True .",
36
- "build:lib": "tsc",
37
+ "build:lib": "tsc && tsc-alias",
37
38
  "build:nbextension": "webpack",
38
39
  "clean": "yarn run clean:lib && yarn run clean:nbextension && yarn run clean:labextension",
39
40
  "clean:lib": "rimraf lib",
@@ -44,43 +45,65 @@
44
45
  "prepack": "yarn run build:lib",
45
46
  "test": "jest",
46
47
  "watch": "npm-run-all -p watch:*",
47
- "watch:lib": "tsc -w",
48
+ "watch:lib": "concurrently \"tsc -w\" \"tsc-alias -w\"",
48
49
  "watch:nbextension": "webpack --watch --mode=development",
49
50
  "watch:labextension": "jupyter labextension watch ."
50
51
  },
51
52
  "dependencies": {
52
- "@jupyter-widgets/base": "^1.1.10 || ^2 || ^3 || ^4 || ^5 || ^6"
53
+ "@fontsource/roboto": "^4.5.8",
54
+ "@jupyter-widgets/base": "^1.1.10 || ^2 || ^3 || ^4 || ^5 || ^6",
55
+ "@jupyterlab/application": "^3.5.2",
56
+ "react": "18.2.0",
57
+ "react-dom": "18.2.0",
58
+ "vega": "^5.22.1"
53
59
  },
54
60
  "devDependencies": {
55
- "@babel/core": "^7.5.0",
56
- "@babel/preset-env": "^7.5.0",
57
- "@jupyter-widgets/base-manager": "^1.0.2",
58
- "@jupyterlab/builder": "^3.0.0",
59
- "@lumino/application": "^1.6.0",
60
- "@lumino/widgets": "^1.6.0",
61
- "@types/jest": "^26.0.0",
62
- "@types/webpack-env": "^1.13.6",
63
- "@typescript-eslint/eslint-plugin": "^3.6.0",
64
- "@typescript-eslint/parser": "^3.6.0",
65
- "acorn": "^7.2.0",
66
- "css-loader": "^3.2.0",
67
- "eslint": "^7.4.0",
68
- "eslint-config-prettier": "^6.11.0",
69
- "eslint-plugin-prettier": "^3.1.4",
70
- "fs-extra": "^7.0.0",
61
+ "@babel/core": "^7.20.12",
62
+ "@babel/preset-env": "^7.20.2",
63
+ "@babel/preset-react": "^7.18.6",
64
+ "@babel/preset-typescript": "^7.18.6",
65
+ "@jupyter-widgets/base-manager": "^1.0.3",
66
+ "@jupyterlab/builder": "^3.0.9",
67
+ "@lumino/application": "^1.31.3",
68
+ "@lumino/widgets": "^1.37.1",
69
+ "@types/jest": "^26.0.24",
70
+ "@types/react": "^18.0.27",
71
+ "@types/react-dom": "18.0.10",
72
+ "@types/webpack-env": "^1.18.0",
73
+ "@typescript-eslint/eslint-plugin": "^3.10.1",
74
+ "@typescript-eslint/parser": "^3.10.1",
75
+ "acorn": "^7.4.1",
76
+ "babel-loader": "^9.1.2",
77
+ "concurrently": "^7.6.0",
78
+ "css-loader": "^3.6.0",
79
+ "eslint": "^7.32.0",
80
+ "eslint-config-prettier": "^6.15.0",
81
+ "eslint-plugin-prettier": "^3.4.1",
82
+ "file-loader": "^6.2.0",
83
+ "fs-extra": "^7.0.1",
71
84
  "identity-obj-proxy": "^3.0.0",
72
- "jest": "^26.0.0",
73
- "mkdirp": "^0.5.1",
74
- "npm-run-all": "^4.1.3",
75
- "prettier": "^2.0.5",
76
- "rimraf": "^2.6.2",
85
+ "jest": "^26.6.3",
86
+ "mkdirp": "^0.5.6",
87
+ "npm-run-all": "^4.1.5",
88
+ "prettier": "^2.8.4",
89
+ "rimraf": "^2.6.3",
77
90
  "source-map-loader": "^1.1.3",
78
- "style-loader": "^1.0.0",
79
- "ts-jest": "^26.0.0",
80
- "ts-loader": "^8.0.0",
81
- "typescript": "~4.1.3",
82
- "webpack": "^5.61.0",
83
- "webpack-cli": "^4.0.0"
91
+ "style-loader": "^1.3.0",
92
+ "ts-jest": "^26.5.6",
93
+ "ts-loader": "^8.4.0",
94
+ "tsc-alias": "^1.8.2",
95
+ "tsconfig-paths-webpack-plugin": "^4.0.0",
96
+ "typescript": "~4.9.5",
97
+ "url-loader": "^4.1.1",
98
+ "webpack": "^5.69.1",
99
+ "webpack-cli": "^4.10.0"
100
+ },
101
+ "babel": {
102
+ "presets": [
103
+ "@babel/preset-env",
104
+ "@babel/preset-react",
105
+ "@babel/preset-typescript"
106
+ ]
84
107
  },
85
108
  "jupyterlab": {
86
109
  "extension": "lib/plugin",