@@ -181,7 +181,7 @@ def __init__(
181
181
self .cell_ids = cell_ids
182
182
self .na_rep = na_rep
183
183
184
- self .tooltips = _Tooltips ()
184
+ self .tooltips : Optional [ _Tooltips ] = None
185
185
186
186
self .cell_context : Dict [str , Any ] = {}
187
187
@@ -206,6 +206,19 @@ def _repr_html_(self) -> str:
206
206
"""
207
207
return self .render ()
208
208
209
+ def _init_tooltips (self ):
210
+ """
211
+ Checks parameters compatible with tooltips and creates instance if necessary
212
+ """
213
+ if not self .cell_ids :
214
+ # tooltips not optimised for individual cell check. requires reasonable
215
+ # redesign and more extensive code for a feature that might be rarely used.
216
+ raise NotImplementedError (
217
+ "Tooltips can only render with 'cell_ids' is True."
218
+ )
219
+ if self .tooltips is None :
220
+ self .tooltips = _Tooltips ()
221
+
209
222
def set_tooltips (self , ttips : DataFrame ) -> "Styler" :
210
223
"""
211
224
Add string based tooltips that will appear in the `Styler` HTML result. These
@@ -241,11 +254,8 @@ def set_tooltips(self, ttips: DataFrame) -> "Styler":
241
254
... )
242
255
>>> s = df.style.set_tooltips(ttips).render()
243
256
"""
244
- if not self .cell_ids :
245
- # tooltips not optimised for individual cell check.
246
- raise NotImplementedError (
247
- "Tooltips can only render with 'cell_ids' is True."
248
- )
257
+ self ._init_tooltips ()
258
+ assert self .tooltips is not None # mypy requiremen
249
259
self .tooltips .tt_data = ttips
250
260
return self
251
261
@@ -295,6 +305,8 @@ def set_tooltips_class(
295
305
... ('position', 'absolute'),
296
306
... ('z-index', 1)])
297
307
"""
308
+ self ._init_tooltips ()
309
+ assert self .tooltips is not None # mypy requirement
298
310
if properties :
299
311
self .tooltips .class_properties = properties
300
312
if name :
@@ -530,7 +542,7 @@ def format_attr(pair):
530
542
else :
531
543
table_attr += ' class="tex2jax_ignore"'
532
544
533
- return {
545
+ d = {
534
546
"head" : head ,
535
547
"cellstyle" : cellstyle ,
536
548
"body" : body ,
@@ -540,6 +552,10 @@ def format_attr(pair):
540
552
"caption" : caption ,
541
553
"table_attributes" : table_attr ,
542
554
}
555
+ if self .tooltips :
556
+ d = self .tooltips ._translate (self .data , self .uuid , d )
557
+
558
+ return d
543
559
544
560
def format (self , formatter , subset = None , na_rep : Optional [str ] = None ) -> "Styler" :
545
561
"""
@@ -716,7 +732,6 @@ def render(self, **kwargs) -> str:
716
732
self ._compute ()
717
733
# TODO: namespace all the pandas keys
718
734
d = self ._translate ()
719
- d = self .tooltips ._translate_tooltips (self .data , self .uuid , d )
720
735
# filter out empty styles, every cell will have a class
721
736
# but the list of props may just be [['', '']].
722
737
# so we have the nested anys below
@@ -786,7 +801,7 @@ def clear(self) -> None:
786
801
Returns None.
787
802
"""
788
803
self .ctx .clear ()
789
- self .tooltips = _Tooltips ()
804
+ self .tooltips = None
790
805
self .cell_context = {}
791
806
self ._todo = []
792
807
@@ -1817,7 +1832,61 @@ def _class_styles(self):
1817
1832
"""
1818
1833
return [{"selector" : f".{ self .class_name } " , "props" : self .class_properties }]
1819
1834
1820
- def _translate_tooltips (self , styler_data , uuid , d ):
1835
+ def _pseudo_css (self , uuid : str , name : str , row : int , col : int , text : str ):
1836
+ """
1837
+ For every table data-cell that has a valid tooltip (not None, NaN or
1838
+ empty string) must create two pseudo CSS entries for the specific
1839
+ <td> element id which are added to overall table styles:
1840
+ an on hover visibility change and a content change
1841
+ dependent upon the user's chosen display string.
1842
+
1843
+ For example:
1844
+ [{"selector": "T__row1_col1:hover .pd-t",
1845
+ "props": [("visibility", "visible")]},
1846
+ {"selector": "T__row1_col1 .pd-t::after",
1847
+ "props": [("content", "Some Valid Text String")]}]
1848
+
1849
+ Parameters
1850
+ ----------
1851
+ uuid: str
1852
+ The uuid of the Styler instance
1853
+ name: str
1854
+ The css-name of the class used for styling tooltips
1855
+ row : int
1856
+ The row index of the specified tooltip string data
1857
+ col : int
1858
+ The col index of the specified tooltip string data
1859
+ text : str
1860
+ The textual content of the tooltip to be displayed in HTML.
1861
+
1862
+ Returns
1863
+ -------
1864
+ pseudo_css : List
1865
+ """
1866
+ return [
1867
+ {
1868
+ "selector" : "#T_"
1869
+ + uuid
1870
+ + "row"
1871
+ + str (row )
1872
+ + "_col"
1873
+ + str (col )
1874
+ + f":hover .{ name } " ,
1875
+ "props" : [("visibility" , "visible" )],
1876
+ },
1877
+ {
1878
+ "selector" : "#T_"
1879
+ + uuid
1880
+ + "row"
1881
+ + str (row )
1882
+ + "_col"
1883
+ + str (col )
1884
+ + f" .{ name } ::after" ,
1885
+ "props" : [("content" , f'"{ text } "' )],
1886
+ },
1887
+ ]
1888
+
1889
+ def _translate (self , styler_data , uuid , d ):
1821
1890
"""
1822
1891
Mutate the render dictionary to allow for tooltips:
1823
1892
@@ -1844,61 +1913,11 @@ def _translate_tooltips(self, styler_data, uuid, d):
1844
1913
1845
1914
name = self .class_name
1846
1915
1847
- def _pseudo_css (row : int , col : int , text : str ):
1848
- """
1849
- For every table data-cell that has a valid tooltip (not None, NaN or
1850
- empty string) must create two pseudo CSS entries for the specific
1851
- <td> element id which are added to overall table styles:
1852
- an on hover visibility change and a content change
1853
- dependent upon the user's chosen display string.
1854
-
1855
- For example:
1856
- [{"selector": "T__row1_col1:hover .pd-t",
1857
- "props": [("visibility", "visible")]},
1858
- {"selector": "T__row1_col1 .pd-t::after",
1859
- "props": [("content", "Some Valid Text String")]}]
1860
-
1861
- Parameters
1862
- ----------
1863
- row : int
1864
- The row index of the specified tooltip string data
1865
- col : int
1866
- The col index of the specified tooltip string data
1867
- text : str
1868
- The textual content of the tooltip to be displayed in HTML.
1869
-
1870
- Returns
1871
- -------
1872
- pseudo_css : List
1873
- """
1874
- return [
1875
- {
1876
- "selector" : "#T_"
1877
- + uuid
1878
- + "row"
1879
- + str (row )
1880
- + "_col"
1881
- + str (col )
1882
- + f":hover .{ name } " ,
1883
- "props" : [("visibility" , "visible" )],
1884
- },
1885
- {
1886
- "selector" : "#T_"
1887
- + uuid
1888
- + "row"
1889
- + str (row )
1890
- + "_col"
1891
- + str (col )
1892
- + f" .{ name } ::after" ,
1893
- "props" : [("content" , f'"{ text } "' )],
1894
- },
1895
- ]
1896
-
1897
1916
mask = (self .tt_data .isna ()) | (self .tt_data .eq ("" )) # empty string = no ttip
1898
1917
self .table_styles = [
1899
1918
style
1900
1919
for sublist in [
1901
- _pseudo_css (i , j , str (self .tt_data .iloc [i , j ]))
1920
+ self . _pseudo_css (uuid , name , i , j , str (self .tt_data .iloc [i , j ]))
1902
1921
for i in range (len (self .tt_data .index ))
1903
1922
for j in range (len (self .tt_data .columns ))
1904
1923
if not mask .iloc [i , j ]
0 commit comments