Code Monkey home page Code Monkey logo

ipysheet's People

Contributors

afonit avatar choldgraf avatar dependabot[bot] avatar giswqs avatar jasongrout avatar jtpio avatar maartenbreddels avatar martinrenou avatar oscar6echo avatar sergiuser1 avatar sylvaincorlay avatar thomas-bc avatar weiglszonja 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ipysheet's Issues

Problem rendering from widget state at notebook start

I have found a strange edge case.
When I reopen a notebook containing widget state with a sheet, I see 2 headers and not small broken red link to indicate the widget is not connected to a kernel (as all core widget do).

screenshot-ipysheet-issue

To reproduce:

Note that it's only a rendering problem it seems as applying nbconvert (with a template to work with ipywidgets 7.x) works fine.

Also note the missing broken red link...

Traitlets warnings

When importing ipysheet:

/usr/local/src/sage-config/local/lib/python2.7/site-packages/ipysheet/sheet.py:11: DeprecationWarning: metadata {'value': None} was set from the constructor. With traitlets 4.1, metadata should be set using the .tag() method, e.g., Int().tag(key1='value1', key2='value2')
  value = Union([Bool(), Unicode(), Float(), Int()], allow_none=True, value=None).tag(sync=True)
/usr/local/src/sage-config/local/lib/python2.7/site-packages/ipysheet/sheet.py:19: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`). Passing types is deprecated in traitlets 4.1.
  choice = List(Unicode, allow_none=True, default_value=None).tag(sync=True)
/usr/local/src/sage-config/local/lib/python2.7/site-packages/ipysheet/sheet.py:45: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`). Passing types is deprecated in traitlets 4.1.
  row_headers = Union([Bool(), List(Unicode)], value=True).tag(sync=True)
/usr/local/src/sage-config/local/lib/python2.7/site-packages/ipysheet/sheet.py:46: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`). Passing types is deprecated in traitlets 4.1.
  column_headers = Union([Bool(), List(Unicode)], value=True).tag(sync=True)
/usr/local/src/sage-config/local/lib/python2.7/site-packages/ipysheet/sheet.py:48: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`). Passing types is deprecated in traitlets 4.1.
  column_width = Union([CInt(), List(CInt)], value=None, allow_none=True).tag(sync=True)

Cell checkbox value not converted to Python bool

While arguable this is what you'd expect.
It gets converted to text 'true' or 'false' and appear as 1 or 0 in a on_value_change(change) context.
See 'basics' nb in ipysheet-demo repo for the first remark and 'demo_ipysheet_bs' for the second.

Could it be done in a natural way ?

cell attributes except value do not get synced

In latest version cells attributes format, type, style, etc (all but value I think) do not get synced when changed from Python.
See repo ipysheet-demo notebook 'basics'.
It's a handsontable issue - I think - since the attributes get to the web page, as far as I could debug.

Make pscript a non-optional dependency

Since this PR, ipysheet does not optionally depends on flexx anymore. It now depends on pscript, which is a small library for JavaScipt to Python transpilation (used by flexx). I think it would be a good idea to officially depend on it so that we have default support for Python renderers.

numeric parsing issues

Follow up to #97
Using version 5065a59

import ipysheet

sheet = ipysheet.Sheet(rows=1, columns=1)
sheet.cells = ipysheet.Cell(value=None, row_start=0, row_end=0, column_start=0, column_end=0, type='numeric'),

sheet

Exhibit A:

  1. Run code
  2. Type "1" (sans quotes) into cell
  3. Cell contains 1.000, right aligned
  4. sheet.cells[0].value == '1' a string!

Exhibit B:

  1. Run code
  2. Type "1" (sans quotes) into cell
  3. Cell contains 1.000, right aligned
  4. Type "2" (sans quotes) into cell
  5. Cell contains 2.000, right aligned
  6. sheet.cells[0].value == 2 an integer

Exhibit C:

  1. Run code
  2. Type "1" (sans quotes) into cell
  3. Cell contains 1.000, right aligned
  4. Type "2." (sans quotes) into cell
  5. Cell contains 2., left aligned
  6. sheet.cells[0].value == '2.' a string

Now change code to

import ipysheet

sheet = ipysheet.Sheet(rows=1, columns=1)
sheet.cells = ipysheet.Cell(value="", row_start=0, row_end=0, column_start=0, column_end=0, type='numeric'),

sheet

Exhibit D:

  1. Run new code
  2. Type "1" (sans quotes) into cell
  3. Cell contains 1.000, right aligned
  4. sheet.cells[0].value == 1 an integer

from_dataframe can't load columns with NaT fields

I have a Pandas dataframe that has some NaT values in a column with datatype datetime, which were set using pd.to_datetime(). The current version of from_datetime() throws the following error when trying to load:

ValueError: NaTType does not support strftime

Add array trait to ipysheet columns

Ipysheet looks great! I have been trying to find a way to use it in some of my projects. I would love to jslink a couple of ipysheet columns with a bqplot scatter plot. I was hoping this would work....

widgets.jslink((column2, 'value'), (scatt, 'x'))
widgets.jslink((column3, 'value'), (scatt, 'y'))

