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

[Feat] Enable temporal selector DatePicker #309

Merged
merged 63 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
933b207
date picker poc - dmc component implementation
nadijagraca Feb 7, 2024
3d502ec
merge main
nadijagraca Feb 9, 2024
b42328e
adding date picker component
nadijagraca Feb 14, 2024
fabaf3e
Merge branch 'main' into feat/components/datepicker
nadijagraca Feb 14, 2024
f00fc25
linting
nadijagraca Feb 14, 2024
ffbd6f0
adding example page to dev app
nadijagraca Feb 14, 2024
c357035
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 14, 2024
e5534fb
addressing pr comments part 1
nadijagraca Feb 15, 2024
74f5094
linting
nadijagraca Feb 15, 2024
b07984a
fixing typo in datepicker
nadijagraca Feb 15, 2024
98d922b
addressing pr comments part 2
nadijagraca Feb 19, 2024
3ba36a0
linting
nadijagraca Feb 19, 2024
0736896
Merge branch 'main' into feat/components/datepicker
nadijagraca Feb 19, 2024
7fb67f6
add changelog
nadijagraca Feb 19, 2024
9ba81a8
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 19, 2024
345c64b
addressing pr comments part 4
nadijagraca Feb 20, 2024
79e9424
merging DatePicker and DateRangePicker into one model
nadijagraca Feb 22, 2024
dc360f4
deleting date_range_picker file
nadijagraca Feb 22, 2024
f7263f0
adjusting changelog file to reflect recent changes
nadijagraca Feb 22, 2024
7020908
Merge branch 'main' into feat/components/datepicker
huong-li-nguyen Feb 22, 2024
87f199d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 22, 2024
389abc3
Update app.py
huong-li-nguyen Feb 22, 2024
53b5516
Merge branch 'feat/components/datepicker' of https://github.com/mckin…
huong-li-nguyen Feb 22, 2024
693b3bd
addressing pr comments and fixing remaining bugs
nadijagraca Feb 27, 2024
8f8cf78
minor fixes
nadijagraca Feb 28, 2024
ab7f07f
merge main
nadijagraca Feb 28, 2024
8c5059f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 28, 2024
e3048c1
addressing remaining pr comments
nadijagraca Feb 28, 2024
b34ff48
removing comments and updating json schema
nadijagraca Feb 28, 2024
71f9b26
fixing test
nadijagraca Feb 28, 2024
eed99a1
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Feb 28, 2024
815c904
fixing tests
nadijagraca Feb 28, 2024
95cdde5
[Demo] Update features example dashboard with selectors (#333)
huong-li-nguyen Feb 28, 2024
fb95dbd
fixing bug on datepicker
nadijagraca Feb 29, 2024
8f59d72
Merge branch 'main' into feat/components/datepicker
nadijagraca Feb 29, 2024
3498f1a
fixing validation and minor refactoring
nadijagraca Feb 29, 2024
f196369
fixing validation and minor refactoring
nadijagraca Feb 29, 2024
8dd8256
fixing validation tests
nadijagraca Mar 1, 2024
e7a2ecb
adding testing data to dev app
nadijagraca Mar 1, 2024
c676d0d
reverting changes to dev app
nadijagraca Mar 1, 2024
60d1218
merge main
nadijagraca Mar 1, 2024
4a2d4ba
minor linting fixes
nadijagraca Mar 1, 2024
4a7c78f
removing unnecessary dcc store
nadijagraca Mar 2, 2024
8ab568d
adjusting range validator
nadijagraca Mar 2, 2024
1116975
Merge branch 'main' into feat/components/datepicker
huong-li-nguyen Mar 4, 2024
02ff9d7
Merge branch 'main' into feat/components/datepicker
huong-li-nguyen Mar 5, 2024
0dcf315
Pull main
petar-qb Mar 7, 2024
758876f
Merge branch 'main' into feat/components/datepicker
huong-li-nguyen Mar 11, 2024
58c0a56
Merge branch 'main' into feat/components/datepicker
huong-li-nguyen Mar 12, 2024
1470fed
Lint
huong-li-nguyen Mar 12, 2024
815742d
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Mar 12, 2024
cbc21da
[Feat] Add CSS styling to single and multi `DatePicker` (#346)
huong-li-nguyen Mar 13, 2024
926037c
Merge branch 'main' into feat/components/datepicker
huong-li-nguyen Mar 13, 2024
2fee8f9
Merge branch 'main' of https://github.com/mckinsey/vizro into feat/co…
petar-qb Mar 14, 2024
e8a83bd
Merge branch 'main' of https://github.com/mckinsey/vizro into feat/co…
petar-qb Mar 14, 2024
ed690fb
Merge branch 'main' of https://github.com/mckinsey/vizro into feat/co…
petar-qb Mar 15, 2024
c309d11
Minor changelog change
petar-qb Mar 18, 2024
a9c21ec
[QA] Add unit tests and docs for `DatePicker` (#319)
nadijagraca Mar 19, 2024
a67b5f0
Merge branch 'main' of https://github.com/mckinsey/vizro into feat/co…
petar-qb Mar 19, 2024
2f57abf
Removed redundant changelog file
petar-qb Mar 19, 2024
f385c14
Schema update
petar-qb Mar 19, 2024
45f4c45
Reverting test coverage fail_under from 93 to 92 due to different cov…
petar-qb Mar 19, 2024
74ed0cd
Minor parameter and test_parameter improvements
petar-qb Mar 20, 2024
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
61 changes: 60 additions & 1 deletion vizro-core/examples/_dev/app.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
"""Rough example used by developers."""

from datetime import datetime

import pandas as pd
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.models._components.form._text_area import TextArea
from vizro.models._components.form._user_input import UserInput
from vizro.tables import dash_data_table

iris = px.data.iris()

Expand All @@ -30,7 +34,62 @@
],
)

dashboard = vm.Dashboard(pages=[page])
# CREATE FAKE DATA
huong-li-nguyen marked this conversation as resolved.
Show resolved Hide resolved
column = [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4]
row = [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
value = [1, 7, 3, 5, 2, 10, 9, 1, 3, 7, 5, 8, 2, 9, 1, 2, 7, 5, 3, 2]
group = ["A", "B", "C", "D", "E", "E", "D", "C", "B", "A", "A", "E", "C", "B", "D", "A", "D", "B", "C", "E"]
date_time = [
"2023-01-01",
"2023-02-02",
"2023-03-03",
"2023-04-04",
"2023-05-05",
"2023-06-06",
"2023-07-07",
"2023-08-08",
"2023-09-09",
"2023-10-10",
"2023-11-11",
"2023-12-12",
"2024-01-01",
"2024-02-02",
"2024-03-03",
"2024-04-04",
"2024-05-05",
"2024-06-06",
"2024-07-07",
"2024-08-08",
]

data = pd.DataFrame()

date_time_new = [datetime.strptime(date, "%Y-%m-%d").date() for date in date_time]

data["COLUMN1"] = column
data["ROW1"] = row
data["VALUE"] = value
data["GROUP"] = group
data["DATE_TIME"] = date_time_new

page_1 = vm.Page(
title="Datepicker page",
components=[vm.Table(id="table", figure=dash_data_table(data_frame=data))],
controls=[
vm.Filter(
column="DATE_TIME",
selector=vm.DateRangePicker(
title="Pick a date",
min_date="2023-01-01",
value=["2024-01-01", "2024-03-01"],
max_date="2024-07-07",
nadijagraca marked this conversation as resolved.
Show resolved Hide resolved
),
# selector=vm.DatePicker(title="Pick a date", min_date='2023-01-01', value=['2024-01-01']),
)
],
huong-li-nguyen marked this conversation as resolved.
Show resolved Hide resolved
)

dashboard = vm.Dashboard(pages=[page, page_1])

if __name__ == "__main__":
Vizro().build(dashboard).run()
8 changes: 6 additions & 2 deletions vizro-core/src/vizro/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from ._base import VizroBaseModel # noqa: I001
from ._action import Action
from ._components import Card, Container, Graph, Table, Tabs
from ._components.form import Button, Checklist, Dropdown, RadioItems, RangeSlider, Slider
from ._components.form import Button, Checklist, Dropdown, RadioItems, RangeSlider, Slider, DateRangePicker, DatePicker
from ._controls import Filter, Parameter
from ._navigation.accordion import Accordion
from ._navigation.navigation import Navigation
Expand All @@ -23,13 +23,15 @@
Graph=Graph,
Parameter=Parameter,
Table=Table,
DateRangePicker=DateRangePicker,
Tabs=Tabs,
DatePicker=DatePicker,
nadijagraca marked this conversation as resolved.
Show resolved Hide resolved
)
Navigation.update_forward_refs(Accordion=Accordion, NavBar=NavBar, NavLink=NavLink)
Dashboard.update_forward_refs(Page=Page, Navigation=Navigation)
NavBar.update_forward_refs(NavLink=NavLink)
NavLink.update_forward_refs(Accordion=Accordion)

Parameter.update_forward_refs(DateRangePicker=DateRangePicker, DatePicker=DatePicker)
nadijagraca marked this conversation as resolved.
Show resolved Hide resolved
# Please keep alphabetically ordered
__all__ = [
"Accordion",
Expand All @@ -39,6 +41,8 @@
"Container",
"Checklist",
"Dashboard",
"DatePicker",
"DateRangePicker",
"Dropdown",
"Filter",
"Graph",
Expand Down
4 changes: 3 additions & 1 deletion vizro-core/src/vizro/models/_components/form/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from vizro.models._components.button import Button
from vizro.models._components.form.checklist import Checklist
from vizro.models._components.form.date_picker import DatePicker
from vizro.models._components.form.date_range_picker import DateRangePicker
from vizro.models._components.form.dropdown import Dropdown
from vizro.models._components.form.radio_items import RadioItems
from vizro.models._components.form.range_slider import RangeSlider
from vizro.models._components.form.slider import Slider

# Please keep alphabetically ordered
__all__ = ["Button", "Checklist", "Dropdown", "RadioItems", "RangeSlider", "Slider"]
__all__ = ["Button", "Checklist", "DatePicker", "DateRangePicker", "Dropdown", "RadioItems", "RangeSlider", "Slider"]
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def validate_max(cls, max, values):
return max


def validate_slider_value(cls, value, values):
def validate_range_value(cls, value, values):
nadijagraca marked this conversation as resolved.
Show resolved Hide resolved
"""Reusable validator for the "value" argument for sliders."""
if value is None:
return value
Expand Down
66 changes: 66 additions & 0 deletions vizro-core/src/vizro/models/_components/form/date_picker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from typing import List, Literal, Optional

import dash_mantine_components as dmc
from dash import html

try:
from pydantic.v1 import Field, PrivateAttr, validator
except ImportError: # pragma: no cov
from pydantic import Field, PrivateAttr, validator


from datetime import date

from vizro.models import Action, VizroBaseModel
from vizro.models._action._actions_chain import _action_validator_factory
from vizro.models._components.form._form_utils import validate_max, validate_range_value


class DatePicker(VizroBaseModel):
"""Temporal single-selector `DatePicker`.

Can be provided to [`Filter`][vizro.models.Filter] or [`Parameter`][vizro.models.Parameter].
Based on the underlying [`dmc.DatePicker`](https://www.dash-mantine-components.com/components/datepicker).

nadijagraca marked this conversation as resolved.
Show resolved Hide resolved
Args:
type (Literal["date_picker"]): Defaults to `"date_picker"`.
min (Optional[date]): Start date for date picker. Defaults to `None`.
max (Optional[date]): End date for date picker. Defaults to `None`.
value (List[date]): Default date value for date picker. Defaults to `None`.
nadijagraca marked this conversation as resolved.
Show resolved Hide resolved
title (str): Title to be displayed. Defaults to `""`.
actions (List[Action]): See [`Action`][vizro.models.Action]. Defaults to `[]`.

"""

type: Literal["date_picker"] = "date_picker"
min: Optional[date] = Field(None, description="Start date value for date picker.")
max: Optional[date] = Field(None, description="End date value for date picker.")
value: Optional[date] = Field(None, description="Default date value for date picker")
nadijagraca marked this conversation as resolved.
Show resolved Hide resolved
title: str = Field("", description="Title to be displayed.")

nadijagraca marked this conversation as resolved.
Show resolved Hide resolved
actions: List[Action] = []

_input_property: str = PrivateAttr("value")
_set_actions = _action_validator_factory("value")

# Re-used validators
_validate_value = validator("value", allow_reuse=True)(validate_range_value)
_validate_max_date = validator("max", allow_reuse=True)(validate_max)
nadijagraca marked this conversation as resolved.
Show resolved Hide resolved

def build(self):
init_value = self.value or self.min
return html.Div(
[
html.P(self.title) if self.title else None,
nadijagraca marked this conversation as resolved.
Show resolved Hide resolved
dmc.DatePicker(
id=self.id,
minDate=self.min,
value=init_value,
maxDate=self.max,
persistence=True,
persistence_type="session",
),
],
className="selector_container",
id=f"{self.id}_outer",
)
71 changes: 71 additions & 0 deletions vizro-core/src/vizro/models/_components/form/date_range_picker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from typing import List, Literal, Optional

import dash_mantine_components as dmc
from dash import html

try:
from pydantic.v1 import Field, PrivateAttr, validator
except ImportError: # pragma: no cov
from pydantic import Field, PrivateAttr, validator


from datetime import date

from vizro.models import Action, VizroBaseModel
from vizro.models._action._actions_chain import _action_validator_factory
from vizro.models._components.form._form_utils import validate_max, validate_range_value


class DateRangePicker(VizroBaseModel):
nadijagraca marked this conversation as resolved.
Show resolved Hide resolved
"""Temporal multi-selector `DateRangePicker`.

Can be provided to [`Filter`][vizro.models.Filter] or
[`Parameter`][vizro.models.Parameter]. Based on the underlying
[`dmc.DateRangePicker`](https://www.dash-mantine-components.com/components/datepicker#daterangepicker).

Args:
type (Literal["date_range_picker"]): Defaults to `"date_range_picker"`.
min (Optional[date]): Start date for date picker. Defaults to `None`.
max (Optional[date]): End date for date picker. Defaults to `None`.
value (Optional[List[date]]):
Default start and end date for date picker. Must be 2 items. Defaults to `[min, max]`.
title (str): Title to be displayed. Defaults to `""`.
actions (List[Action]): See [`Action`][vizro.models.Action]. Defaults to `[]`.

"""

type: Literal["date_range_picker"] = "date_range_picker"
min: Optional[date] = Field(None, description="Start date value for date range picker.")
max: Optional[date] = Field(None, description="End date value for date range picker.")
value: Optional[List[date]] = Field(
[], description="Default start and end date for date picker.", min_items=2, max_items=2
)
title: str = Field("", description="Title to be displayed.")

actions: List[Action] = []
nadijagraca marked this conversation as resolved.
Show resolved Hide resolved

_input_property: str = PrivateAttr("value")
_set_actions = _action_validator_factory("value")

# Re-used validators
_validate_value = validator("value", allow_reuse=True)(validate_range_value)
_validate_max = validator("max", allow_reuse=True)(validate_max)

def build(self):
init_value = self.value or [self.min, self.max] # type: ignore[list-item]
return html.Div(
[
html.P(self.title) if self.title else None,
nadijagraca marked this conversation as resolved.
Show resolved Hide resolved
dmc.DateRangePicker(
id=self.id,
minDate=self.min,
value=init_value,
allowSingleDateInRange=False,
huong-li-nguyen marked this conversation as resolved.
Show resolved Hide resolved
maxDate=self.max,
persistence=True,
persistence_type="session",
),
],
className="selector_container",
id=f"{self.id}_outer",
)
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from vizro.models._components.form._form_utils import (
set_default_marks,
validate_max,
validate_slider_value,
validate_range_value,
validate_step,
)
from vizro.models._models_utils import _log_call
Expand Down Expand Up @@ -53,7 +53,7 @@ class RangeSlider(VizroBaseModel):

# Re-used validators
_validate_max = validator("max", allow_reuse=True)(validate_max)
_validate_value = validator("value", allow_reuse=True)(validate_slider_value)
_validate_value = validator("value", allow_reuse=True)(validate_range_value)
_validate_step = validator("step", allow_reuse=True)(validate_step)
_set_default_marks = validator("marks", allow_reuse=True, always=True)(set_default_marks)
_set_actions = _action_validator_factory("value")
Expand Down
4 changes: 2 additions & 2 deletions vizro-core/src/vizro/models/_components/form/slider.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from vizro.models._components.form._form_utils import (
set_default_marks,
validate_max,
validate_slider_value,
validate_range_value,
validate_step,
)
from vizro.models._models_utils import _log_call
Expand Down Expand Up @@ -51,7 +51,7 @@ class Slider(VizroBaseModel):

# Re-used validators
_validate_max = validator("max", allow_reuse=True)(validate_max)
_validate_value = validator("value", allow_reuse=True)(validate_slider_value)
_validate_value = validator("value", allow_reuse=True)(validate_range_value)
_validate_step = validator("step", allow_reuse=True)(validate_step)
_set_default_marks = validator("marks", allow_reuse=True, always=True)(set_default_marks)
_set_actions = _action_validator_factory("value")
Expand Down
Loading
Loading