Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preview dataset #1288

Merged
merged 47 commits into from
Mar 24, 2023
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
007f7c2
set up preview in response and flowchart.py
Huongg Mar 13, 2023
0ff46cf
return preview for metaData
Huongg Mar 13, 2023
e469560
filter data and render the table
Huongg Mar 14, 2023
38e641c
add preview-table component
Huongg Mar 15, 2023
4fd5136
fix styling for table in metadata panel
Huongg Mar 15, 2023
6ca4ec4
add previewTable to metadata-modal
Huongg Mar 15, 2023
36931d0
different theme for preview table
Huongg Mar 15, 2023
2abe3a6
add classname for preview-table
Huongg Mar 15, 2023
85dda7c
add size for PreviewTable
Huongg Mar 16, 2023
6aa6b6e
add cursor pointer
Huongg Mar 16, 2023
9a6eae7
styling for row hover state
Huongg Mar 16, 2023
dc19dd1
light and dark theme for hovering
Huongg Mar 17, 2023
d41b4f6
include excel and parquet dataset
Huongg Mar 17, 2023
5d775cf
Merge branch 'main' of github.com:kedro-org/kedro-viz into preview-da…
Huongg Mar 17, 2023
6e143f9
add margin for table large
Huongg Mar 17, 2023
de652bd
check if self.type is in preview_datasets
Huongg Mar 17, 2023
20bcefd
remove preview table style
Huongg Mar 17, 2023
6a90f53
add preview text
Huongg Mar 17, 2023
a7c07b0
Adding test for preview table
Huongg Mar 17, 2023
e7b1a56
adding condition to not call _preview if not existed
Huongg Mar 20, 2023
2ce39d0
move the hasAttr inside the previewDataSet loops
Huongg Mar 20, 2023
c6ec97a
update light theme colour for highlighting
Huongg Mar 20, 2023
0a6c107
onclick handler when clicking on small table
Huongg Mar 20, 2023
4c4a2a1
update release note
Huongg Mar 20, 2023
7990f5a
remove highlighting row in small table
Huongg Mar 20, 2023
3d1de36
update previewing message
Huongg Mar 20, 2023
1f578a5
update variable names
Huongg Mar 20, 2023
e5fab1d
pull changes from remote branch
Huongg Mar 20, 2023
15e61d4
Merge branch 'main' into preview-dataset
Huongg Mar 20, 2023
9869229
ignore updateContent file
Huongg Mar 21, 2023
bc7a12c
formatting
Huongg Mar 21, 2023
a772729
test_data_node_metadata_preview for flowchart.py
Huongg Mar 21, 2023
ed13b44
remove parquet dataset preview
Huongg Mar 21, 2023
bc25c3e
restructure data in preview table
Huongg Mar 22, 2023
e446fdd
update name to onExpandMetaDataClick
Huongg Mar 22, 2023
c726a7b
restructure the flowchart.py for _preview
Huongg Mar 22, 2023
36b7c66
update test to reflect the new data structure
Huongg Mar 22, 2023
3658109
adding test for flowchart.py
Huongg Mar 22, 2023
538cf9c
downgrade mypy package
Huongg Mar 22, 2023
63b0b7d
formatting
Huongg Mar 22, 2023
4f558c7
include # pylint: disable=attr-defined for _preview
Huongg Mar 22, 2023
8d5ed2a
include # type: ignore
Huongg Mar 22, 2023
1244076
include ignore in response
Huongg Mar 22, 2023
e3f7924
update wrong test name
Huongg Mar 23, 2023
9b89c6c
sticky header for preview table
Huongg Mar 23, 2023
0455310
feature flag and connect the preview data with config table
Huongg Mar 23, 2023
3d54783
use more generic classname for metadata modal
Huongg Mar 23, 2023
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
1 change: 1 addition & 0 deletions package/kedro_viz/api/rest/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class DataNodeMetadataAPIResponse(BaseAPIResponse):
image: Optional[str]
tracking_data: Optional[Dict]
run_command: Optional[str]
preview: Optional[Dict]