where scatt is a scatter mark . However, the scatter x, y attributes require numpy arrays. Would it be possible to add an 'array' trait to the ipysheet columns so they could be syncable with bqplot marks?

Clean widget views code

We need to clean this code.
Giving a list as a key to a JavaScript object actually converts it to a string so we needed to parse the string in order to get back the row and column indices.

We can find a better solution than this.

ipysheet hides error

This isn't really a bug, just pointing out some unexpected behaviour compared to ipywidgets:

import ipywidgets as widgets
import ipysheet

sheet = ipysheet.Sheet(rows=1, columns=1)
sheet.cells = ipysheet.Cell(row_start=0, row_end=0, column_start=0, column_end=0),
field = widgets.Text(continuous_update=False)

def update(change):
    raise RuntimeError
            
field.observe(update, names='value')
sheet.cells[0].observe(update, names='value')

If I type into field it shows the RuntimeError directly below the widget. If I type into sheet, the RuntimeError is not shown. Using an Output widget as a workaround.

pip install failed on win7

Below the stack trace.
It looks like it's the extra "/" at the end of path prevents the installation in folder notebook.d/.
On Windows only. It works fine on macOS.

F:\MyTest>pip install ipysheet
Collecting ipysheet
  Downloading https://cdp-artifactory.fr.world.socgen/artifactory/api/pypi/pypi-python-release/packages/66/45/330822c6c85c2ed67818c5d3ffdfc990fd8640087b41c2340bb1b38b5743/ipysheet-0.1.0.tar.gz (585kB)
    100% |████████████████████████████████| 593kB 2.0MB/s
Requirement already satisfied: ipywidgets>=7.0.0 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipysheet)
Requirement already satisfied: traitlets>=4.3.1 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: nbformat>=4.2.0 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: ipykernel>=4.5.1 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: ipython>=4.0.0; python_version >= "3.3" in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: widgetsnbextension~=3.1.0 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: ipython_genutils in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from traitlets>=4.3.1->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: six in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from traitlets>=4.3.1->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: decorator in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from traitlets>=4.3.1->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: jsonschema!=2.5.0,>=2.4 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from nbformat>=4.2.0->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: jupyter-core in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from nbformat>=4.2.0->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: tornado>=4.0 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipykernel>=4.5.1->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: jupyter-client in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipykernel>=4.5.1->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: simplegeneric>0.8 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipython>=4.0.0; python_version >= "3.3"->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: setuptools>=18.5 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipython>=4.0.0; python_version >= "3.3"->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: pickleshare in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipython>=4.0.0; python_version >= "3.3"->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: jedi>=0.10 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipython>=4.0.0; python_version >= "3.3"->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: pygments in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipython>=4.0.0; python_version >= "3.3"->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: colorama; sys_platform == "win32" in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipython>=4.0.0; python_version >= "3.3"->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: prompt-toolkit<2.0.0,>=1.0.4 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from ipython>=4.0.0; python_version >= "3.3"->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: notebook>=4.4.1 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from widgetsnbextension~=3.1.0->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: pyzmq>=13 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from jupyter-client->ipykernel>=4.5.1->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: python-dateutil>=2.1 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from jupyter-client->ipykernel>=4.5.1->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: parso==0.1.1 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from jedi>=0.10->ipython>=4.0.0; python_version >= "3.3"->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: wcwidth in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from prompt-toolkit<2.0.0,>=1.0.4->ipython>=4.0.0; python_version >= "3.3"->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: Send2Trash in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from notebook>=4.4.1->widgetsnbextension~=3.1.0->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: terminado>=0.8.1 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from notebook>=4.4.1->widgetsnbextension~=3.1.0->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: nbconvert in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from notebook>=4.4.1->widgetsnbextension~=3.1.0->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: jinja2 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from notebook>=4.4.1->widgetsnbextension~=3.1.0->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: pywinpty>=0.5; os_name == "nt" in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from terminado>=0.8.1->notebook>=4.4.1->widgetsnbextension~=3.1.0->ipywidgets>=7.0.
0->ipysheet)
Requirement already satisfied: pandocfilters>=1.4.1 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.1.0->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: testpath in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.1.0->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: entrypoints>=0.2.2 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.1.0->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: bleach in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.1.0->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: mistune>=0.7.4 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from nbconvert->notebook>=4.4.1->widgetsnbextension~=3.1.0->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: MarkupSafe>=0.23 in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from jinja2->notebook>=4.4.1->widgetsnbextension~=3.1.0->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: html5lib!=1.0b1,!=1.0b2,!=1.0b3,!=1.0b4,!=1.0b5,!=1.0b6,!=1.0b7,!=1.0b8,>=0.99999999pre in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from bleach->nbconvert->no
tebook>=4.4.1->widgetsnbextension~=3.1.0->ipywidgets>=7.0.0->ipysheet)
Requirement already satisfied: webencodings in c:\homeware\anaconda3-4.4.0-windows-x86_64\lib\site-packages (from html5lib!=1.0b1,!=1.0b2,!=1.0b3,!=1.0b4,!=1.0b5,!=1.0b6,!=1.0b7,!=1.0b8,>=0.99999999pre->bleach-
>nbconvert->notebook>=4.4.1->widgetsnbextension~=3.1.0->ipywidgets>=7.0.0->ipysheet)
Building wheels for collected packages: ipysheet
  Running setup.py bdist_wheel for ipysheet ... error
  Complete output from command C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\python.exe -u -c "import setuptools, tokenize;__file__='C:\\Users\\oborderi\\AppData\\Local\\Temp\\pip-build-7t4ypee7\\ipysheet\\setup.p
