Giter Site home page Giter Site logo

avaiga / taipy-gui Goto Github PK

View Code? Open in Web Editor NEW
51.0 4.0 16.0 11.1 MB

Graphical User Interface generator for Taipy

License: Apache License 2.0

Python 56.76% JavaScript 0.88% HTML 0.15% TypeScript 38.71% CSS 3.29% Jupyter Notebook 0.21% Dockerfile 0.01%
gui hacktoberfest

taipy-gui's Introduction

⚠️ Archived ⚠️

WARNING: This repository is archived. Taipy has performed a repository restructuring. The taipy-gui code has been moved and merged into the main taipy repository.


License

Copyright 2021-2024 Avaiga Private Limited

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

taipy-gui's People

Contributors

aastridvh avatar alexandresajus avatar dependabot[bot] avatar dinhlongviolin1 avatar dr-irv avatar fabienlelaquais avatar fredll avatar fredll-avaiga avatar haotran-avaiga avatar joaoandre avatar joaoandre-avaiga avatar jrobinav avatar thienan1010 avatar toan-quach avatar trgiangdo avatar tsuu2092 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

taipy-gui's Issues

BUG-Assign a full dictionary to a bound variable

Description

If the page content contains dotted-notation bindings (such {my_dict.my_key}), the Gui does not propagate the value to the user interface when you update the entire gui.my_dict object.

How to reproduce

from taipy.gui import Gui

d = { "v1": 0, "v2": 1}

def on_change(gui, var, val):
  d = { "v1": 2*val, "v2": val}
  gui.d = d
  
Gui(page="""
Value: <|{d.v1}|>

Slider: <|{d.v2}|slider|>
""").run()

Expected behavior
Moving the slider updates the v2 property value.

In on_change, we expect that setting the new entire dictionary value will update gui.v1 as well, but instead we get the error message: on_change function invocation exception: 'dict' object has no attribute 'v1'

Easy tables and charts

Description

As of today, creating a table or a chart control requires a dataset of some sort (DataFrame...).

Wouldn't it be great to allow the simple construct:
<|{[1,2,3,4]}|chart|>
to display a very simple chart, where the X axis would be just the index of the array?

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Improve Testing

Description
Right now the gui repo is setting testing threshold to 75%. Test coverage should be improved dramatically so the threshold level would be at least 85%.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

BUG-Block Markdown syntax does not work when not on an empty line

Description

If you need a block element in your markdown (part, layout...) then it must appear on a line on its own, which is unfortunate.

How to reproduce

from taipy.gui import Gui;
Gui(page = """
Some text <|
Some more text
|>
""").run()

Breaks.
Adding a carriage return before the opengin <| fragment does work though.

Expected behavior

The code above should be interpreted properly.

Undo/Redo functionality in the user interface

Description

Edition in the front-end should be undoable (and redoable).

Issues to be adresses

  • Whether the back-end should trigger new pipeline executions or not is a decision made by the programmer.
  • Whether the data sources are updated is a decision made by the programmer.
  • Undo/redo in paginated tables should bring the modified row in the visible area.
  • Multi-user must be addressed.

Turn libmagic as optional

We put Libmagic as a mandatory package in our Pipfile and setup.py.
We want to turn it optional and let users install it with pip install taipy[magic] or something similar.

Interesting fact, if magic is not installed, the variable _has_magic_module is never set and an exception is raised on first read access.

if util.find_spec("magic"):
    import magic

    _has_magic_module = True

