46
46
import org .cytoscape .view .presentation .property .LineTypeVisualProperty ;
47
47
import org .cytoscape .view .presentation .property .values .LineType ;
48
48
import org .cytoscape .view .presentation .property .values .NodeShape ;
49
+ import org .cytoscape .view .vizmap .VisualMappingFunction ;
49
50
import org .cytoscape .view .vizmap .VisualMappingFunctionFactory ;
50
51
import org .cytoscape .view .vizmap .VisualStyle ;
51
52
import org .cytoscape .view .vizmap .events .VisualStyleChangeRecord ;
52
53
import org .cytoscape .view .vizmap .events .VisualStyleChangedEvent ;
53
54
import org .cytoscape .view .vizmap .mappings .BoundaryRangeValues ;
54
55
import org .cytoscape .view .vizmap .mappings .ContinuousMapping ;
56
+ import org .cytoscape .view .vizmap .mappings .ContinuousMappingPoint ;
55
57
import org .cytoscape .view .vizmap .mappings .DiscreteMapping ;
56
58
import org .cytoscape .view .vizmap .mappings .PassthroughMapping ;
57
59
import org .jcolorbrewer .ColorBrewer ;
@@ -181,6 +183,9 @@ public static NodeShape getDefaultNodeShape(ChartType chartType) {
181
183
return chartType == null || chartType == ChartType .RADIAL_HEAT_MAP ? ELLIPSE : RECTANGLE ;
182
184
}
183
185
186
+ /**
187
+ * Updates the whole EM style.
188
+ */
184
189
public void updateProperties (VisualStyle vs , EMStyleOptions options , CyCustomGraphics2 <?> chart ) {
185
190
eventHelper .silenceEventSource (vs );
186
191
@@ -208,7 +213,6 @@ public void updateProperties(VisualStyle vs, EMStyleOptions options, CyCustomGra
208
213
if (options .isPublicationReady ()) {
209
214
vs .removeVisualMappingFunction (BasicVisualLexicon .NODE_LABEL );
210
215
vs .setDefaultValue (BasicVisualLexicon .NODE_LABEL , "" );
211
- vs .removeVisualMappingFunction (BasicVisualLexicon .NETWORK_BACKGROUND_PAINT );
212
216
vs .setDefaultValue (BasicVisualLexicon .NETWORK_BACKGROUND_PAINT , Color .WHITE );
213
217
}
214
218
} finally {
@@ -217,6 +221,23 @@ public void updateProperties(VisualStyle vs, EMStyleOptions options, CyCustomGra
217
221
}
218
222
}
219
223
224
+ public void updateNodeChart (VisualStyle vs , EMStyleOptions options , CyCustomGraphics2 <?> chart ) {
225
+ eventHelper .silenceEventSource (vs );
226
+
227
+ try {
228
+ String chartName = chart != null ? chart .getDisplayName () : null ;
229
+ ChartType chartType = ChartType .toChartType (chartName );
230
+
231
+ setNodeChartDefaults (vs , chartType );
232
+ setNodeShapes (vs , options , chartType );
233
+ setNodeSize (vs , options , chartType );
234
+ setNodeChart (vs , chart );
235
+ } finally {
236
+ eventHelper .unsilenceEventSource (vs );
237
+ eventHelper .addEventPayload (vs , new VisualStyleChangeRecord (), VisualStyleChangedEvent .class );
238
+ }
239
+ }
240
+
220
241
@ SuppressWarnings ({ "rawtypes" , "unchecked" })
221
242
private void setNodeChart (VisualStyle vs , CyCustomGraphics2 <?> chart ) {
222
243
VisualLexicon lexicon = renderingEngineManager .getDefaultVisualLexicon ();
@@ -318,23 +339,53 @@ private void setNodeDefaults(VisualStyle vs, EMStyleOptions options, ChartType c
318
339
// Set the default node appearance
319
340
vs .setDefaultValue (NODE_FILL_COLOR , Colors .DEF_NODE_COLOR );
320
341
vs .setDefaultValue (NODE_BORDER_PAINT , Colors .DEF_NODE_BORDER_COLOR );
321
- vs .setDefaultValue (NODE_SHAPE , getDefaultNodeShape (chartType ));
322
- vs .setDefaultValue (NODE_SIZE , chartType == ChartType .RADIAL_HEAT_MAP ? MIN_NODE_SIZE : (MAX_NODE_SIZE + MIN_NODE_SIZE ) / 2 );
323
342
vs .setDefaultValue (NODE_BORDER_WIDTH , DEF_NODE_BORDER_WIDTH );
324
343
vs .setDefaultValue (NODE_TRANSPARENCY , DEF_NODE_TRANSPARENCY );
325
344
vs .setDefaultValue (NODE_BORDER_TRANSPARENCY , DEF_NODE_TRANSPARENCY );
326
345
vs .setDefaultValue (NODE_LABEL_TRANSPARENCY , DEF_NODE_TRANSPARENCY );
346
+ setNodeChartDefaults (vs , chartType );
347
+ }
348
+
349
+ /**
350
+ * Sets default node visual properties that can be affected by the chart type.
351
+ */
352
+ private void setNodeChartDefaults (VisualStyle vs , ChartType chartType ) {
353
+ vs .setDefaultValue (NODE_SHAPE , getDefaultNodeShape (chartType ));
354
+ vs .setDefaultValue (NODE_SIZE , chartType == ChartType .RADIAL_HEAT_MAP ? MIN_NODE_SIZE : (MAX_NODE_SIZE + MIN_NODE_SIZE ) / 2 );
327
355
}
328
356
357
+ @ SuppressWarnings ({ "unchecked" , "rawtypes" })
329
358
private void setNodeShapes (VisualStyle vs , EMStyleOptions options , ChartType chartType ) {
330
359
String prefix = options .getAttributePrefix ();
360
+ String columnName = Columns .NODE_GS_TYPE .with (prefix , null );
361
+ NodeShape enrShape = getDefaultNodeShape (chartType );
362
+
363
+ VisualMappingFunction <?, NodeShape > oldMapping = vs .getVisualMappingFunction (NODE_SHAPE );
331
364
332
- // Add mapping function for node shape
333
- DiscreteMapping <String , NodeShape > nodeShape = (DiscreteMapping <String , NodeShape >) dmFactory
334
- .createVisualMappingFunction (Columns .NODE_GS_TYPE .with (prefix , null ), String .class , NODE_SHAPE );
335
- nodeShape .putMapValue (Columns .NODE_GS_TYPE_ENRICHMENT , getDefaultNodeShape (chartType ));
336
- nodeShape .putMapValue (Columns .NODE_GS_TYPE_SIGNATURE , SIGNATURE_NODE_SHAPE );
337
- vs .addVisualMappingFunction (nodeShape );
365
+ // This is done for performance optimization only!
366
+ boolean update = oldMapping instanceof DiscreteMapping == false ;
367
+
368
+ if (!update ) {
369
+ // Also test the mapped column name
370
+ update = !columnName .equals (oldMapping .getMappingColumnName ());
371
+
372
+ if (!update ) {
373
+ // Finally test the mapping values
374
+ Object enrVal = ((DiscreteMapping ) oldMapping ).getMapValue (Columns .NODE_GS_TYPE_ENRICHMENT );
375
+ Object sigVal = ((DiscreteMapping ) oldMapping ).getMapValue (Columns .NODE_GS_TYPE_SIGNATURE );
376
+
377
+ update = !enrShape .equals (enrVal ) || !SIGNATURE_NODE_SHAPE .equals (sigVal );
378
+ }
379
+ }
380
+
381
+ if (update ) {
382
+ // Add mapping function for node shape
383
+ DiscreteMapping <String , NodeShape > nodeShape = (DiscreteMapping <String , NodeShape >) dmFactory
384
+ .createVisualMappingFunction (columnName , String .class , NODE_SHAPE );
385
+ nodeShape .putMapValue (Columns .NODE_GS_TYPE_ENRICHMENT , enrShape );
386
+ nodeShape .putMapValue (Columns .NODE_GS_TYPE_SIGNATURE , SIGNATURE_NODE_SHAPE );
387
+ vs .addVisualMappingFunction (nodeShape );
388
+ }
338
389
}
339
390
340
391
private void setNodeBorderColors (VisualStyle vs , EMStyleOptions options ) {
@@ -440,18 +491,54 @@ private void setNodeTooltip(VisualStyle vs, EMStyleOptions options) {
440
491
vs .addVisualMappingFunction (nodeLabel );
441
492
}
442
493
494
+ @ SuppressWarnings ("rawtypes" )
443
495
private void setNodeSize (VisualStyle vs , EMStyleOptions options , ChartType chartType ) {
444
496
if (chartType == null || chartType == ChartType .RADIAL_HEAT_MAP ) {
445
497
String prefix = options .getAttributePrefix ();
446
- ContinuousMapping <Integer , Double > nodeSize = (ContinuousMapping <Integer , Double >) cmFactory
447
- .createVisualMappingFunction (Columns .NODE_GS_SIZE .with (prefix ,null ), Integer .class , NODE_SIZE );
448
-
449
- BoundaryRangeValues <Double > bv0 = new BoundaryRangeValues <Double >(MIN_NODE_SIZE , MIN_NODE_SIZE , MIN_NODE_SIZE );
450
- BoundaryRangeValues <Double > bv1 = new BoundaryRangeValues <Double >(MAX_NODE_SIZE , MAX_NODE_SIZE , MAX_NODE_SIZE );
451
- nodeSize .addPoint (10 , bv0 );
452
- nodeSize .addPoint (474 , bv1 );
453
-
454
- vs .addVisualMappingFunction (nodeSize );
498
+ String columnName = Columns .NODE_GS_SIZE .with (prefix , null );
499
+ int val0 = 10 ;
500
+ int val1 = 474 ;
501
+
502
+ VisualMappingFunction <?, Double > oldMapping = vs .getVisualMappingFunction (NODE_SIZE );
503
+
504
+ // This is done for performance optimization only!
505
+ boolean update = oldMapping instanceof ContinuousMapping == false ;
506
+
507
+ if (!update ) {
508
+ try {
509
+ // Also test the mapped column name and number of points
510
+ update = !columnName .equals (oldMapping .getMappingColumnName ())
511
+ || ((ContinuousMapping ) oldMapping ).getPointCount () != 2 ;
512
+
513
+ if (!update ) {
514
+ // And the mapping values
515
+ ContinuousMappingPoint pt0 = ((ContinuousMapping ) oldMapping ).getPoint (0 );
516
+ ContinuousMappingPoint pt1 = ((ContinuousMapping ) oldMapping ).getPoint (1 );
517
+
518
+ update = val0 != (Integer ) pt0 .getValue ();
519
+ update = update || val1 != (Integer ) pt1 .getValue ();
520
+
521
+ if (!update ) // Finally test the boundary ranges
522
+ update = MIN_NODE_SIZE != pt0 .getRange ().equalValue
523
+ || MAX_NODE_SIZE != pt1 .getRange ().equalValue ;
524
+ }
525
+ } catch (Exception e ) {
526
+ e .printStackTrace ();
527
+ update = true ;
528
+ }
529
+ }
530
+
531
+ if (update ) {
532
+ ContinuousMapping <Integer , Double > mapping = (ContinuousMapping <Integer , Double >) cmFactory
533
+ .createVisualMappingFunction (columnName , Integer .class , NODE_SIZE );
534
+
535
+ BoundaryRangeValues <Double > bv0 = new BoundaryRangeValues <>(MIN_NODE_SIZE , MIN_NODE_SIZE , MIN_NODE_SIZE );
536
+ BoundaryRangeValues <Double > bv1 = new BoundaryRangeValues <>(MAX_NODE_SIZE , MAX_NODE_SIZE , MAX_NODE_SIZE );
537
+ mapping .addPoint (val0 , bv0 );
538
+ mapping .addPoint (val1 , bv1 );
539
+
540
+ vs .addVisualMappingFunction (mapping );
541
+ }
455
542
} else {
456
543
vs .removeVisualMappingFunction (NODE_SIZE );
457
544
}
0 commit comments