y';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d C:\Users\oborderi\AppData\Local\Temp\tmp4ibkzrywpip-wheel- --py
thon-tag cp36:
  setup.py entered
  $PATH=C:\ProgramData\Oracle\Java\javapath;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Axalto\Access Client\v5\;C:\Program Files (x86)\G
emalto\Access Client\v5\;c:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\;c:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\;c:\Program Files\Microsoft SQL Server\110\Tools\
Binn\;c:\Program Files (x86)\Microsoft SQL Server\110\DTS\Binn\;C:\ORACLE\Client\11.2.0;C:\Program Files\Freeware\TortoiseGit\1.8.110\bin;C:\Program Files\Git\cmd;C:\Program Files\nodejs\;C:\Program Files (x86)
\Windows Kits\8.1\Windows Performance Toolkit\;C:\Users\oborderi\sgwt-installer\phantomjs\phantomjs-2.1.1-windows\bin;C:\Users\oborderi\sgwt-installer\nodist\bin;C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64;C:\HO
MEWARE\Anaconda3-4.4.0-Windows-x86_64\Library\mingw-w64\bin;C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Library\usr\bin;C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Library\bin;C:\HOMEWARE\Anaconda3-4.4.0-Windows-
x86_64\Scripts;C:\Program Files\Microsoft VS Code\bin;C:\Users\oborderi\AppData\Roaming\npm
  running bdist_wheel
  running build
  running build_py
  creating build
  creating build\lib
  creating build\lib\ipysheet
  copying ipysheet\easy.py -> build\lib\ipysheet
  copying ipysheet\sheet.py -> build\lib\ipysheet
  copying ipysheet\test_all.py -> build\lib\ipysheet
  copying ipysheet\_version.py -> build\lib\ipysheet
  copying ipysheet\__init__.py -> build\lib\ipysheet
  running egg_info
  writing ipysheet.egg-info\PKG-INFO
  writing dependency_links to ipysheet.egg-info\dependency_links.txt
  writing requirements to ipysheet.egg-info\requires.txt
  writing top-level names to ipysheet.egg-info\top_level.txt
  reading manifest file 'ipysheet.egg-info\SOURCES.txt'
  reading manifest template 'MANIFEST.in'
  writing manifest file 'ipysheet.egg-info\SOURCES.txt'
  creating build\lib\ipysheet\static
  copying ipysheet\static\extension.js -> build\lib\ipysheet\static
  copying ipysheet\static\handsontable.js -> build\lib\ipysheet\static
  copying ipysheet\static\index.js -> build\lib\ipysheet\static
  copying ipysheet\static\index.js.map -> build\lib\ipysheet\static
  installing to build\bdist.win-amd64\wheel
  running install
  running install_lib
  creating build\bdist.win-amd64
  creating build\bdist.win-amd64\wheel
  creating build\bdist.win-amd64\wheel\ipysheet
  copying build\lib\ipysheet\easy.py -> build\bdist.win-amd64\wheel\.\ipysheet
  copying build\lib\ipysheet\sheet.py -> build\bdist.win-amd64\wheel\.\ipysheet
  creating build\bdist.win-amd64\wheel\ipysheet\static
  copying build\lib\ipysheet\static\extension.js -> build\bdist.win-amd64\wheel\.\ipysheet\static
  copying build\lib\ipysheet\static\handsontable.js -> build\bdist.win-amd64\wheel\.\ipysheet\static
  copying build\lib\ipysheet\static\index.js -> build\bdist.win-amd64\wheel\.\ipysheet\static
  copying build\lib\ipysheet\static\index.js.map -> build\bdist.win-amd64\wheel\.\ipysheet\static
  copying build\lib\ipysheet\test_all.py -> build\bdist.win-amd64\wheel\.\ipysheet
  copying build\lib\ipysheet\_version.py -> build\bdist.win-amd64\wheel\.\ipysheet
  copying build\lib\ipysheet\__init__.py -> build\bdist.win-amd64\wheel\.\ipysheet
  running install_data
  creating build\bdist.win-amd64\wheel\ipysheet-0.1.0.data
  creating build\bdist.win-amd64\wheel\ipysheet-0.1.0.data\data
  creating build\bdist.win-amd64\wheel\ipysheet-0.1.0.data\data\share
  creating build\bdist.win-amd64\wheel\ipysheet-0.1.0.data\data\share\jupyter
  creating build\bdist.win-amd64\wheel\ipysheet-0.1.0.data\data\share\jupyter\nbextensions
  creating build\bdist.win-amd64\wheel\ipysheet-0.1.0.data\data\share\jupyter\nbextensions\ipysheet
  copying ipysheet\static\handsontable.js -> build\bdist.win-amd64\wheel\ipysheet-0.1.0.data\data\share\jupyter\nbextensions\ipysheet
  copying ipysheet\static\extension.js -> build\bdist.win-amd64\wheel\ipysheet-0.1.0.data\data\share\jupyter\nbextensions\ipysheet
  copying ipysheet\static\index.js -> build\bdist.win-amd64\wheel\ipysheet-0.1.0.data\data\share\jupyter\nbextensions\ipysheet
  copying ipysheet\static\index.js.map -> build\bdist.win-amd64\wheel\ipysheet-0.1.0.data\data\share\jupyter\nbextensions\ipysheet
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
    File "C:\Users\oborderi\AppData\Local\Temp\pip-build-7t4ypee7\ipysheet\setup.py", line 169, in <module>
      setup(**setup_args)
    File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\site-packages\setuptools\__init__.py", line 129, in setup
      return distutils.core.setup(**attrs)
    File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\core.py", line 148, in setup
      dist.run_commands()
    File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\dist.py", line 955, in run_commands
      self.run_command(cmd)
    File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\dist.py", line 974, in run_command
      cmd_obj.run()
    File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\site-packages\wheel\bdist_wheel.py", line 215, in run
      self.run_command('install')
    File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\cmd.py", line 313, in run_command
      self.distribution.run_command(command)
    File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\dist.py", line 974, in run_command
      cmd_obj.run()
    File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\site-packages\setuptools\command\install.py", line 61, in run
      return orig.install.run(self)
    File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\command\install.py", line 557, in run
      self.run_command(cmd_name)
    File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\cmd.py", line 313, in run_command
      self.distribution.run_command(command)
    File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\dist.py", line 974, in run_command
      cmd_obj.run()
    File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\command\install_data.py", line 56, in run
      dir = convert_path(f[0])
    File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\util.py", line 127, in convert_path
      raise ValueError("path '%s' cannot end with '/'" % pathname)
  ValueError: path 'etc/jupyter/nbconfig/notebook.d/' cannot end with '/'

  ----------------------------------------
  Failed building wheel for ipysheet
  Running setup.py clean for ipysheet