Note: On MacOs Libmagic should be installed with brew (https://pypi.org/project/python-magic/). Could be good to add this information as an error message if the user is on Mac.

Acceptance criteria

  • Turn libmagic optional
  • Update GitHub Action to run test with and without

Rename Page and PageRenderer

Description

The class that is exposed to users is PageRenderer, which is definitively a good name in term of what it actually does. But users dont really care. They are concerned about how they use it. Page would therefore be fare better.

Page is, at the time of this writing, used to associate a PageRenderer with its route and styling information, which the user has no direct access to. Hiding this class (renaming to _Page?) would therefore be beneficial.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Gui: make non visible components private

Description
make non visible components private so that they don't appear in the generated doc

  • class
  • ...

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Allow multiple, parallel connections to the same Taipy application.

What would that feature address
Several users can connect to a Taipy application, to view and/or generate scenario data.

Description of the ideal solution
The Taipy sever allows for several, distinct connections, and serves pages according to the appropriate client.

Acceptance Criteria
Each connected user may be identified, and is able to navigate across the Taipy data.

Revise HTML Rendering

Description
HTML rendering on the frontend side is currently not working properly. This issue should be revised and resolved as soon as possible

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Allow early variable binding

Description

At the current time, variable binding is done when a page is first displayed. Only the variable used in that page would be bound, and therefore accessible from the Gui instance (or to be more precise, from the client data scope).

Let's suppose we have an application with two pages:

  • the app starts by showing page 1.
  • variable 'x' is used on page 2 only.
  • some functions triggered by buttons or controls of page 1 need to update 'x'
    Naturally, we want to refer to 'gui.x' and do our thing.
    Unfortunately, until page 2 is displayed, 'x' does not exist in the Gui object, and the application fails.

In the situation of some user code accessing a variable from the Gui object, but fails to find it (it is not bound), no matter if we want to read or write this variable, the Gui object should try to locate the not-yet-bound variable in the global scope (just at it does in the regular magic binding from the page renderers), and bind it if it can.

Only when the variable actually cannot be found should the application complain and fail.

Of course, we may want to cache the binding failures if there's a performance hit or, which I think is more relevant, if we don't want to generate the same error message over and over.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Rename the `date_selector` control to `date` if it can be turned to a static control

Description

The date_selector control could benefit from having an editable property, set to True by default.

If this happens, we will want to rename that control to make its name shorter and reflect better what it really does.
date is an option, but maybe datetime is better. Let's discuss.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Pytest for playwright

  • Taipy version:
  • Python version:
  • Operating System:

Description

We already have testing for backend (Python) and frontend (React) individually. It would be great to also be able to test our application end-to-end. Playwright has been chosen by me (Long) over puppeteer for this purpose. The goal of this issue is to implement a structure for writing end-to-end testing using playwright on pytest.

Have a default '.css' file to configure a default margin

What would that feature address
This issue would address the default margin present in the GUI. The default margin is currently 0px. Having no margin is in general not good-looking.

Description of the ideal solution
Having a default margin at 20px for example would allow a user to have a more aesthetically pleasing page without creating or changing a '.css' file. So, a default .css file with this code :

div#root {
    margin: 20px;
}

Caveats
It shouldn't have an impact on other elements. However, it would mean that the default margin is for example 20px. Therefore, the user would have to bypass the default parameter by creating his own .css file if he wants to have no margin or a different margin.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Add a parameter to 'chart' control to change the parameters unique to a certain type of chart

Description
Add the ability for the user to change the parameters unique for a type of chart through a dictionary. For example for type=histogram,
we could change parameters that are present here. https://plotly.com/javascript/reference/histogram/

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Separate download functionality and download control

Description

Allow users to trigger a download when they need it.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Allow an image to show in a button

Description

Just like the toggle element, button should allow for using images.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Allow multiple instances of taipy.App

The current implementation of taipy.App has a bad flaw that needs fixing: the Markdown class instance that we use to parse the md template is for some reason not propagated to the extension code (like the handleMatch() methods of InlineProcessor subclasses).
Obviously, we want to access the App instance there, since this is where we can retrieve the DataProbes that were created, and maybe more information (such as styling).

The workaround so far was to set a class variable (in App.__init__()) to the Markdown class.
This is pretty bad since therefore, you cannot have more that a single App in your application...

Remove all stying config on python backend

Description
The styling config has been implemented initialy to allow users to add their own custom class name to taipy visual elements so they could manipulate it to their liking. This feature is no longer a requirement and should be removed to prevent redundancy.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Chart: change property name extend_data to options

Description
Chart: change property name extend_data to options

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Chart: allow multi-dataframe support (different length)

Description
Chart: allow multi-dataframe support (different length)

That would allow for vertical timeline on charts for example

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

protect data

Description
For better robustness, it would be nice to protect Gui data by

  • providing user data scope as a parameter to user function (instead of gui)
  • user data scope should only allow access to the user python script variables

gui parameter will not be provided to user functions anymore:

  • UI methods (block, send alert, navigate ...) can be called through the user created gui instance

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Provide a PageRenderer checker

What would that feature address

When your Taipy application uses many or complex page structures, it can be difficult to spot problems in the page definitions.
Warning messages may stack in the console, sometimes without any location information (which page, which content, what line).

Description of the ideal solution

We could add some checking functionality that would provide the user with better information.

It could be a check() method in the PageRenderer class, so that would work for Partials as well.

This method could return the renderer page just as it would be sent to the client, or None if any problem was spotted.

Caveats

The line number in the original text fragment that created the PageRenderer is often lost. We may need to plug it in the generated tags for error processing purposes.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Improve Encapsulation

Description

  • Simplify holder evaluation
  • add content and image encapsulation
  • manage lov value selection

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Documentation - Charts - Have one page per chart and a "fundamentals" page as well

Description

  • Have a fundamentals page about charts, with a grid composed of every available chart (link + image) available in Taipy.
  • Links in the grid may lead to their respective chart page.
  • In every chart page, present the chart usage, the code result and a screenshot of the rendered element in the GUI.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Let the pane control be usable as a block

Description

