c# - Linqpad 图表。Column 和 StackedColumn 的组合
问题描述
我正在尝试在 LinqPad 中做一些图表。我有一些来自 api 的日志,我知道调用了什么 api 以及请求是否被缓存(在我们的实际情况中,我们使用来自 bing api 的坐标解析地址,或者如果我们缓存了它,我们会从缓存表中获取地址)
我使用这个 linqpad 脚本:
var startDate = new DateTime(2019, 1,1);
var Requests = new[]
{
new {Date=startDate, Name = "Api1", Cached=true },
new {Date=startDate, Name = "Api2", Cached=true },
new {Date=startDate, Name = "Api3", Cached=true },
new {Date=startDate, Name = "Api1", Cached=true },
new {Date=startDate, Name = "Api1", Cached=false },
new {Date=startDate, Name = "Api2", Cached=false },
new {Date=startDate, Name = "Api3", Cached=false },
new {Date=startDate, Name = "Api1", Cached=false },
new {Date=startDate.AddDays(1), Name = "Api3", Cached=true },
new {Date=startDate.AddDays(1), Name = "Api1", Cached=false },
new {Date=startDate.AddDays(1), Name = "Api2", Cached=true },
new {Date=startDate.AddDays(1), Name = "Api2", Cached=false },
new {Date=startDate.AddDays(1), Name = "Api1", Cached=true },
new {Date=startDate.AddDays(1), Name = "Api1", Cached=false },
new {Date=startDate.AddDays(1), Name = "Api3", Cached=true },
};
Requests.GroupBy(x=>x.Date).Chart (c => c.Key)
.AddYSeries (c => c.Count(x=>x.Name=="Api1"),name:"Api1")
.AddYSeries (c => c.Count(x=>x.Name=="Api2"),name:"Api2")
.AddYSeries (c => c.Count(x=>x.Name=="Api3"),name:"Api3")
.AddYSeries (c => c.Count(x=>x.Name=="Api1" && x.Cached),name: "Api1 Cached")
.AddYSeries (c => c.Count(x=>x.Name=="Api2" && x.Cached),name: "Api2 Cached")
.AddYSeries (c => c.Count(x=>x.Name=="Api3" && x.Cached),name: "Api3 Cached")
.Dump();
这就是结果:
实际上我希望每天只有 3 列,但它们必须松弛(在一列中显示总值和缓存值)
如果我切换到 SlackedColumns 我将所有值放在一列中,这不是我想要的:
有什么想法,怎么做?
更新:
我想要的是这样的(但我更喜欢它按日期分组,就像 linqpad 那样):
解决方案
我无法用 linqpad 做到这一点,所以我使用外部库在 html 中获取期望输出:
所以它看起来像这样:
void Main()
{
var startDate = new DateTime(2019, 1,1);
var Requests = new[]
{
new {Date=startDate, Name = "Api1", Cached=true },
new {Date=startDate, Name = "Api2", Cached=true },
new {Date=startDate, Name = "Api3", Cached=true },
new {Date=startDate, Name = "Api1", Cached=true },
new {Date=startDate, Name = "Api1", Cached=false },
new {Date=startDate, Name = "Api2", Cached=false },
new {Date=startDate, Name = "Api3", Cached=false },
new {Date=startDate, Name = "Api1", Cached=false },
new {Date=startDate.AddDays(1), Name = "Api3", Cached=true },
new {Date=startDate.AddDays(1), Name = "Api1", Cached=false },
new {Date=startDate.AddDays(1), Name = "Api2", Cached=true },
new {Date=startDate.AddDays(1), Name = "Api2", Cached=false },
new {Date=startDate.AddDays(1), Name = "Api1", Cached=true },
new {Date=startDate.AddDays(1), Name = "Api1", Cached=false },
new {Date=startDate.AddDays(1), Name = "Api3", Cached=true },
};
var data = new Dictionary<Tuple<string, bool>,List<int>>();
foreach (var val in Requests.GroupBy(x=>x.Date.ToShortDateString()))
{
var keyCached = Tuple.Create(val.Key, true);
var keyNotCached = Tuple.Create(val.Key, false);
if (!data.ContainsKey(keyCached))
{
data.Add(keyCached, new List<int>());
}
if (!data.ContainsKey(keyNotCached))
{
data.Add(keyNotCached, new List<int>());
}
data[keyCached].Add(val.Count(x=>x.Cached));
data[keyNotCached].Add(val.Count(x=>!x.Cached));
}
var columns = Requests.Select(c=>c.Date.ToShortDateString());
var rawData= data.Select(x=>new {name =x.Key.Item1 + " " + ( x.Key.Item2 ? "Cached":"Not Cached"), stack = x.Key.Item1, data = x.Value});
Util.RawHtml(createHtml(columns, Newtonsoft.Json.JsonConvert.SerializeObject(rawData))).Dump();
}
private string createHtml(IEnumerable<string> columns, string serializedData)
{
var columnsString = Newtonsoft.Json.JsonConvert.SerializeObject(columns);
var s = @"<script src=""https://code.highcharts.com/highcharts.js""></script>
<script src=""https://code.highcharts.com/modules/exporting.js""></script>
<script src=""https://code.highcharts.com/modules/export-data.js""></script>
<div id=""container"" style=""min-width: 310px; height: 400px; margin: 0 auto""></div>
<script>
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Total'
},
xAxis: {
categories:"+columnsString+@"
},
yAxis: {
allowDecimals: false,
min: 0,
title: {
text: 'Number of calls'
}
},
tooltip: {
formatter: function () {
return '<b>' + this.x + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>' +
'Total: ' + this.point.stackTotal;
}
},
plotOptions: {
column: {
stacking: 'normal'
}
},
series: "+serializedData+@"
});
</script>";
return s;
}
推荐阅读
- android - Android 在 Fragment 中获取错误 onClick 侦听器
- angular - 如何知道指针在离子角范围分量中是向左还是向右
- python - 在这种情况下,“追加”有效,但“扩展”无效
- corda - 使用 jolokia 集成 jolokia 并在应用程序内获取 cordapps 和流的详细信息
- intellij-idea - 如何使用此“启用实时模板”?
- windows - 如何像 Explorer 那样挂载 VHDx,而不是像 Mount-DiskImage 或 VhdAttach 那样挂载?
- javascript - 评估类中的内部方法
- android - getRuntime().exec 和 Processbuilder 仅返回 2 行数据
- java - 如何使用环境 API 存储 byte[] 数组
- arrays - 从数组 Angular 2 中获取值