Failed to build ipysheet
Installing collected packages: ipysheet
  Running setup.py install for ipysheet ... error
    Complete output from command C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\python.exe -u -c "import setuptools, tokenize;__file__='C:\\Users\\oborderi\\AppData\\Local\\Temp\\pip-build-7t4ypee7\\ipysheet\\setup
.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record C:\Users\oborderi\AppData\Local\Temp\pip-w18k2qfg-record\in
stall-record.txt --single-version-externally-managed --compile:
    setup.py entered
    $PATH=C:\ProgramData\Oracle\Java\javapath;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Axalto\Access Client\v5\;C:\Program Files (x86)
\Gemalto\Access Client\v5\;c:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\;c:\Program Files (x86)\Microsoft SQL Server\110\Tools\Binn\;c:\Program Files\Microsoft SQL Server\110\Tool
s\Binn\;c:\Program Files (x86)\Microsoft SQL Server\110\DTS\Binn\;C:\ORACLE\Client\11.2.0;C:\Program Files\Freeware\TortoiseGit\1.8.110\bin;C:\Program Files\Git\cmd;C:\Program Files\nodejs\;C:\Program Files (x8
6)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Users\oborderi\sgwt-installer\phantomjs\phantomjs-2.1.1-windows\bin;C:\Users\oborderi\sgwt-installer\nodist\bin;C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64;C:\
HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Library\mingw-w64\bin;C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Library\usr\bin;C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Library\bin;C:\HOMEWARE\Anaconda3-4.4.0-Window
s-x86_64\Scripts;C:\Program Files\Microsoft VS Code\bin;C:\Users\oborderi\AppData\Roaming\npm
    running install
    running build
    running build_py
    creating build
    creating build\lib
    creating build\lib\ipysheet
    copying ipysheet\easy.py -> build\lib\ipysheet
    copying ipysheet\sheet.py -> build\lib\ipysheet
    copying ipysheet\test_all.py -> build\lib\ipysheet
    copying ipysheet\_version.py -> build\lib\ipysheet
    copying ipysheet\__init__.py -> build\lib\ipysheet
    running egg_info
    writing ipysheet.egg-info\PKG-INFO
    writing dependency_links to ipysheet.egg-info\dependency_links.txt
    writing requirements to ipysheet.egg-info\requires.txt
    writing top-level names to ipysheet.egg-info\top_level.txt
    reading manifest file 'ipysheet.egg-info\SOURCES.txt'
    reading manifest template 'MANIFEST.in'
    writing manifest file 'ipysheet.egg-info\SOURCES.txt'
    creating build\lib\ipysheet\static
    copying ipysheet\static\extension.js -> build\lib\ipysheet\static
    copying ipysheet\static\handsontable.js -> build\lib\ipysheet\static
    copying ipysheet\static\index.js -> build\lib\ipysheet\static
    copying ipysheet\static\index.js.map -> build\lib\ipysheet\static
    running install_lib
    creating C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet
    copying build\lib\ipysheet\easy.py -> C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet
    copying build\lib\ipysheet\sheet.py -> C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet
    creating C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet\static
    copying build\lib\ipysheet\static\extension.js -> C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet\static
    copying build\lib\ipysheet\static\handsontable.js -> C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet\static
    copying build\lib\ipysheet\static\index.js -> C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet\static
    copying build\lib\ipysheet\static\index.js.map -> C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet\static
    copying build\lib\ipysheet\test_all.py -> C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet
    copying build\lib\ipysheet\_version.py -> C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet
    copying build\lib\ipysheet\__init__.py -> C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet
    byte-compiling C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet\easy.py to easy.cpython-36.pyc
    byte-compiling C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet\sheet.py to sheet.cpython-36.pyc
    byte-compiling C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet\test_all.py to test_all.cpython-36.pyc
    byte-compiling C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet\_version.py to _version.cpython-36.pyc
    byte-compiling C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\Lib\site-packages\ipysheet\__init__.py to __init__.cpython-36.pyc
    running install_data
    creating C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\share\jupyter\nbextensions\ipysheet
    copying ipysheet\static\handsontable.js -> C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\share\jupyter\nbextensions\ipysheet
    copying ipysheet\static\extension.js -> C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\share\jupyter\nbextensions\ipysheet
    copying ipysheet\static\index.js -> C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\share\jupyter\nbextensions\ipysheet
    copying ipysheet\static\index.js.map -> C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\share\jupyter\nbextensions\ipysheet
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\oborderi\AppData\Local\Temp\pip-build-7t4ypee7\ipysheet\setup.py", line 169, in <module>
        setup(**setup_args)
      File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\site-packages\setuptools\__init__.py", line 129, in setup
        return distutils.core.setup(**attrs)
      File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\core.py", line 148, in setup
        dist.run_commands()
      File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\dist.py", line 955, in run_commands
        self.run_command(cmd)
      File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\dist.py", line 974, in run_command
        cmd_obj.run()
      File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\site-packages\setuptools\command\install.py", line 61, in run
        return orig.install.run(self)
      File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\command\install.py", line 557, in run
        self.run_command(cmd_name)
      File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\cmd.py", line 313, in run_command
        self.distribution.run_command(command)
      File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\dist.py", line 974, in run_command
        cmd_obj.run()
      File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\command\install_data.py", line 56, in run
        dir = convert_path(f[0])
      File "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\lib\distutils\util.py", line 127, in convert_path
        raise ValueError("path '%s' cannot end with '/'" % pathname)
    ValueError: path 'etc/jupyter/nbconfig/notebook.d/' cannot end with '/'

    ----------------------------------------