class Config:
schema_extra = {
Expand Down
10 changes: 10 additions & 0 deletions package/kedro_viz/models/flowchart.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

logger = logging.getLogger(__name__)

PREVIEW_DATASETS = ["pandas.csv_dataset.CSVDataSet",
"pandas.parquet_dataset.ParquetDataSet", "pandas.excel_dataset.ExcelDataSet"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Supporting Spark and launch would be a really nice stretch goal, but not a dealbreaker



def _pretty_name(name: str) -> str:
name = name.replace("-", " ").replace("_", " ").replace(":", ": ")
Expand Down Expand Up @@ -555,13 +558,20 @@ class DataNodeMetadata(GraphNodeMetadata):
# command to run the pipeline to this data node
run_command: Optional[str] = field(init=False, default=None)

preview: Optional[Dict] = field(init=False, default=None)

# TODO: improve this scheme.
def __post_init__(self, data_node: DataNode):
self.type = data_node.dataset_type
dataset = cast(AbstractDataSet, data_node.kedro_obj)
dataset_description = dataset._describe()
self.filepath = _parse_filepath(dataset_description)

if self.type in PREVIEW_DATASETS:
# If the kedro-datasets is on the latest and does have the _preview
if (hasattr(dataset, '_preview')):
self.preview = dataset._preview(40)
Copy link
Contributor

@datajoely datajoely Mar 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not make this configurable here?
image

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on our telemetry, hardly anyone uses this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's interesting. I would argue this is a slightly more compelling thing for users to actually change, but it's also something we can wait to see if users start asking for :)

Copy link
Contributor Author

@Huongg Huongg Mar 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is now done @datajoely 😄 I just included this today, by default this feature is always on unless user chooses to change it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it toggled or can they pass the preview number of rows?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is just toggled on and off at the moment, with the number of rows sets to 40


# Run command is only available if a node is an output, i.e. not a free input
if not data_node.is_free_input:
self.run_command = f"kedro run --to-outputs={data_node.full_name}"
Expand Down
42 changes: 28 additions & 14 deletions src/components/metadata-modal/metadata-modal.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { connect } from 'react-redux';
import PlotlyChart from '../plotly-chart';
import PreviewTable from '../preview-table';
import CollapseIcon from '../icons/collapse';
import BackIcon from '../icons/back';
import NodeIcon from '../icons/node-icon';
Expand All @@ -12,8 +13,9 @@ import './metadata-modal.css';
const MetadataModal = ({ metadata, onToggle, visible }) => {
const hasPlot = Boolean(metadata?.plot);
const hasImage = Boolean(metadata?.image);
const hasPreview = Boolean(metadata?.preview);

if (!visible.metadataModal || (!hasPlot && !hasImage)) {
if (!visible.metadataModal || (!hasPlot && !hasImage && !hasPreview)) {
return null;
}

Expand All @@ -37,6 +39,11 @@ const MetadataModal = ({ metadata, onToggle, visible }) => {
<NodeIcon className="pipeline-plot-modal__icon" icon={nodeTypeIcon} />
<span className="pipeline-plot-modal__title">{metadata.name}</span>
</div>
{hasPreview && (
<div className="pipeline-plot-modal__preview-text">
Previewing 40 first rows only
Huongg marked this conversation as resolved.
Show resolved Hide resolved
</div>
)}
</div>
{hasPlot && (
<PlotlyChart
Expand All @@ -56,19 +63,26 @@ const MetadataModal = ({ metadata, onToggle, visible }) => {
</div>
</div>
)}
<div className="pipeline-plot-modal__bottom">
<button
className="pipeline-plot-modal__collapse-plot"
onClick={onCollapsePlotClick}
>
<CollapseIcon className="pipeline-plot-modal__collapse-plot-icon"></CollapseIcon>
<span className="pipeline-plot-modal__collapse-plot-text">
{hasPlot
? 'Collapse Plotly Visualization'
: 'Collapse Matplotlib Image'}
</span>
</button>
</div>
{hasPreview && (
<div className="pipeline-plot-modal__preview">
<PreviewTable data={metadata.preview} size="large" />
</div>
)}
{!hasPreview && (
<div className="pipeline-plot-modal__bottom">
Huongg marked this conversation as resolved.
Show resolved Hide resolved
<button
className="pipeline-plot-modal__collapse-plot"
onClick={onCollapsePlotClick}
>
<CollapseIcon className="pipeline-plot-modal__collapse-plot-icon"></CollapseIcon>
<span className="pipeline-plot-modal__collapse-plot-text">
{hasPlot
? 'Collapse Plotly Visualization'
: 'Collapse Matplotlib Image'}
</span>
</button>
</div>
)}
</div>
);
};
Expand Down
13 changes: 12 additions & 1 deletion src/components/metadata-modal/metadata-modal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
flex-direction: column;
align-content: center;
align-items: center;
width: 100%; /* Full width (cover the whole page) */
height: 100%; /* Full height (cover the whole page) */
/* We don't need full width as sometime the preview table can take up more than a width of the page */
background-color: var(--color-bg-plot);

.pipeline-plotly-chart,
Expand Down Expand Up @@ -87,6 +87,11 @@
fill: var(--color-text);
}

.pipeline-plot-modal__preview-text {
font-size: 14px;
margin-right: 80px;
}

.pipeline-plot-modal__bottom {
position: relative;
display: flex;
Expand Down Expand Up @@ -114,6 +119,12 @@
}
}

.pipeline-plot-modal__preview {
max-width: calc(100vw - #{variables.$global-toolbar-width});
overflow-y: auto;
padding: 1.5em;
}

.pipeline-plot-modal__collapse-plot-icon {
width: 1.9em;
height: 1.9em;
Expand Down
20 changes: 20 additions & 0 deletions src/components/metadata/metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { connect } from 'react-redux';
import modifiers from '../../utils/modifiers';
import NodeIcon from '../../components/icons/node-icon';
import IconButton from '../../components/ui/icon-button';
import PreviewTable from '../../components/preview-table';
import CommandCopier from '../ui/command-copier/command-copier';
import PlotlyChart from '../plotly-chart';
import CloseIcon from '../icons/close';
Expand Down Expand Up @@ -56,6 +57,7 @@ const MetaData = ({
const hasPlot = Boolean(metadata?.plot);
const hasImage = Boolean(metadata?.image);
const hasTrackingData = Boolean(metadata?.trackingData);
const hasPreviewData = Boolean(metadata?.preview);
const isMetricsTrackingDataset = nodeTypeIcon === 'metricsTracking';
const hasCode = Boolean(metadata?.code);
const isTranscoded = Boolean(metadata?.originalType);
Expand Down Expand Up @@ -292,6 +294,24 @@ const MetaData = ({
</span>
</button>
)}
{hasPreviewData && (
<>
<div className="pipeline-metadata__preview">
<PreviewTable data={metadata.preview} size="small" />
<div className="pipeline-metadata__preview-shadow-box-right" />
<div className="pipeline-metadata__preview-shadow-box-bottom" />
</div>
<button
className="pipeline-metadata__link"
onClick={onExpandPlotClick}
>
<ExpandIcon className="pipeline-metadata__link-icon"></ExpandIcon>
<span className="pipeline-metadata__link-text">
Expand Preview Table
</span>
</button>
</>
)}
</div>
</>
)}
Expand Down
45 changes: 43 additions & 2 deletions src/components/metadata/styles/metadata.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

.kui-theme--light {
--color-metadata-bg: #{variables.$white-200};
--color-metadata-preview-bg: #{variables.$grey-200};
--color-metadata-kind-token-bg: #{variables.$white-400};
--color-plot-bg: #{variables.$white-400};
--color-button-plot: #{variables.$blue-900};
Expand All @@ -12,6 +13,7 @@

.kui-theme--dark {
--color-metadata-bg: #{variables.$slate-500};
--color-metadata-preview-bg: #{variables.$slate-800};
--color-metadata-kind-token-bg: #{variables.$slate-0};
--color-plot-bg: #{variables.$slate-700};
--color-button-plot: #{variables.$blue-900};
Expand Down Expand Up @@ -240,11 +242,13 @@ $list-inline-spacing: 0.2em;
.pipeline-metadata__link {
@extend %button;

align-items: center;
background-color: var(--color-button-plot);
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0;
background-color: var(--color-button-plot);
z-index: 1;

&:hover {
background-color: var(--color-button-plot-hovered);
Expand All @@ -270,3 +274,40 @@ $list-inline-spacing: 0.2em;
font-size: 0.87em;
}
}

.pipeline-metadata__preview {
background: var(--color-metadata-preview-bg);
height: 300px;
overflow: hidden;
position: relative;
}

.pipeline-metadata__preview-shadow-box-right {
background-image: linear-gradient(
to right,
rgba(0, 0, 0, 0),
var(--color-metadata-preview-bg)
);
border: none;
content: ' ';
height: 100%;
position: absolute;
right: 0;
top: 0;
width: 50px;
}

.pipeline-metadata__preview-shadow-box-bottom {
background-image: linear-gradient(
to bottom,
rgba(0, 0, 0, 0),
var(--color-metadata-preview-bg)
);
border: none;
content: ' ';
width: 100%;
left: 0%;
position: absolute;
bottom: 0;
height: 40px;
}
3 changes: 3 additions & 0 deletions src/components/preview-table/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import PreviewTable from './preview-table';

export default PreviewTable;
42 changes: 42 additions & 0 deletions src/components/preview-table/preview-table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import className from 'classnames';

import './preview-table.css';

const PreviewTable = ({ data, size = 'small' }) => {
const headers = Object.keys(data);
Huongg marked this conversation as resolved.
Show resolved Hide resolved
const nRows = Object.keys(data[headers[0]]);
Huongg marked this conversation as resolved.
Show resolved Hide resolved

return (
<table
className={className('preview-table', {
'preview-table__small': size === 'small',
'preview-table__large': size === 'large',
})}
cellSpacing={0}
>
<tbody>
<tr className="preview-table__row-header">
{headers.map((header) => (
<th className="preview-table__header" key={header}>
{header}
</th>
))}
</tr>
{nRows.map((index) => (
<tr className="preview-table__row" key={index}>
{headers.map((header, i) => {
return (
<td className="preview-table__data" key={i}>
{data[header][index]}
</td>
);
})}
</tr>
))}
</tbody>
</table>
);
};

export default PreviewTable;
70 changes: 70 additions & 0 deletions src/components/preview-table/preview-table.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
@use '../../styles/variables' as variables;
@use '../../styles/extends';

.kui-theme--light {
--color-highlight: #{variables.$grey-200};
}

.kui-theme--dark {
--color-highlight: #{variables.$slate-400};
}

.preview-table__header {
font-size: 12px;
font-weight: 600;
line-height: 16px;
padding-bottom: 12px;
}

.preview-table__data {
font-size: 12px;
font-weight: 400;
line-height: 16px;
padding-bottom: 8px;
}

.preview-table__small {
margin: 30px 32px;

.preview-table__header,
.preview-table__data {
text-align: left;
padding-right: 32px;
}
}

.preview-table__large {
margin: auto 30px 30px auto;

.preview-table__header,
.preview-table__data {
padding: 12px 42px 12px 22px;
text-align: left;
}
}

.preview-table__row:hover {
background: var(--color-highlight);
cursor: pointer;
}

.preview-table__header,
.preview-table__data {
position: relative;
outline: 0;
}

.preview-table__header:hover {
cursor: pointer;
}

.preview-table__header:hover::after {
background: var(--color-highlight);
content: '';
height: 100vh;
left: 0;
position: absolute;
top: -12px;
width: 95%;
z-index: -1;
}
Loading