in Sources/Visualization/Microsoft.Psi.Visualization.Windows/ViewModels/StreamTreeNode.cs [423:507]
public virtual List<VisualizerMetadata> GetCompatibleVisualizers(
VisualizationPanel visualizationPanel = null,
bool? isUniversal = null,
bool? isInNewPanel = null)
{
var results = new List<VisualizerMetadata>();
var nodeDataType = VisualizationContext.Instance.GetDataType(this.DataTypeName);
var comparer = new VisualizerMetadataComparer(nodeDataType);
// If we're looking for visualizers that fit in any panel
if (visualizationPanel == null)
{
results.AddRange(VisualizationContext.Instance.PluginMap.Visualizers.Where(v =>
(nodeDataType == v.DataType || nodeDataType.IsSubclassOf(v.DataType)) &&
(!isInNewPanel.HasValue || v.IsInNewPanel == isInNewPanel.Value) &&
(!isUniversal.HasValue || v.IsUniversalVisualizer == isUniversal))
.OrderBy(v => v, comparer));
}
else
{
// o/w find out the compatible panel types
results.AddRange(VisualizationContext.Instance.PluginMap.Visualizers.Where(v =>
visualizationPanel.CompatiblePanelTypes.Contains(v.VisualizationPanelType) &&
(nodeDataType == v.DataType || nodeDataType.IsSubclassOf(v.DataType)) &&
(!isInNewPanel.HasValue || v.IsInNewPanel == isInNewPanel.Value) &&
(!isUniversal.HasValue || v.IsUniversalVisualizer == isUniversal))
.OrderBy(v => v, comparer));
}
// Special-case: for streams of type Dictionary<TKey, numeric>, create the corresponding
// numeric series visualizer, by using a dictionary-key-to-string adapter.
if ((!isUniversal.HasValue || !isUniversal.Value) &&
(visualizationPanel == null || visualizationPanel.CompatiblePanelTypes.Contains(VisualizationPanelType.Timeline)))
{
if (nodeDataType.IsGenericType && nodeDataType.GetGenericTypeDefinition() == typeof(Dictionary<,>))
{
var genericArguments = nodeDataType.GetGenericArguments();
var numericSeriesVisualizationObjectType = NumericSeriesVisualizationObject.GetSeriesVisualizationObjectTypeByNumericType(genericArguments[1]);
if (numericSeriesVisualizationObjectType != null)
{
if (visualizationPanel == null)
{
var metadata = VisualizationContext.Instance.PluginMap.Visualizers
.FirstOrDefault(v =>
(v.VisualizationObjectType == numericSeriesVisualizationObjectType) &&
(!isInNewPanel.HasValue || v.IsInNewPanel == isInNewPanel.Value))
.GetCloneWithNewStreamAdapterType(typeof(DictionaryKeyToStringAdapter<,>).MakeGenericType(genericArguments));
results.Add(metadata);
}
else
{
var metadata = VisualizationContext.Instance.PluginMap.Visualizers
.FirstOrDefault(v =>
visualizationPanel.CompatiblePanelTypes.Contains(v.VisualizationPanelType) &&
(v.VisualizationObjectType == numericSeriesVisualizationObjectType) &&
(!isInNewPanel.HasValue || v.IsInNewPanel == isInNewPanel.Value))
.GetCloneWithNewStreamAdapterType(typeof(DictionaryKeyToStringAdapter<,>).MakeGenericType(genericArguments));
results.Add(metadata);
}
}
}
}
// Special-case: the latency visualizer b/c it's not detectable by data type
// (the adapter to make it work will be added automatically later in
// CustomizeVisualizerMetadata). Latency visualizer is only compatible with
// timeline visualization panels.
if (isUniversal.HasValue && isUniversal.Value)
{
if (isInNewPanel.HasValue && isInNewPanel.Value)
{
results.Add(VisualizationContext.Instance.PluginMap.Visualizers.FirstOrDefault(v => v.CommandText == ContextMenuName.VisualizeLatencyInNewPanel));
}
else if (visualizationPanel is TimelineVisualizationPanel)
{
results.Add(VisualizationContext.Instance.PluginMap.Visualizers.FirstOrDefault(v => v.CommandText == ContextMenuName.VisualizeLatency));
}
}
// Customize each visualizer metadata.
this.InsertCustomAdapters(results);
return results;
}