使用 Razor 模型数据填充 javascript 个图表
Populating javascript chart with Razor model data
我有一个折线图 http://www.chartjs.org/docs/#line-chart-introduction 我想用 MVC6/Razor
中视图模型的数据填充
我的视图模型是
public class LeaderboardViewModel
{
public List<LeaderboardViewEntry> LeaderboardViewEntries { get; set; }
public HistoicPointsViewModel HistoicPoints { get; set; }
}
public class HistoicPointsViewModel
{
public HistoicPointsViewModel()
{
PlayerHistores = new List<PlayerHistoricViewModel>();
}
public DateTime[] YAxisDates { get; set; }
public List<PlayerHistoricViewModel> PlayerHistores { get; set; }
}
public class PlayerHistoricViewModel
{
public PlayerHistoricViewModel()
{
Points = new List<int?>();
}
public string PlayerName { get; set; }
public List<int?> Points { get; set; }
}
我的视图是脚本部分在我的视图中是:
@model Foosball9001.ViewModels.Leaderboards.LeaderboardViewModel
<canvas id="myChart" width="800" height="400"></canvas>
@section Scripts{
<script type="text/javascript">
var data = {
labels: @Model.HistoicPoints.YAxisDates,
datasets: [
{
@foreach (PlayerHistoricViewModel x in Model.HistoicPoints.PlayerHistores)
{
{
label: x.PlayerName,
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: x.Points
}
}
}
]
};
var ctx = document.getElementById("myChart").getContext("2d");
var myNewChart = new Chart(ctx).Line(data);
</script>
}
所以我想使用我的 HistoicPointsViewModel.YAxisDates
作为 Y 轴坐标,然后我想在我的 PlayerHistores 中为每个玩家创建一个数据集,它将来自 PlayerHistoricViewModel.Points
的数据作为数据绘制成图表
我的问题是使用 Razor 编写动态 javascript,所以它看起来像示例
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [65, 59, 80, 81, 56, 55, 40]
},
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
您需要将模型列表编码为 json 您可以使用来自 razor 的 json 助手来完成此操作,试试这个:
var datelist = @Html.Raw(Json.Encode(Model.HistoicPoints.YAxisDates.Select(v => v.ToString("MMMM")));
ToString("MMMM")
会给你整个月份的名称。
历史玩家也一样
var playerHistory = @Html.Raw(Json.Encode(Model.HistoicPoints.PlayerHistores.Select(v => new
{
label = v.PlayerName,
fillColor = String.Format("rgba({0},{1},{2},{3})", Color.Blue.R, Color.AliceBlue.G, Color.AliceBlue.B, Color.AliceBlue.A),
strokeColor = String.Format("rgba({0},{1},{2},{3})", Color.Blue.R, Color.AliceBlue.G, Color.AliceBlue.B, Color.AliceBlue.A),
pointColor = String.Format("rgba({0},{1},{2},{3})", Color.Blue.R, Color.AliceBlue.G, Color.AliceBlue.B, Color.AliceBlue.A),
pointStrokeColor = "#fff",
pointHighlightFill = "#fff",
pointHighlightStroke = "rgba(220,220,220,1)",
data = v.Points
})));
我已经使用 Color
class 创建了颜色,如果你想使用它或者只是将 rgba 设置为字符串。
基本上你在 javascript 代码中执行此操作。
var data = {
labels: '@datelist',
datasets: '@playerHistory'
};
我认为最简单的方法是创建相应的 ChartModel
,它可以序列化为您需要的确切 JSON 结构:
public class DtatsetModel
{
public string label {get;set;}
public const string fillColor = "rgba(220,220,220,0.2)";
public const string strokeColor = "rgba(220,220,220,1)";
public const string pointColor = "rgba(220,220,220,1)";
public const string pointStrokeColor = "#fff";
public const string pointHighlightFill = "#fff";
public const string pointHighlightStroke = "rgba(151,187,205,1)";
public List<string> data {get;set;}
public DtatsetModel(PlayerHistoricViewModel x)
{
this.label = x.PlayerName;
this.data = x.Points.Where(p=>p.HasValue).Select(p=>p.ToString());
}
}
public class ChartModel
{
public List<string> labels {get;set;}
public List<DtatsetModel> datasets {get;set;}
public ChartModel(HistoicPointsViewModel x)
{
this.labels = x.Select(d=>d.ToString("MMMM"));
this.datasets = x.PlayerHistores.Select(h=>new DtatsetModel(h));
}
}
然后在视图中你可以做类似
的事情
<script type="text/javascript">
var data = @Html.Raw(JsonConvert.SerializeObject(new ChartModel(Model.HistoicPoints)))
var ctx = document.getElementById("myChart").getContext("2d");
var myNewChart = new Chart(ctx).Line(data);
</script>
对于连载我使用了JSON.NET
首先,我建议不要混合使用 javascript 和 razor,因为内联 javascript 容易出现 XSS。
我会在一些您可以在 razor 中创建的不可见元素上使用数据属性,然后从 javascript 中读取这些数据属性。
所以只需创建具有数据属性的 div (data attributes description)
@foreach (PlayerHistoricViewModel x in Model.HistoicPoints.PlayerHistores)
{
<div
class="players"
data-label= "x.PlayerName",
data-fillColor= "rgba(220,220,220,0.2)",
data-strokeColor= "rgba(220,220,220,1)",
data-pointColor= "rgba(220,220,220,1)",
data-pointStrokeColor= "#fff",
data-pointHighlightFill= "#fff",
data-pointHighlightStroke= "rgba(220,220,220,1)",
data-points= "x.Points"//this will maybe need some work to make json array
/>
}
在javascript中:
var datasets = [];
$("div.players").each(function(){
var testdata = {
label = $(this).data('label');
fillColor = $(this).data('label');
...
points = $(this).data('points');
//if datapoints will be json array then it will be automatically parsed as such
}
datasets.push(testdata);
});
通过这种方式,您已经 javascript 与剃须刀分离了。
我有一个折线图 http://www.chartjs.org/docs/#line-chart-introduction 我想用 MVC6/Razor
中视图模型的数据填充我的视图模型是
public class LeaderboardViewModel
{
public List<LeaderboardViewEntry> LeaderboardViewEntries { get; set; }
public HistoicPointsViewModel HistoicPoints { get; set; }
}
public class HistoicPointsViewModel
{
public HistoicPointsViewModel()
{
PlayerHistores = new List<PlayerHistoricViewModel>();
}
public DateTime[] YAxisDates { get; set; }
public List<PlayerHistoricViewModel> PlayerHistores { get; set; }
}
public class PlayerHistoricViewModel
{
public PlayerHistoricViewModel()
{
Points = new List<int?>();
}
public string PlayerName { get; set; }
public List<int?> Points { get; set; }
}
我的视图是脚本部分在我的视图中是:
@model Foosball9001.ViewModels.Leaderboards.LeaderboardViewModel
<canvas id="myChart" width="800" height="400"></canvas>
@section Scripts{
<script type="text/javascript">
var data = {
labels: @Model.HistoicPoints.YAxisDates,
datasets: [
{
@foreach (PlayerHistoricViewModel x in Model.HistoicPoints.PlayerHistores)
{
{
label: x.PlayerName,
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: x.Points
}
}
}
]
};
var ctx = document.getElementById("myChart").getContext("2d");
var myNewChart = new Chart(ctx).Line(data);
</script>
}
所以我想使用我的 HistoicPointsViewModel.YAxisDates
作为 Y 轴坐标,然后我想在我的 PlayerHistores 中为每个玩家创建一个数据集,它将来自 PlayerHistoricViewModel.Points
的数据作为数据绘制成图表
我的问题是使用 Razor 编写动态 javascript,所以它看起来像示例
var data = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [65, 59, 80, 81, 56, 55, 40]
},
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [28, 48, 40, 19, 86, 27, 90]
}
]
};
您需要将模型列表编码为 json 您可以使用来自 razor 的 json 助手来完成此操作,试试这个:
var datelist = @Html.Raw(Json.Encode(Model.HistoicPoints.YAxisDates.Select(v => v.ToString("MMMM")));
ToString("MMMM")
会给你整个月份的名称。
历史玩家也一样
var playerHistory = @Html.Raw(Json.Encode(Model.HistoicPoints.PlayerHistores.Select(v => new
{
label = v.PlayerName,
fillColor = String.Format("rgba({0},{1},{2},{3})", Color.Blue.R, Color.AliceBlue.G, Color.AliceBlue.B, Color.AliceBlue.A),
strokeColor = String.Format("rgba({0},{1},{2},{3})", Color.Blue.R, Color.AliceBlue.G, Color.AliceBlue.B, Color.AliceBlue.A),
pointColor = String.Format("rgba({0},{1},{2},{3})", Color.Blue.R, Color.AliceBlue.G, Color.AliceBlue.B, Color.AliceBlue.A),
pointStrokeColor = "#fff",
pointHighlightFill = "#fff",
pointHighlightStroke = "rgba(220,220,220,1)",
data = v.Points
})));
我已经使用 Color
class 创建了颜色,如果你想使用它或者只是将 rgba 设置为字符串。
基本上你在 javascript 代码中执行此操作。
var data = {
labels: '@datelist',
datasets: '@playerHistory'
};
我认为最简单的方法是创建相应的 ChartModel
,它可以序列化为您需要的确切 JSON 结构:
public class DtatsetModel
{
public string label {get;set;}
public const string fillColor = "rgba(220,220,220,0.2)";
public const string strokeColor = "rgba(220,220,220,1)";
public const string pointColor = "rgba(220,220,220,1)";
public const string pointStrokeColor = "#fff";
public const string pointHighlightFill = "#fff";
public const string pointHighlightStroke = "rgba(151,187,205,1)";
public List<string> data {get;set;}
public DtatsetModel(PlayerHistoricViewModel x)
{
this.label = x.PlayerName;
this.data = x.Points.Where(p=>p.HasValue).Select(p=>p.ToString());
}
}
public class ChartModel
{
public List<string> labels {get;set;}
public List<DtatsetModel> datasets {get;set;}
public ChartModel(HistoicPointsViewModel x)
{
this.labels = x.Select(d=>d.ToString("MMMM"));
this.datasets = x.PlayerHistores.Select(h=>new DtatsetModel(h));
}
}
然后在视图中你可以做类似
的事情<script type="text/javascript">
var data = @Html.Raw(JsonConvert.SerializeObject(new ChartModel(Model.HistoicPoints)))
var ctx = document.getElementById("myChart").getContext("2d");
var myNewChart = new Chart(ctx).Line(data);
</script>
对于连载我使用了JSON.NET
首先,我建议不要混合使用 javascript 和 razor,因为内联 javascript 容易出现 XSS。
我会在一些您可以在 razor 中创建的不可见元素上使用数据属性,然后从 javascript 中读取这些数据属性。
所以只需创建具有数据属性的 div (data attributes description)
@foreach (PlayerHistoricViewModel x in Model.HistoicPoints.PlayerHistores)
{
<div
class="players"
data-label= "x.PlayerName",
data-fillColor= "rgba(220,220,220,0.2)",
data-strokeColor= "rgba(220,220,220,1)",
data-pointColor= "rgba(220,220,220,1)",
data-pointStrokeColor= "#fff",
data-pointHighlightFill= "#fff",
data-pointHighlightStroke= "rgba(220,220,220,1)",
data-points= "x.Points"//this will maybe need some work to make json array
/>
}
在javascript中:
var datasets = [];
$("div.players").each(function(){
var testdata = {
label = $(this).data('label');
fillColor = $(this).data('label');
...
points = $(this).data('points');
//if datapoints will be json array then it will be automatically parsed as such
}
datasets.push(testdata);
});
通过这种方式,您已经 javascript 与剃须刀分离了。