So far the pane control expects a page or a partial to define its content.

It would be nice to make it a block as well, so content can be inlined in the page definition.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Allow filtering on table columns

What would that feature address

We want to allow users to select a filter from a table header to focus on a subset of the data.
The filter itself will pick one or several existing value and discard the rows that don't match.

Description of the ideal solution

Excel-like filtering.

Caveats

Some complex filters, like on numerical fields, might have to be implemented on the server.
Then the problem is how to select those filters from the front-end.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Create a demo that shows the feature
  • Ensure documentaion is updated

Test ngrok

There is no test on ngrok.

We at least need a test to ensure we can run with or without this package.

This will allow us to validate its optional installation in the CI.

Improve expression evaluation and function binding +

Description
Allow for better expression evaluation with

  • list comprehension
  • module imports
  • function usage

Eliminate most of function binding except for lambda who don't have a name

that would allow to write:
<|{[math.cos(2 * math.pi * x / 100) * math.exp(-3 * x * decay / 50 / 360) for x in range(0, 720)]}|chart|>

  • change page_id to page for dialog and pane controls
  • status should use tuple (type, message)

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Add all sorts of chart examples to user manual

Description

Taipy aims at simplifying the access to advanced graphics such as charts.
However, the access to the expressivity of Plotly is constrained by the understanding of this large library.

Because we don't want to have developers engaged in learning all of Plotly in order to achieve their goals, on potential way is to provide multiple examples, as simple and different as possible, to users can basically copy and paste provided code snippets (control expressions) to achieve most of their goals.

Acceptance Criteria

  • The User Manual section for charts has a significant number of different example to start with.

Make the creation of the layout columns easier

Description

This improvement will add to the existing syntax, another way to create columns in the layout parameters. Currently, when we want to create 5 columns in a layout, we write

<|layout|columns=1 1 1 1 1

The goal would be to change this syntax to make it simpler and easier to read. For example, like this :

<|layout|columns=1*5

This syntax will create the same layout as before so 5 columns of the same width.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Add orientation parameter to 'indicator' control

Description
This improvement will let the user choose whether to display the indicator vertically or horizontally. The syntax and effect should be the same as the 'slider' control (for ex, orientation=v).

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Allow access to Gui methods from state

Description
Allow access to Gui methods from state

In callbacks, you'll be able to write:

def on_callback(state: State, ...):
    state.gui.download(file)

rename GUi.Methods:

  • block_ui => hold_actions
  • unblock_ui => resume_actions
  • show_notification => notify

and keep:

  • navigate => navigate
  • download => download

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Add an element tag identifier in Markdown parser

Description

When your Markdown input becomes large, with lots of parts and layout and whatnot, you tend to suffer when it comes to making sure you're breaking the document structure.

The Markdown parser helps indicate where blocks are not closed or where block closing fragments are misplaced... but you don't really have any support on opening and closing fragments match.

We could extend the visual element Markdown syntax by allowing an identifier to be placed between the '<' and the '|', expecting the same identifier in the related closing fragment that would become '|''[opening_id]''>'.

So this syntax would be allowed:

<first|
some content
<second|
some more
|second>
|first>

If the '|second>' fragment is omitted, the parser will be able to mention it precisely.
If '|first>' and '|second>' are swapped, the parser will indicate it as well (although theoretically harmless).

This would be optional, and the parser would then be able to generate relevant messages to the programmer in case she gets lost in the document structure.
This really makes sense only for block constructs, but it is harmless to make it possible to use for controls as well.
Only a subset of identifier would be allowed, to simplify the parsing. The character set [0-9a-zA-Z_.] seems sufficient.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Add a 'render' parameter directly in the control

Description
Add a 'render' parameter that is used the same way as the render parameter in part control. The objective is to simplify the code when parts are only used to render or not a single control.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

BUG-MUI Messages emitted from the NavBar control

Description

The coverage tests for the GUI controls appears to generate a lengthy message:

    console.error
      MUI: The `value` provided to the Tabs component is invalid.
      None of the Tabs' children match with "/".
      You can provide one of the following values: ...

This complicates the reading of the coverage run log, and is also a potentially issue that needs fixing.

How to reproduce

Look at the Code Coverage section report, on the src/components/Taipy/NavBar.spec.tsx source file.

Expected behavior

No message should be produced, or something relevant.

BUG-Inconsistent behavior for the display of a list of pages with a single page

Description
If I only need a single page, then we should use:
gui = Gui(name, Markdown(page1))

However, a second option would be:
list_pages = {
'p1':Markdown(page1)
}
gui = Gui(name,pages = list_pages)

however using this code nothing appears on the GUI, but if I add a second page then it works!
I do not see why having a single page would work using a list of pages.

Discuss the user authorization topic in Taipy

What would that feature address

Discuss an architecture that allows reflecting our users' needs.

