Я пытаюсь сделать некоторые диаграммы в 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):
как я понял, вы хотите что-то вроде этого ?
Requests.GroupBy(x => x.Date).Chart(c => c.Key)
.AddYSeries(c => c.Count(x => x.Name == "Api1"), LINQPad.Util.SeriesType.StackedColumn, "Api1", false)
.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), LINQPad.Util.SeriesType.StackedColumn, "Api1 Cached", true)
.AddYSeries(c => c.Count(x => x.Name == "Api2" && x.Cached), LINQPad.Util.SeriesType.StackedColumn, "Api2 Cached", true)
.AddYSeries(c => c.Count(x => x.Name == "Api3" && x.Cached), LINQPad.Util.SeriesType.StackedColumn, "Ap3 Cached", true)
.Dump();
в этом случае есть программное ограничение. но вы можете использовать System.Windows.Forms.DataVisualization.Charting пример
Мне не удалось сделать это с помощью 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;
}
Не совсем, я обновил свой вопрос образцом диаграммы, которую я сделал в Excel.