Command "C:\HOMEWARE\Anaconda3-4.4.0-Windows-x86_64\python.exe -u -c "import setuptools, tokenize;__file__='C:\\Users\\oborderi\\AppData\\Local\\Temp\\pip-build-7t4ypee7\\ipysheet\\setup.py';f=getattr(tokenize,
 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record C:\Users\oborderi\AppData\Local\Temp\pip-w18k2qfg-record\install-record.txt --singl
e-version-externally-managed --compile" failed with error code 1 in C:\Users\oborderi\AppData\Local\Temp\pip-build-7t4ypee7\ipysheet\

F:\MyTest>

observe triggers an even number of times; reverting changes

Here's a cool app I made to calculate sin(x)

2019-04-08-154206

from traitlets import HasTraits, observe, List, link, dlink
import ipywidgets as widgets
import ipysheet
import numpy as np

ROWS = 5

class Model(HasTraits):
    xs = List()
    ys = List()
    
    @observe('xs')
    def on_xs(self, change):
        self.ys = np.sin(self.xs).tolist()
        
model = Model(xs = [np.nan]*ROWS)

sheet = ipysheet.Sheet(rows=ROWS, columns=2, column_headers=['x', 'sin(x)'])

common_cell_kwargs = dict(
    value=[""]*ROWS,
    row_start=0,
    row_end=ROWS-1,
    squeeze_row=False
)

sheet.cells = (
    ipysheet.Cell(column_start=0, column_end=0, **common_cell_kwargs),
    ipysheet.Cell(column_start=1, column_end=1, read_only=True, **common_cell_kwargs)
)

link((model, 'xs'), (sheet.cells[0], 'value'),
    transform=(
        lambda xs: [str(x) for x in xs],
        lambda xs: [float(x) for x in xs]
    )
)
dlink((model, 'ys'), (sheet.cells[1], 'value'),
    transform=(
        lambda ys: [str(y) for y in ys]
    )
)

button_plus = widgets.Button(description='Set to +arange')
button_minus = widgets.Button(description='Set to -arange')

output = widgets.Output()

def plus_arange(button):
    model.xs = np.arange(ROWS).tolist()
    
def minus_arange(button):
    model.xs = (-np.arange(ROWS)).tolist() 

def observer(change):
    with output:
        print("{} -> {}".format(change.old, change.new))
        
sheet.cells[1].observe(observer, names='value')
    
button_plus.on_click(plus_arange)
button_minus.on_click(minus_arange)

widgets.VBox([
    widgets.HBox([
        button_plus, button_minus
    ]),
    sheet
])

Step 1.
Run the code in a single cell

Step 2.
Press the first button

The sheet is properly updated and output contains 1 line of output

Step 3.
Press the second button

The second column is not updated and output contains an additional 4 lines of output.
The output shows that the Cell value is overwritten 4 times, bouncing back and forth between the old and new values

Sheet.observe is not doing anything

Hello,
It seems Sheet.observe is not working. I am trying to trigger an event when any cell in the sheet changes. here is an example below. Changing a or b does not update the sum.

import ipywidgets as widgets
sheet = ipysheet.sheet(rows=3, columns=2, column_headers=False, row_headers=False)
cell_a = ipysheet.cell(0, 1, 1, label_left='a')
cell_b = ipysheet.cell(1, 1, 2, label_left='b')
cell_sum = ipysheet.cell(2, 1, 3, label_left='sum', read_only=True)

# changes in a or b should trigger this function
def calculate(change):
    cell_sum.value = cell_a.value + cell_b.value

sheet.observe(calculate, type='All')
#cell_a.observe(calculate, 'value')
#cell_b.observe(calculate, 'value')
sheet

Questions about code design

I might be wrong, but I have the feeling that the code could be a lot faster than it is today. Whenever one cell attribute changes, we recompute the whole sheet. More than that, we make a deep copy of the data.
I also feel like adding the entire logic inside of the SheetModel and the SheetView could be wrong.

So, my questions are:

  • Is it possible to make the changes of the sheet more specific to the event that happened? I mean, if I only change the value of one cell, is it possible to only change the sheet data for this cell specifically?
  • Can we add cell logic (like events) inside of the CellModel, and would it make sense to have a CellView ?

filling up an empty sheet in widget view

Hello,
I created an empty sheet in jupyterlab that I would like to fill up in the display view (I'm not sure I am using the right terminology).
Typically, I would add measurement values.
But when I try to extract these data, the sheet remains empty.

to create the sheet

sheet = ipysheet.sheet(rows=3, columns=2)
sheet

to read it

a=ipysheet.to_array(sheet)

What I would like to do is to plot the two columns with pyplot.
Thanks!
tmp

Number formatting

Handsontable uses NumbroJS for numbers formatting. It might be a good idea to implement our own number formatters using d3-format, like ipywidgets and bqplot.

Can't paste into multiple cells

Version: e285b95

import ipysheet
import ipywidgets as widgets

sheet = ipysheet.Sheet(rows=2, columns=2)
sheet.cells = (
    ipysheet.Cell(value='', row_start=1, row_end=1, column_start=0, column_end=0),
    ipysheet.Cell(value='', row_start=1, row_end=1, column_start=1, column_end=1)
)
sheet

To reproduce:

  1. Type 1 into A1
  2. Type 2 into B1
  3. Select both cells
  4. Hit CTRL-C
  5. Click on A2
  6. Hit CTRL-V

Only A2 is populated.

What does work:

  1. If I skip the lines sheet.cells = ...
  2. If sheet.cells = ... defines A2:B2 as a single cell
  3. If for Step 5. above I select A2:B2

fix typescript def for handsontable

The typescript defs for handsontable are not complete and we get this error:

src/renderer.ts:25:32 - error TS2339: Property 'registerRenderer' does not exist on type 'Renderers'.

25         Handsontable.renderers.registerRenderer(this.get('name'), this.fn(Handsontable));

We can live with it because we ignore errors for now:
https://github.com/QuantStack/ipysheet/blob/36f1ffffb3c564d73174f5c56dfd04bfbcd1dafa/js/tsconfig.json#L6
and we just continue whatever the exit code is:
https://github.com/QuantStack/ipysheet/blob/36f1ffffb3c564d73174f5c56dfd04bfbcd1dafa/js/package.json#L19

We should fix this, preferable by doing a PR to handsontable, and changing the above to be more strict.

Overlapping cells

I am reconsidering overlapping cells support. I think it can be confusing for users, I find it confusing myself, and if we remove it I see possible performance improvements.

Currently, when a cell value/metadata changes (whether it's a single cell or a cell range) we need to recompute the sheet data by looping over all the cells. This ensures that the newly added cells get precedence over the "old" ones if they are overlapping.
If we drop overlapping cells support, when a cell value/metadata changes, no need to loop over all the cells. We just update the sheet data on the row/column indices of the cell.

Deactivate automatic resizing

It would be nice to be able to deactivate automatic column/row resizing, we need to find a way to do that with Handsontable, and make it optional for the user.

observe triggers twice when doing a round trip

Related to #66

To illustrate, a simple app that formats floating point user input

import ipysheet
import ipywidgets as widgets

as_list = True

sheet = ipysheet.Sheet(rows=1, columns=1)
if as_list:
    sheet.cells = ipysheet.Cell(value=[""], row_start=0, row_end=0, column_start=0, column_end=0,
                                squeeze_column=True, squeeze_row=False),
else:
    sheet.cells = ipysheet.Cell(value="", row_start=0, row_end=0, column_start=0, column_end=0,
                                squeeze_column=True, squeeze_row=True),

output = widgets.Output()

updating = False

def update(change):
    global updating
    with output:
        if updating:
            print('internal trigger')
            print(change)
        else:
            print('external trigger')
            print(change)
            updating = True
            if as_list:
                sheet.cells[0].value = ['{:.4f}'.format(float(entry)) for entry in change.new]
            else:
                sheet.cells[0].value = '{:.4f}'.format(float(change.new))
            updating = False
            
sheet.cells[0].observe(update, names='value')

sheet.cells[0].value = ['-.4'] if as_list else '-.4'

This puts the following in the output widget:

external trigger
{'name': 'value', 'old': [''], 'new': ['-.4'], 'owner': Cell(choice=[], column_end=0, column_start=0, row_end=0, row_start=0, squeeze_row=False, value=['-.4']), 'type': 'change'}
internal trigger
{'name': 'value', 'old': ['-.4'], 'new': ['-0.4000'], 'owner': Cell(choice=[], column_end=0, column_start=0, row_end=0, row_start=0, squeeze_row=False, value=['-0.4000']), 'type': 'change'}
external trigger
{'name': 'value', 'old': ['-0.4000'], 'new': ['-.4'], 'owner': Cell(choice=[], column_end=0, column_start=0, row_end=0, row_start=0, squeeze_row=False, value=['-.4']), 'type': 'change'}
internal trigger
{'name': 'value', 'old': ['-.4'], 'new': ['-0.4000'], 'owner': Cell(choice=[], column_end=0, column_start=0, row_end=0, row_start=0, squeeze_row=False, value=['-0.4000']), 'type': 'change'}

This shows that there's an extra trait notification, trying to "update" the new value to the original input.

Setting as_list = False uses a scalar instead of a list and does not suffer from this problem

external trigger
{'name': 'value', 'old': '', 'new': '-.4', 'owner': Cell(choice=[], column_end=0, column_start=0, row_end=0, row_start=0, value='-.4'), 'type': 'change'}
internal trigger
{'name': 'value', 'old': '-.4', 'new': '-0.4000', 'owner': Cell(choice=[], column_end=0, column_start=0, row_end=0, row_start=0, value='-0.4000'), 'type': 'change'}

The double notification in the as_list = True case leads to flickering and I'm not sure how to work around it yet.

Would be good to have a get_cell(i, j) method to Sheet

This would be convenient as not all cells need be remembered to retrieve their value.

Maybe something as simple that ?

def get_cell(sheet, i, j):
    for cell in sheet.cells:
        if cell.row == i and cell.column == j:
            return cell

Observe triggers too many times

Version: 5065a59

import ipywidgets as widgets
import ipysheet

sheet = ipysheet.Sheet(rows=1, columns=1)
sheet.cells = ipysheet.Cell(value=[""], row_start=0, row_end=0, column_start=0, column_end=0, squeeze_column=False),

output = widgets.Output()

def observer(change):
    with output:
        print("{0} -> {1}".format(change.old, change.new))
        
sheet.cells[0].observe(observer, names='value')
sheet.cells[0].value = ['a']
sheet.cells[0].value = ['b']
sheet.cells[0].value = ['c']

output

output contains

[''] -> ['a']
['a'] -> ['b']
['b'] -> ['c']
['c'] -> ['a']
['a'] -> ['c']

Related: #85

observe triggers twice when setting value with a tuple

import ipywidgets as widgets
import ipysheet

output = widgets.Output()
table = ipysheet.Sheet(rows=1, columns=2)
cell = ipysheet.Cell(value=("", ""), row_start=0, row_end=0, column_start=0, column_end=1,
                     squeeze_column=False, squeeze_row=True)
table.cells = cell,

def observer(change):
    with output:
        print(change)

cell.observe(lambda change: observer(change.new), names='value')

cell.value = ('a', 'b')

output

prints

('a', 'b')
['a', 'b']

This is probably a side-effect of serialization.

A simple workaround is to use lists, but this is somewhat inconsistent: Sheet.cells is a Tuple so I figured Cell.value would be as well.

Two-way binding to Pandas DataFrame

Is it possible to have a sheet instance have bi-directional binding to a Pandas DataFrame? I think this would be an invaluable example to have in the docs. It's easy enough to set a sheet's column and row properties to the Pandas equivalents, but I couldn't find any documentation regarding how to appropriately pass data values into a sheet instance (link below is what I was checking). Any help would be appreciated.

https://ipysheet.readthedocs.io/en/latest/api.html#ipysheet.sheet.Sheet.data

Checkbox widget causing height update

Version 0.3.0.

Apologies, I'm having trouble uploading screenshots so I have to describe the problem verbally.

Here's my code

import ipywidgets as widgets
import ipysheet

mysheet = ipysheet.Sheet(rows=2, columns=2)

checkbox_kwargs = dict(
    layout={'width': '1em', 'height': '1em'},
    indent=False, value=True
)

checkbox_cell_kwargs = dict(column_start=0, column_end=0, type='widget')

checkbox_cells = tuple(
    ipysheet.Cell(value=widgets.Checkbox(**checkbox_kwargs), row_start=i, row_end=i, **checkbox_cell_kwargs)
    for i in range(2)
) 

mysheet.cells = checkbox_cells

mysheet

When I enter some text into B1 say, the cell height jumps from 22px to 32px in all rows. This behaviour does not happen if I remove the line

mysheet.cells = checkbox_cells

Far fetched suggestion: button to toggle a sheet to almost full page

A sheet sometimes need be quite large - if the input is complex, or maybe also if the output is big.
So a button to temporarily expand the sheet to full page (or almost) proportions is very convenient in this context.

This suggestion comes from qgrid.
And I got good feedback from this feature in particular.

Food for thought.

checkbox value not updating

import ipysheet

kwargs = dict(row_start=0, row_end=0, squeeze_column=True, squeeze_row=True)

grid = ipysheet.Sheet(rows=1, columns=2, column_headers = False, row_headers=False, column_width=[20, 100])
grid.cells = (ipysheet.Cell(value=True, column_start=0, column_end=0, type='checkbox', **kwargs),
              ipysheet.Cell(value='True', column_start=1, column_end=1, **kwargs))

grid.cells[0].value = False
grid.cells[1].value = 'False'

grid

This shows a checked box and a cell containing "False"

Somewhat related to #3

Loaders for NumPy arrays

We have support for loading Pandas Dataframe, we should do the same for NumPy arrays, or list of lists.

Sheet.on_click

Hello,
I'd like to find out when a cell or the sheet is selected. Any way to do it?
Thanks.

Suggestion: Paste and exapand sheet if necessary

From the first proto feedbacks I got from potential users, it would be good to be able to paste into a sheet and the sheet would adjust its size to accept the input data.

A user may want to paste a row or column - of undetermined size - from Excel.
So the widget would be provisionally small and expand 'just enough' if necessary to accommodate the new data.

Pasting is not 100% stable if you stress test the widget (I suspect it's more a browser issue).
So the paste could be active

  • only via a button (?)
  • only if a cell is focused
  • up to certain limit - say 100 row/cols (?)

Then ideally a scroll bar would appear to avoid that the sheet takes up too much screen space.

Food for thought

development installation failed

C:\Users\weiwa\ipysheet\js>npm install .

[email protected] install C:\Users\weiwa\ipysheet\js\node_modules\puppeteer
node install.js

ERROR: Failed to download Chromium r624492! Set "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" env variable to skip download.
{ Error: read ECONNRESET
at TLSWrap.onStreamRead (internal/stream_base_commons.js:111:27)
-- ASYNC --
at BrowserFetcher. (C:\Users\weiwa\ipysheet\js\node_modules\puppeteer\lib\helper.js:108:27)
at Object. (C:\Users\weiwa\ipysheet\js\node_modules\puppeteer\install.js:64:16)
at Module._compile (internal/modules/cjs/loader.js:701:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
at Module.load (internal/modules/cjs/loader.js:600:32)
at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
at Function.Module._load (internal/modules/cjs/loader.js:531:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:754:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3) errno: 'ECONNRESET', code: 'ECONNRESET', syscall: 'read' }npm WARN [email protected] requires a peer of acorn@^6.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of karma@1 || 2 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of typescript@2 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of webpack@^2.0.0 || ^3.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] No license field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] install: node install.js
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

At first it warning that the ipysheet.egg-info folder was missing. I went to pypi to download the file and overwrite it, then used the npm install. command, but the following error occurred. Whether I am operating incorrectly?thanks.

Checkbox widget link broken

Related to #64

import ipywidgets as widgets
import ipysheet
from traitlets import HasTraits, Bool, link

mysheet = ipysheet.Sheet(rows=2, columns=2)

checkbox_kwargs = dict(
    layout={'width': '1em', 'height': '1em'},
    indent=False,
    value=True
)

checkbox_cell_kwargs = dict(
    column_start=0, column_end=0,
    type='widget'
)

checkbox_cells = tuple(
    ipysheet.Cell(value=widgets.Checkbox(**checkbox_kwargs), row_start=i, row_end=i, **checkbox_cell_kwargs)
    for i in range(2)
) 

mysheet.cells = checkbox_cells

class CheckboxStates(HasTraits):
    row1 = Bool()
    row2 = Bool()
    
model = CheckboxStates()

link((model, 'row1'), (checkbox_cells[0].value, 'value'))
link((model, 'row2'), (checkbox_cells[1].value, 'value'))

mysheet

When I run model.row1 = True the corresponding checkbox updates and vice versa, as expected.
Entering some text into B1, say, "breaks" the link between model.row1 and checkbox_cells[0].value.value. There is no error message.

How many `Cell`s should I make?

What's the recommended number of cells to have?

Like, a Cell object could represent the entire sheet, or I could make one Cell object for each row or one for literally every cell.

What's best for performance?

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.