requirement document here.

Description of the ideal solution

A document is available that describes where we are heading.

Acceptance Criteria

  • Shared document is available.

Simplify the Gui class

Description

Now that Taipy exposes the user variables through the State object when invoking callbacks, I see no point of providing the magic variable accessors in the Gui class.

One should actually never access (read or write) those pseudo variables (gui.var) outside the scope of a callback. Removeing all together would of course enforce that.

Removing these would also lift the barrier of not letting users add properties on their own to their gui instance, which could raise aliasing problems with global variables names.

This point also questions the actual need for a Global Data Scope. Please make sure there are use cases where this really is needed.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Support for formats in f-string syntax used in control expressions

Description

Controls can use application variables if their properties definitions using the {var_name} construct, available since Python 3.0.

Now this syntax allows for formatting options (for example "{var:.2f}" indicates you want to display the floating point value of var using only two digits.
Taipy will break if you try that.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

BUG-the selected value of a selector returns a '_TaipyLovValue' and not the true value

Description
When the selected value of a selector returns a '_TaipyLovValue' and not directly the value. However, 'var_value' in the 'on_change' seems to be the real value of the selection.

How to reproduce

from taipy.gui import Gui

selector = ['test 1', 'test 2']
selected = selector[0]

md = """
<|{selected}|selector|lov={selector}|>
"""

def on_change(state, var_name, var_value):
    if var_name == 'selected':
        print(var_value)
        print(state.selected)
        
Gui(page=md).run()

Expected behavior
When we call state.selected, we should get 'test_1' or 'test_2' depending on the selection and not the '_TaipyLovValue'.

Runtime environment
Please specify relevant indications.

  • OS: Windown 10, conda environment
  • Browser: Firefox

Tree: Manage expanded state of nodes

Description
Add a n expanded dynamic property to the tree control

  • if False, allows only one node to be expanded at any given level (ie close an expanded node if the suer expand another one)
  • if a list of ids, expand nodes with id in the list

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Provide a NumPy data accessor

What would that feature address

Some customers may want to rely on NumPy only (and no Pandas).
At this point, Taipy can deal with Data Frames that are exposed to front-end controls such as tables or charts.
We must provide an equivalent for NumPy arrays as well.

Description of the ideal solution

Multi-dimensional NumPy arrays can be bound to Taipy controls just like we already do with Pandas' data frames.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

BUG-Cannot use lambda in action

Description

There are situation where you want to use a lambda as an action.

Say you just want to set a variable as the result of pressing a button.

The natural (?) way of doing this would be:

<|Set value|button|on_action={lambda: value = True}|>

Because Taipy GUI has this state object that represents the user variables, it could be, although cumbersome:

<|Set value|button|on_action={lambda s: s.value = True}|>

However, both syntaxes fail to be properly interpreted by Taipy.

How to reproduce
See how Taipy fails to interpret:

from taipy.gui import Gui

value = False

Gui(page="""
<|Set value|button|on_action={lambda: value = True}|>
""").run()

Expected behavior

The lambda expression is executed, and therefore the value is set.

Initialize taipy-gui repository

Description

Based on the original taipy repository, create taipy-gui which will only contains features relating to the gui side (excluding docs and taipy-core).

Add an assignment function to the State class

Description

There are situations where you want to assign bound variables in lambdas associated with control callbacks.

Unfortunately, you cannot use lambda state: state.var = val because it is not a proper statement for a lambda, and because assignement is prohibited in lambdas anyways.

If we have a State.assign(var_name, var_value) that returns anything that the lambda could then use as the resulting expression, we're good to go.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

Add hover text on controls

Description

Hover information provides tips on what a control does.

Acceptance Criteria

  • Ensure new code is unit tested, and check code coverage is at least 90%
  • Propagate any change on the demos and run all of them to ensure there is no breaking change
  • Ensure any change is well documented

BUG-Chart Select Property generates 2 on_change calls

Description
When selecting 1 point in a chart using the selected property, the on_change function is called twice instead of once.
The behavior is not seen when using a box select on the chart, it just occurs when a single selection of a point
is performed.

How to reproduce
A code fragment

from taipy.gui import Gui, Markdown
import pandas as pd
l=[]
my_df = pd.DataFrame(data={"date":[1,2,3,4,5], "Qty":[10,20,10,20,10]})
page1 = """
# Bug Screen
<|{my_df}|chart|x=date|y=Qty|height=40%|width=50%|selected={l}|>
"""

def on_change(gui, var, value):
    if var=="l":
        print(f"value of f: {value}")

list_pages = {
    'p1':Markdown(page1)
}
gui = Gui(__name__, Markdown(page1))
gui.on_change = on_change
gui.run()

Expected behavior
If I select 1 point once, only 1 print should appear.

Screenshots

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.