From 1a044dd798e9dae3e4d72b0470ab944e192932c7 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Fri, 28 Dec 2018 02:26:33 +0000 Subject: [PATCH] Show some statistics in pie charts. --- .../Controllers/StatsController.cs | 278 +++++++++++++++++- .../DiscImageChef.Server.csproj | 4 + DiscImageChef.Server/Views/Stats/Index.cshtml | 79 ++++- DiscImageChef.Server/packages.config | 1 + 4 files changed, 359 insertions(+), 3 deletions(-) diff --git a/DiscImageChef.Server/Controllers/StatsController.cs b/DiscImageChef.Server/Controllers/StatsController.cs index db5f220d5..24ed4106a 100644 --- a/DiscImageChef.Server/Controllers/StatsController.cs +++ b/DiscImageChef.Server/Controllers/StatsController.cs @@ -43,6 +43,8 @@ using System.Xml.Serialization; using DiscImageChef.CommonTypes.Interop; using DiscImageChef.CommonTypes.Metadata; using DiscImageChef.Server.Models; +using Highsoft.Web.Mvc.Charts; +using Filter = DiscImageChef.Server.Models.Filter; using OperatingSystem = DiscImageChef.Server.Models.OperatingSystem; using PlatformID = DiscImageChef.CommonTypes.Interop.PlatformID; using Version = DiscImageChef.Server.Models.Version; @@ -105,6 +107,71 @@ namespace DiscImageChef.Server.Controllers }); ViewBag.repOperatingSystems = operatingSystems.OrderBy(os => os.name).ToList(); + + List osPieData = new List(); + + decimal totalOsCount = ctx.OperatingSystems.Sum(o => o.Count); + foreach(string os in ctx.OperatingSystems.Select(o => o.Name).Distinct().ToList()) + { + decimal osCount = ctx.OperatingSystems.Where(o => o.Name == os).Sum(o => o.Count); + + osPieData.Add(new PieSeriesData + { + Name = + DetectOS.GetPlatformName((PlatformID)Enum.Parse(typeof(PlatformID), + os)), + Y = (double?)(osCount / totalOsCount), + Sliced = os == "Linux", + Selected = os == "Linux" + }); + } + + ViewData["osPieData"] = osPieData; + + List linuxPieData = new List(); + + decimal linuxCount = ctx.OperatingSystems.Where(o => o.Name == PlatformID.Linux.ToString()) + .Sum(o => o.Count); + foreach(OperatingSystem version in + ctx.OperatingSystems.Where(o => o.Name == PlatformID.Linux.ToString())) + linuxPieData.Add(new PieSeriesData + { + Name = + $"{DetectOS.GetPlatformName(PlatformID.Linux, version.Version)}{(string.IsNullOrEmpty(version.Version) ? "" : " ")}{version.Version}", + Y = (double?)(version.Count / linuxCount) + }); + + ViewData["linuxPieData"] = linuxPieData; + + List macosPieData = new List(); + + decimal macosCount = ctx.OperatingSystems.Where(o => o.Name == PlatformID.MacOSX.ToString()) + .Sum(o => o.Count); + foreach(OperatingSystem version in + ctx.OperatingSystems.Where(o => o.Name == PlatformID.MacOSX.ToString())) + macosPieData.Add(new PieSeriesData + { + Name = + $"{DetectOS.GetPlatformName(PlatformID.MacOSX, version.Version)}{(string.IsNullOrEmpty(version.Version) ? "" : " ")}{version.Version}", + Y = (double?)(version.Count / macosCount) + }); + + ViewData["macosPieData"] = macosPieData; + + List windowsPieData = new List(); + + decimal windowsCount = ctx.OperatingSystems.Where(o => o.Name == PlatformID.Win32NT.ToString()) + .Sum(o => o.Count); + foreach(OperatingSystem version in + ctx.OperatingSystems.Where(o => o.Name == PlatformID.Win32NT.ToString())) + windowsPieData.Add(new PieSeriesData + { + Name = + $"{DetectOS.GetPlatformName(PlatformID.Win32NT, version.Version)}{(string.IsNullOrEmpty(version.Version) ? "" : " ")}{version.Version}", + Y = (double?)(version.Count / windowsCount) + }); + + ViewData["windowsPieData"] = windowsPieData; } if(ctx.Versions.Any()) @@ -118,6 +185,20 @@ namespace DiscImageChef.Server.Controllers }); ViewBag.repVersions = versions.OrderBy(ver => ver.name).ToList(); + + decimal totalVersionCount = ctx.Versions.Sum(o => o.Count); + + ViewData["versionsPieData"] = ctx.Versions.Select(version => new PieSeriesData + { + Name = + version.Value == "previous" + ? "Previous than 3.4.99.0" + : version.Value, + Y = (double?)(version.Count / + totalVersionCount), + Sliced = version.Value == "previous", + Selected = version.Value == "previous" + }).ToList(); } if(ctx.Commands.Any()) @@ -157,18 +238,134 @@ namespace DiscImageChef.Server.Controllers ctx.Commands.FirstOrDefault(c => c.Name == "convert-image")?.Count.ToString() ?? "0"; ViewBag.lblImageInfo = ctx.Commands.FirstOrDefault(c => c.Name == "image-info")?.Count.ToString() ?? "0"; + + decimal totalCommandCount = ctx.Commands.Sum(o => o.Count); + + ViewData["commandsPieData"] = ctx + .Commands.Select(command => new PieSeriesData + { + Name = command.Name, + Y = (double?)(command.Count / + totalCommandCount), + Sliced = command.Name == "analyze", + Selected = command.Name == "analyze" + }).ToList(); } - if(ctx.Filters.Any()) ViewBag.repFilters = ctx.Filters.OrderBy(filter => filter.Name).ToList(); + if(ctx.Filters.Any()) + { + ViewBag.repFilters = ctx.Filters.OrderBy(filter => filter.Name).ToList(); + + List filtersPieData = new List(); + + decimal totalFiltersCount = ctx.Filters.Sum(o => o.Count); + foreach(Filter filter in ctx.Filters.ToList()) + filtersPieData.Add(new PieSeriesData + { + Name = filter.Name, + Y = (double?)(filter.Count / totalFiltersCount), + Sliced = filter.Name == "No filter", + Selected = filter.Name == "No filter" + }); + + ViewData["filtersPieData"] = filtersPieData; + } if(ctx.MediaFormats.Any()) + { ViewBag.repMediaImages = ctx.MediaFormats.OrderBy(filter => filter.Name).ToList(); - if(ctx.Partitions.Any()) ViewBag.repPartitions = ctx.Partitions.OrderBy(filter => filter.Name).ToList(); + List formatsPieData = new List(); + + decimal totalFormatsCount = ctx.MediaFormats.Sum(o => o.Count); + decimal top10FormatCount = 0; + + foreach(MediaFormat format in ctx.MediaFormats.OrderByDescending(o => o.Count).Take(10)) + { + top10FormatCount += format.Count; + + formatsPieData.Add(new PieSeriesData + { + Name = format.Name, Y = (double?)(format.Count / totalFormatsCount) + }); + } + + formatsPieData.Add(new PieSeriesData + { + Name = "Other", + Y = (double?)((totalFormatsCount - top10FormatCount) / + totalFormatsCount), + Sliced = true, + Selected = true + }); + + ViewData["formatsPieData"] = formatsPieData; + } + + if(ctx.Partitions.Any()) + { + ViewBag.repPartitions = ctx.Partitions.OrderBy(filter => filter.Name).ToList(); + + List partitionsPieData = new List(); + + decimal totalPartitionsCount = ctx.Partitions.Sum(o => o.Count); + decimal top10PartitionCount = 0; + + foreach(Partition partition in ctx.Partitions.OrderByDescending(o => o.Count).Take(10)) + { + top10PartitionCount += partition.Count; + + partitionsPieData.Add(new PieSeriesData + { + Name = partition.Name, + Y = (double?)(partition.Count / totalPartitionsCount) + }); + } + + partitionsPieData.Add(new PieSeriesData + { + Name = "Other", + Y = (double?)((totalPartitionsCount - top10PartitionCount) / + totalPartitionsCount), + Sliced = true, + Selected = true + }); + + ViewData["partitionsPieData"] = partitionsPieData; + } if(ctx.Filesystems.Any()) + { ViewBag.repFilesystems = ctx.Filesystems.OrderBy(filter => filter.Name).ToList(); + List filesystemsPieData = new List(); + + decimal totalFilesystemsCount = ctx.Filesystems.Sum(o => o.Count); + decimal top10FilesystemCount = 0; + + foreach(Filesystem filesystem in ctx.Filesystems.OrderByDescending(o => o.Count).Take(10)) + { + top10FilesystemCount += filesystem.Count; + + filesystemsPieData.Add(new PieSeriesData + { + Name = filesystem.Name, + Y = (double?)(filesystem.Count / totalFilesystemsCount) + }); + } + + filesystemsPieData.Add(new PieSeriesData + { + Name = "Other", + Y = (double?)((totalFilesystemsCount - top10FilesystemCount) / + totalFilesystemsCount), + Sliced = true, + Selected = true + }); + + ViewData["filesystemsPieData"] = filesystemsPieData; + } + if(ctx.Medias.Any()) { realMedia = new List(); @@ -192,12 +389,73 @@ namespace DiscImageChef.Server.Controllers } if(realMedia.Count > 0) + { ViewBag.repRealMedia = realMedia.OrderBy(media => media.Type).ThenBy(media => media.SubType).ToList(); + List realMediaPieData = new List(); + + decimal totalRealMediaCount = realMedia.Sum(o => o.Count); + decimal top10RealMediaCount = 0; + + foreach(MediaItem realMediaItem in realMedia.OrderByDescending(o => o.Count).Take(10)) + { + top10RealMediaCount += realMediaItem.Count; + + realMediaPieData.Add(new PieSeriesData + { + Name = $"{realMediaItem.Type} ({realMediaItem.SubType})", + Y = (double?)(realMediaItem.Count / totalRealMediaCount) + }); + } + + realMediaPieData.Add(new PieSeriesData + { + Name = "Other", + Y = (double?)((totalRealMediaCount - top10RealMediaCount) / + totalRealMediaCount), + Sliced = true, + Selected = true + }); + + ViewData["realMediaPieData"] = realMediaPieData; + } + if(virtualMedia.Count > 0) + { ViewBag.repVirtualMedia = virtualMedia.OrderBy(media => media.Type).ThenBy(media => media.SubType).ToList(); + + List virtualMediaPieData = new List(); + + decimal totalVirtualMediaCount = virtualMedia.Sum(o => o.Count); + decimal top10VirtualMediaCount = 0; + + foreach(MediaItem virtualMediaItem in virtualMedia.OrderByDescending(o => o.Count).Take(10)) + { + top10VirtualMediaCount += virtualMediaItem.Count; + + virtualMediaPieData.Add(new PieSeriesData + { + Name = + $"{virtualMediaItem.Type} ({virtualMediaItem.SubType})", + Y = (double?)(virtualMediaItem.Count / + totalVirtualMediaCount) + }); + } + + virtualMediaPieData.Add(new PieSeriesData + { + Name = "Other", + Y = (double?) + ((totalVirtualMediaCount - top10VirtualMediaCount) / + totalVirtualMediaCount), + Sliced = true, + Selected = true + }); + + ViewData["virtualMediaPieData"] = virtualMediaPieData; + } } if(ctx.DeviceStats.Any()) @@ -255,6 +513,22 @@ namespace DiscImageChef.Server.Controllers ViewBag.repDevices = devices.OrderBy(device => device.Manufacturer).ThenBy(device => device.Model) .ThenBy(device => device.Revision).ThenBy(device => device.Bus) .ToList(); + + ViewData["devicesBusPieData"] = (from deviceBus in devices.Select(d => d.Bus).Distinct() + let deviceBusCount = devices.Count(d => d.Bus == deviceBus) + select new PieSeriesData + { + Name = deviceBus, + Y = deviceBusCount / (double)devices.Count + }).ToList(); + + ViewData["devicesManufacturerPieData"] = + (from manufacturer in + devices.Where(d => d.Manufacturer != null).Select(d => d.Manufacturer.ToLowerInvariant()) + .Distinct() + let manufacturerCount = devices.Count(d => d.Manufacturer?.ToLowerInvariant() == manufacturer) + select new PieSeriesData {Name = manufacturer, Y = manufacturerCount / (double)devices.Count}) + .ToList(); } } catch(Exception) diff --git a/DiscImageChef.Server/DiscImageChef.Server.csproj b/DiscImageChef.Server/DiscImageChef.Server.csproj index cf7d58727..15771a2d2 100644 --- a/DiscImageChef.Server/DiscImageChef.Server.csproj +++ b/DiscImageChef.Server/DiscImageChef.Server.csproj @@ -73,6 +73,10 @@ ..\packages\Google.Protobuf.3.5.1\lib\net45\Google.Protobuf.dll True + + ..\packages\Highsoft.Highcharts.6.2.0.67\lib\net40\Highcharts.Web.Mvc.dll + True + ..\packages\Markdig.0.15.5\lib\net40\Markdig.dll True diff --git a/DiscImageChef.Server/Views/Stats/Index.cshtml b/DiscImageChef.Server/Views/Stats/Index.cshtml index 05f5fcc79..a052db444 100644 --- a/DiscImageChef.Server/Views/Stats/Index.cshtml +++ b/DiscImageChef.Server/Views/Stats/Index.cshtml @@ -1,5 +1,7 @@ @using DiscImageChef.CommonTypes.Metadata @using DiscImageChef.Server.Models +@using Highsoft.Web.Mvc.Charts +@using Chart = Highsoft.Web.Mvc.Charts.Chart @using Filter = DiscImageChef.Server.Models.Filter @{ ViewBag.Title = "DiscImageChef Statistics"; @@ -28,6 +30,8 @@ gtag('config', 'UA-111466173-1'); + +

@@ -41,9 +45,22 @@


+ @if(ViewBag.repOperatingSystems != null) {
+
+
+
+
+
+
+
+
@foreach(NameValueStats os in ViewBag.repOperatingSystems) { @@ -60,6 +77,9 @@ @if(ViewBag.repVersions != null) {
+
+
@foreach(NameValueStats version in ViewBag.repVersions) { @@ -74,6 +94,10 @@ }
+
+
+

Commands run:

analyze command has been run @ViewBag.lblAnalyze times
@@ -102,6 +126,9 @@ @if(ViewBag.repFilters != null) {

+
+

Filters found:

@@ -126,6 +153,9 @@ @if(ViewBag.repMediaImages != null) {
+
+

Media image formats found:

@@ -150,6 +180,9 @@ @if(ViewBag.repPartitions != null) {
+
+

Partition schemes found:

@@ -174,6 +207,9 @@ @if(ViewBag.repFilesystems != null) {
+
+

Filesystems found:

@@ -198,6 +234,9 @@ @if(ViewBag.repVirtualMedia != null) {
+
+

Media types found in images:

@@ -226,6 +265,9 @@ @if(ViewBag.repRealMedia != null) {
+
+

Media types found in devices:

@@ -254,6 +296,12 @@ @if(ViewBag.repDevices != null) {
+
+
+
+

Found devices:

@@ -312,4 +360,33 @@ - \ No newline at end of file + + +@(Html.Highsoft().GetHighcharts(new Highcharts {Chart = new Chart {PlotBackgroundColor = null, PlotBorderWidth = null, PlotShadow = new Shadow {Enabled = true}}, Title = new Title {Text = "Operating system usage"}, Tooltip = new Tooltip {PointFormat = "{series.name}: {point.percentage:.1f}%"}, PlotOptions = new PlotOptions {Pie = new PlotOptionsPie {AllowPointSelect = true, Cursor = PlotOptionsPieCursor.Pointer, DataLabels = new PlotOptionsPieDataLabels {Enabled = true, Format = "{point.name}: {point.percentage:.1f} %"}}}, Series = new List {new PieSeries {Name = "Percentage:", Data = ViewData["osPieData"] as List}}}, "osChart", false)) + +@(Html.Highsoft().GetHighcharts(new Highcharts {Chart = new Chart {PlotBackgroundColor = null, PlotBorderWidth = null, PlotShadow = new Shadow {Enabled = true}}, Title = new Title {Text = "Linux versions"}, Tooltip = new Tooltip {PointFormat = "{series.name}: {point.percentage:.1f}%"}, PlotOptions = new PlotOptions {Pie = new PlotOptionsPie {AllowPointSelect = true, Cursor = PlotOptionsPieCursor.Pointer, DataLabels = new PlotOptionsPieDataLabels {Enabled = true, Format = "{point.name}: {point.percentage:.1f} %"}}}, Series = new List {new PieSeries {Name = "Percentage:", Data = ViewData["linuxPieData"] as List}}}, "linuxChart", false)) + +@(Html.Highsoft().GetHighcharts(new Highcharts {Chart = new Chart {PlotBackgroundColor = null, PlotBorderWidth = null, PlotShadow = new Shadow {Enabled = true}}, Title = new Title {Text = "macOS versions"}, Tooltip = new Tooltip {PointFormat = "{series.name}: {point.percentage:.1f}%"}, PlotOptions = new PlotOptions {Pie = new PlotOptionsPie {AllowPointSelect = true, Cursor = PlotOptionsPieCursor.Pointer, DataLabels = new PlotOptionsPieDataLabels {Enabled = true, Format = "{point.name}: {point.percentage:.1f} %"}}}, Series = new List {new PieSeries {Name = "Percentage:", Data = ViewData["macosPieData"] as List}}}, "macosChart", false)) + +@(Html.Highsoft().GetHighcharts(new Highcharts {Chart = new Chart {PlotBackgroundColor = null, PlotBorderWidth = null, PlotShadow = new Shadow {Enabled = true}}, Title = new Title {Text = "Windows versions"}, Tooltip = new Tooltip {PointFormat = "{series.name}: {point.percentage:.1f}%"}, PlotOptions = new PlotOptions {Pie = new PlotOptionsPie {AllowPointSelect = true, Cursor = PlotOptionsPieCursor.Pointer, DataLabels = new PlotOptionsPieDataLabels {Enabled = true, Format = "{point.name}: {point.percentage:.1f} %"}}}, Series = new List {new PieSeries {Name = "Percentage:", Data = ViewData["windowsPieData"] as List}}}, "windowsChart", false)) + +@(Html.Highsoft().GetHighcharts(new Highcharts {Chart = new Chart {PlotBackgroundColor = null, PlotBorderWidth = null, PlotShadow = new Shadow {Enabled = true}}, Title = new Title {Text = "DiscImageChef versions"}, Tooltip = new Tooltip {PointFormat = "{series.name}: {point.percentage:.1f}%"}, PlotOptions = new PlotOptions {Pie = new PlotOptionsPie {AllowPointSelect = true, Cursor = PlotOptionsPieCursor.Pointer, DataLabels = new PlotOptionsPieDataLabels {Enabled = true, Format = "{point.name}: {point.percentage:.1f} %"}}}, Series = new List {new PieSeries {Name = "Percentage:", Data = ViewData["versionsPieData"] as List}}}, "versionsChart", false)) + +@(Html.Highsoft().GetHighcharts(new Highcharts {Chart = new Chart {PlotBackgroundColor = null, PlotBorderWidth = null, PlotShadow = new Shadow {Enabled = true}}, Title = new Title {Text = "Commands run"}, Tooltip = new Tooltip {PointFormat = "{series.name}: {point.percentage:.1f}%"}, PlotOptions = new PlotOptions {Pie = new PlotOptionsPie {AllowPointSelect = true, Cursor = PlotOptionsPieCursor.Pointer, DataLabels = new PlotOptionsPieDataLabels {Enabled = true, Format = "{point.name}: {point.percentage:.1f} %"}}}, Series = new List {new PieSeries {Name = "Percentage:", Data = ViewData["commandsPieData"] as List}}}, "commandsChart", false)) + +@(Html.Highsoft().GetHighcharts(new Highcharts {Chart = new Chart {PlotBackgroundColor = null, PlotBorderWidth = null, PlotShadow = new Shadow {Enabled = true}}, Title = new Title {Text = "Filters found"}, Tooltip = new Tooltip {PointFormat = "{series.name}: {point.percentage:.1f}%"}, PlotOptions = new PlotOptions {Pie = new PlotOptionsPie {AllowPointSelect = true, Cursor = PlotOptionsPieCursor.Pointer, DataLabels = new PlotOptionsPieDataLabels {Enabled = true, Format = "{point.name}: {point.percentage:.1f} %"}}}, Series = new List {new PieSeries {Name = "Percentage:", Data = ViewData["filtersPieData"] as List}}}, "filtersChart", false)) + +@(Html.Highsoft().GetHighcharts(new Highcharts {Chart = new Chart {PlotBackgroundColor = null, PlotBorderWidth = null, PlotShadow = new Shadow {Enabled = true}}, Title = new Title {Text = "Top 10 media image formats found"}, Tooltip = new Tooltip {PointFormat = "{series.name}: {point.percentage:.1f}%"}, PlotOptions = new PlotOptions {Pie = new PlotOptionsPie {AllowPointSelect = true, Cursor = PlotOptionsPieCursor.Pointer, DataLabels = new PlotOptionsPieDataLabels {Enabled = true, Format = "{point.name}: {point.percentage:.1f} %"}}}, Series = new List {new PieSeries {Name = "Percentage:", Data = ViewData["formatsPieData"] as List}}}, "formatsChart", false)) + +@(Html.Highsoft().GetHighcharts(new Highcharts {Chart = new Chart {PlotBackgroundColor = null, PlotBorderWidth = null, PlotShadow = new Shadow {Enabled = true}}, Title = new Title {Text = "Top 10 partitioning schemes found"}, Tooltip = new Tooltip {PointFormat = "{series.name}: {point.percentage:.1f}%"}, PlotOptions = new PlotOptions {Pie = new PlotOptionsPie {AllowPointSelect = true, Cursor = PlotOptionsPieCursor.Pointer, DataLabels = new PlotOptionsPieDataLabels {Enabled = true, Format = "{point.name}: {point.percentage:.1f} %"}}}, Series = new List {new PieSeries {Name = "Percentage:", Data = ViewData["partitionsPieData"] as List}}}, "partitionsChart", false)) + +@(Html.Highsoft().GetHighcharts(new Highcharts {Chart = new Chart {PlotBackgroundColor = null, PlotBorderWidth = null, PlotShadow = new Shadow {Enabled = true}}, Title = new Title {Text = "Top 10 filesystems found"}, Tooltip = new Tooltip {PointFormat = "{series.name}: {point.percentage:.1f}%"}, PlotOptions = new PlotOptions {Pie = new PlotOptionsPie {AllowPointSelect = true, Cursor = PlotOptionsPieCursor.Pointer, DataLabels = new PlotOptionsPieDataLabels {Enabled = true, Format = "{point.name}: {point.percentage:.1f} %"}}}, Series = new List {new PieSeries {Name = "Percentage:", Data = ViewData["filesystemsPieData"] as List}}}, "filesystemsChart", false)) + +@(Html.Highsoft().GetHighcharts(new Highcharts {Chart = new Chart {PlotBackgroundColor = null, PlotBorderWidth = null, PlotShadow = new Shadow {Enabled = true}}, Title = new Title {Text = "Top 10 media types found in images"}, Tooltip = new Tooltip {PointFormat = "{series.name}: {point.percentage:.1f}%"}, PlotOptions = new PlotOptions {Pie = new PlotOptionsPie {AllowPointSelect = true, Cursor = PlotOptionsPieCursor.Pointer, DataLabels = new PlotOptionsPieDataLabels {Enabled = true, Format = "{point.name}: {point.percentage:.1f} %"}}}, Series = new List {new PieSeries {Name = "Percentage:", Data = ViewData["virtualMediaPieData"] as List}}}, "virtualMediaChart", false)) + +@(Html.Highsoft().GetHighcharts(new Highcharts {Chart = new Chart {PlotBackgroundColor = null, PlotBorderWidth = null, PlotShadow = new Shadow {Enabled = true}}, Title = new Title {Text = "Top 10 media types found in real devices"}, Tooltip = new Tooltip {PointFormat = "{series.name}: {point.percentage:.1f}%"}, PlotOptions = new PlotOptions {Pie = new PlotOptionsPie {AllowPointSelect = true, Cursor = PlotOptionsPieCursor.Pointer, DataLabels = new PlotOptionsPieDataLabels {Enabled = true, Format = "{point.name}: {point.percentage:.1f} %"}}}, Series = new List {new PieSeries {Name = "Percentage:", Data = ViewData["realMediaPieData"] as List}}}, "realMediaChart", false)) + +@(Html.Highsoft().GetHighcharts(new Highcharts {Chart = new Chart {PlotBackgroundColor = null, PlotBorderWidth = null, PlotShadow = new Shadow {Enabled = true}}, Title = new Title {Text = "Devices found by bus"}, Tooltip = new Tooltip {PointFormat = "{series.name}: {point.percentage:.1f}%"}, PlotOptions = new PlotOptions {Pie = new PlotOptionsPie {AllowPointSelect = true, Cursor = PlotOptionsPieCursor.Pointer, DataLabels = new PlotOptionsPieDataLabels {Enabled = true, Format = "{point.name}: {point.percentage:.1f} %"}}}, Series = new List {new PieSeries {Name = "Percentage:", Data = ViewData["devicesBusPieData"] as List}}}, "devicesBusChart", false)) + + +@(Html.Highsoft().GetHighcharts(new Highcharts {Chart = new Chart {PlotBackgroundColor = null, PlotBorderWidth = null, PlotShadow = new Shadow {Enabled = true}}, Title = new Title {Text = "Devices found by bus"}, Tooltip = new Tooltip {PointFormat = "{series.name}: {point.percentage:.1f}%"}, PlotOptions = new PlotOptions {Pie = new PlotOptionsPie {AllowPointSelect = true, Cursor = PlotOptionsPieCursor.Pointer, DataLabels = new PlotOptionsPieDataLabels {Enabled = true, Format = "{point.name}: {point.percentage:.1f} %"}}}, Series = new List {new PieSeries {Name = "Percentage:", Data = ViewData["devicesManufacturerPieData"] as List}}}, "devicesManufacturerChart", false)) \ No newline at end of file diff --git a/DiscImageChef.Server/packages.config b/DiscImageChef.Server/packages.config index a18b7f6ae..ba0c8bce3 100644 --- a/DiscImageChef.Server/packages.config +++ b/DiscImageChef.Server/packages.config @@ -3,6 +3,7 @@ +