@@ -205,17 +205,21 @@ def stopped(self):
205205 self .n_attrs_spin .setDisabled (False )
206206
207207
208+ MAX_LABEL_LEN = 16
209+
210+
208211class OWRadvizGraph (OWGraphWithAnchors ):
209212 def __init__ (self , scatter_widget , parent ):
210213 super ().__init__ (scatter_widget , parent )
211214 self .anchors_scatter_item = None
215+ self .padding = 0.025
212216
213217 def clear (self ):
214218 super ().clear ()
215219 self .anchors_scatter_item = None
216220
217221 def set_view_box_range (self ):
218- self .view_box .setRange (QRectF (- 1.2 , - 1.05 , 2.4 , 2.1 ), padding = 0.025 )
222+ self .view_box .setRange (QRectF (- 1 , - 1 , 2 , 2 ), padding = self . padding )
219223
220224 def closest_draggable_item (self , pos ):
221225 points , _ = self .master .get_anchors ()
@@ -231,18 +235,55 @@ def update_anchors(self):
231235 points , labels = self .master .get_anchors ()
232236 if points is None :
233237 return
234- if self .anchor_items is None :
235- self .anchor_items = []
236- for point , label in zip (points , labels ):
237- anchor = TextItem ()
238- anchor .setText (label )
239- anchor .setColor (QColor (0 , 0 , 0 ))
240- anchor .setPos (* point )
241- self .plot_widget .addItem (anchor )
242- self .anchor_items .append (anchor )
243- else :
244- for anchor , point in zip (self .anchor_items , points ):
245- anchor .setPos (* point )
238+ if self .anchor_items is not None :
239+ for anchor in self .anchor_items :
240+ self .plot_widget .removeItem (anchor )
241+
242+ self .anchor_items = []
243+ label_len = 1
244+ for point , label in zip (points , labels ):
245+ anchor = TextItem ()
246+ anchor .textItem .setToolTip (f"<b>{ label } </b>" )
247+
248+ if len (label ) > MAX_LABEL_LEN :
249+ i = label .rfind (" " , 0 , MAX_LABEL_LEN )
250+ if i != - 1 :
251+ first_row = label [:i ] + "\n "
252+ second_row = label [i + 1 :]
253+ if len (second_row ) > MAX_LABEL_LEN :
254+ j = second_row .rfind (" " , 0 , MAX_LABEL_LEN )
255+ if j != - 1 :
256+ second_row = second_row [:j + 1 ] + "..."
257+ else :
258+ second_row = second_row [:MAX_LABEL_LEN - 3 ] + "..."
259+ label = first_row + second_row
260+ else :
261+ label = label [:MAX_LABEL_LEN - 3 ] + "..."
262+
263+ anchor .setText (label )
264+ label_len = min (MAX_LABEL_LEN , len (label ))
265+ anchor .setColor (QColor (0 , 0 , 0 ))
266+
267+ x , y = point
268+ angle = np .rad2deg (np .arctan2 (y , x ))
269+ anchor .setPos (x * 1.025 , y * 1.025 )
270+
271+ if abs (angle ) < 90 :
272+ anchor .setAngle (angle )
273+ anchor .setAnchor ((0 , 0.5 ))
274+ else :
275+ anchor .setAngle (angle + 180 )
276+ anchor .setAnchor ((1 , 0.5 ))
277+
278+ anchor .textItem .setTextWidth (anchor .textItem .boundingRect ().width ())
279+ option = anchor .textItem .document ().defaultTextOption ()
280+ option .setAlignment (Qt .AlignRight )
281+ anchor .textItem .document ().setDefaultTextOption (option )
282+
283+ self .plot_widget .addItem (anchor )
284+ self .anchor_items .append (anchor )
285+
286+ self .padding = label_len * 0.0175
246287 self ._update_anchors_scatter_item (points )
247288
248289 def _update_anchors_scatter_item (self , points ):
@@ -282,9 +323,11 @@ class Warning(OWAnchorProjectionWidget.Warning):
282323 invalid_embedding = widget .Msg ("No projection for selected features" )
283324 removed_vars = widget .Msg ("Categorical variables with more than"
284325 " two values are not shown." )
326+ max_vars_selected = widget .Msg ("Maximum number of selected variables reached." )
285327
286328 def _add_controls (self ):
287- self .model_selected = VariableSelectionModel (self .selected_vars )
329+ self .model_selected = VariableSelectionModel (self .selected_vars ,
330+ max_vars = 20 )
288331 variables_selection (self .controlArea , self , self .model_selected )
289332 self .model_selected .selection_changed .connect (
290333 self .__model_selected_changed )
@@ -316,6 +359,10 @@ def vizrank_set_attrs(self, *attrs):
316359 self .model_selected .selection_changed .emit ()
317360
318361 def __model_selected_changed (self ):
362+ if self .model_selected .is_full ():
363+ self .Warning .max_vars_selected ()
364+ else :
365+ self .Warning .max_vars_selected .clear ()
319366 self .init_projection ()
320367 self .setup_plot ()
321368 self .commit ()
0 commit comments