private async Task <Visualization> GetVisualizationFromDataSet(
            NetworkDataSet dataSet,
            VisualizationType type)
        {
            if (type == VisualizationType.MultiLayer_Diagonal)
            {
                var diagonal = dataSet.Visualizations
                               .FirstOrDefault(v => v.Type == VisualizationType.MultiLayer_Diagonal);

                if (diagonal is null)
                {
                    var request = new MultilayerRequest
                    {
                        EdgeList = dataSet.EdgeList,
                        Type     = VisualizationType.MultiLayer_Diagonal
                    };
                    diagonal = await VisualizeMultilayer(request);

                    dataSet.Visualizations.Add(diagonal);
                    await _ctx.SaveChangesAsync();
                }

                return(diagonal);
            }
            else if (type == VisualizationType.MultiLayer_Slices)
            {
                var slices = dataSet.Visualizations
                             .FirstOrDefault(v => v.Type == VisualizationType.MultiLayer_Slices);

                if (slices is null)
                {
                    var request = new MultilayerRequest
                    {
                        EdgeList = dataSet.EdgeList,
                        Type     = VisualizationType.MultiLayer_Slices
                    };
                    slices = await VisualizeMultilayer(request);

                    dataSet.Visualizations.Add(slices);
                    await _ctx.SaveChangesAsync();
                }

                return(slices);
            }

            throw new NotSupportedException($"Visualization type '{type}' is not supported for datasets.");
        }
        public async Task <Visualization> VisualizeMultilayer(MultilayerRequest request)
        {
            var json    = JsonConvert.SerializeObject(request);
            var content = new StringContent(json, Encoding.UTF8, "application/json");
            var message = string.Empty;
            var uri     = $"{_baseUrl}/api/multi-layer";

            if (request.Type == VisualizationType.MultiLayer_Diagonal)
            {
                uri += "/diagonal";
            }
            else if (request.Type == VisualizationType.MultiLayer_Slices)
            {
                uri += "/slices";
            }
            else
            {
                message = $"Visualization type '{request.Type}' is not supported.";
                throw new NotSupportedException(message);
            }

            for (var i = 0; i < MAX_RETRY; i++)
            {
                var client   = GetClient();
                var response = await client.PostAsync(uri, content);

                if (response.IsSuccessStatusCode)
                {
                    var svg = await response.Content.ReadAsStringAsync();

                    return(new Visualization
                    {
                        Title = request.Type.ToTitle(),
                        Type = request.Type,
                        SvgImage = svg
                    });
                }
                else
                {
                    message = await HandleError(response);
                }
            }

            throw new ArgumentException(message);
        }
        private async Task <Visualization> GetVisualizationFromAnalysis(Analysis analysis, VisualizationType type)
        {
            var viz = analysis.Visualizations.FirstOrDefault(a => a.Type == type);

            if (viz is null)
            {
                if (type.IsMultiLayer())
                {
                    if (type == VisualizationType.MultiLayer_Diagonal || type == VisualizationType.MultiLayer_Slices)
                    {
                        viz = analysis.Request.DataSet.Visualizations.FirstOrDefault(v => v.Type == type);

                        if (viz is null)
                        {
                            viz = await VisualizeMultilayer(new MultilayerRequest
                            {
                                EdgeList = analysis.Request.DataSet.EdgeList,
                                Type     = type
                            });

                            analysis.Request.DataSet.Visualizations.Add(viz);
                        }
                    }
                    else
                    {
                        viz = await VisualizeMultilayer(new MultilayerRequest
                        {
                            EdgeList = analysis.Request.DataSet.EdgeList,
                            Type     = type
                        });
                    }
                }
                else if (type.IsMultiLayerCommunities())
                {
                    var request = new MultilayerCommunitiesRequest
                    {
                        EdgeList      = analysis.Request.DataSet.EdgeList,
                        CommunityList = analysis.Result.CommunityList,
                        Type          = type
                    };
                    viz = await VisualizeMultilayerCommunities(request);
                }
                else if (type.IsSingleLayer())
                {
                    viz = await VisualizeSingleLayer(new SingleLayerRequest
                    {
                        EdgeList = analysis.Result.AnalyzedNetworkEdgeList,
                        Type     = type
                    });
                }
                else if (type.IsSingleLayerCommunities())
                {
                    viz = await VisualizeSingleLayerCommunity(new SingleLayerCommunityRequest
                    {
                        EdgeList      = analysis.Result.AnalyzedNetworkEdgeList,
                        CommunityList = analysis.Result.CommunityList,
                        Type          = type
                    });
                }
                else if (type == VisualizationType.Barplot)
                {
                    var communities = analysis.Result.ActorToCommunity.Values
                                      .Distinct()
                                      .OrderBy(c => c);
                    var communitiesCount = communities
                                           .Select(c => analysis.Result.ActorToCommunity.Where(a => a.Value == c).Count());
                    var request = new BarplotRequest <int, int>
                    {
                        X      = communities,
                        Y      = communitiesCount,
                        Labels = communities.Select(c => "C" + c),
                        XLabel = "Community",
                        YLabel = "Actor Count",
                        Params = new BarplotRequestParameters
                        {
                            ColorCommunities = true
                        }
                    };
                    viz = await VisualizeBarplot(request);

                    viz.Title = "Communities Count - Barplot";
                }
                else if (type == VisualizationType.Treemap)
                {
                    var communities = analysis.Result.ActorToCommunity.Values
                                      .Distinct()
                                      .OrderByDescending(c => c);
                    var communitiesCount = communities
                                           .Select(c => analysis.Result.ActorToCommunity.Where(a => a.Value == c)
                                                   .Count());
                    var request = new TreemapRequest <int>
                    {
                        Label = communities.Select(c => "C" + c),
                        Sizes = communitiesCount,
                        Type  = type
                    };
                    viz = await VisualizeTreemap(request);

                    viz.Title = "Communities Count - Treemap";
                }
                else if (type == VisualizationType.MultiLayer_Slices)
                {
                    var request = new MultilayerRequest
                    {
                        EdgeList = analysis.Request.DataSet.EdgeList,
                        Type     = type
                    };
                    viz = await VisualizeMultilayer(request);
                }
                else if (type == VisualizationType.MultiLayer_Slices_Communities)
                {
                    var request = new MultilayerCommunitiesRequest
                    {
                        EdgeList      = analysis.Request.DataSet.EdgeList,
                        CommunityList = analysis.Result.CommunityList,
                        Type          = type
                    };
                    viz = await VisualizeMultilayerCommunities(request);
                }

                if (type != VisualizationType.MultiLayer_Diagonal && type != VisualizationType.MultiLayer_Slices)
                {
                    analysis.Visualizations.Add(viz);
                }

                await _ctx.SaveChangesAsync();
            }
            return(viz);
        }