我需要在我的网站项目中添加折线图。它需要在x轴上有日期值,在y轴上有整数。目前数据显示如下:
我需要它显示在这个excel版本中:
我无法正确地将数据与x轴对齐,并且我无法在x轴上获取标签以显示正确的日期。我的网页(使用Razor语法)设置如下:
<style>
svg {
display: block;
}
#chart1 svg{
height: 500px;
min-width: 100px;
min-height: 100px;
}
</style>
<script>
var chart;
var data2 = JSON.parse(@Html.Raw(Json.Encode(ViewBag.data)));
var data = data2[0];
nv.addGraph(function() {
chart = nv.models.lineChart();
chart
.x(function(d,i)
{
return i;
})
chart.xAxis
.tickFormat(function(d)
{
return d3.time.format('%b %d')(new Date(d));
})
chart.yAxis
.axisLabel('Voltage (v)')
.tickFormat(d3.format(',.2f'));
chart.showXAxis(true);
d3.select('#chart1 svg')
//.datum([]) //for testing noData
.datum(data)
.transition().duration(500)
.call(chart);
nv.utils.windowResize(chart.update);
chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });
return chart;
});
</script>
数据以正确的格式传入。有什么想法吗?
答案 0 :(得分:2)
好的,我设法修复它,但这有点像黑客。在控制器中,我用整数索引替换了JSON数据中的日期。我通过找到最小日期,将其设置为x轴索引为0,将下一个日期设置为1等等来解决这些问题。 然后,我将格式化日期的JSON数组传递给控制器的视图,以便您可以使用索引查找日期。 控制器代码:
public ActionResult MileageReport(DateTime startDate, DateTime endDate)
{
using (EventsManager manager = new EventsManager())
{
IEnumerable<Event> travelEvents = manager.GetEventsWhere(t => t.Eventtype == EventType.Travel.ToString() && t.Createddt > startDate && t.Createddt < endDate);
Dictionary<DateTime, int> mappedDates = MapDatesToIndices(travelEvents);
var groupedEvents = travelEvents.GroupBy(e => e.Userid);
JArray jsonArray = new JArray();
IColourPicker colourPicker = NinjectFactory.GetNinJectKernel().Get<IColourPicker>();
int i = 0;
List<Event> events, tempEvents;
List<DateTime> days;
Event travelEvent;
foreach (IGrouping<string, Event> group in groupedEvents)
{
//we only want the last event for each day
events = group.ToList();
days = events.Select(e => e.Createddt.Value.Date).Distinct().OrderBy(o => o).ToList();
dynamic tEvent = new ExpandoObject();
tEvent.key = group.Key;
tEvent.color = colourPicker.GetColour(i);
JArray tEvents = new JArray();
foreach (DateTime day in days)
{
tempEvents = events.Where(e => e.Createddt.Value.Date == day).ToList();
travelEvent = tempEvents.Single(e => e.Mileage.Value == tempEvents.Select(m => m.Mileage.Value).Max());
object tvObj = new { x = mappedDates[travelEvent.Createddt.Value.Date], y = travelEvent.Mileage };
tEvents.Add(JObject.FromObject(tvObj));
}
tEvent.values = tEvents;
jsonArray.Add(JObject.FromObject(tEvent));
i++;
}
string jsonStringTemp = jsonArray.ToString();
string jsonString = FormatJsonString(jsonStringTemp);
ViewBag.xaxislabels = FormatDatesForIndices(mappedDates);
ViewBag.data = jsonString;
ViewBag.name = "Mileage Report";
return PartialView("LineGraph");
}
}
private dynamic FormatDatesForIndices(Dictionary<DateTime, int> mappedDates)
{
List<DateTime> dates = mappedDates.Keys.ToList();
object[] items = new object[dates.Count];
for (int i = 0; i < dates.Count; i++)
{
items[i] = new { date = dates[i].ToString(BaseFormats.DateDisplayFormatNoYear) };
}
JavaScriptSerializer js = new JavaScriptSerializer();
string jsonString = js.Serialize(items);
return jsonString;
}
private Dictionary<DateTime, int> MapDatesToIndices(IEnumerable<Event> travelEvents)
{
Dictionary<DateTime, int> mappedDates = new Dictionary<DateTime, int>();
List<DateTime?> dts = travelEvents.Select(t => t.Createddt).ToList();
dts = dts.Where(d => d != null).ToList();
DateTime min = dts.Min().Value.Date;
DateTime max = dts.Max().Value.Date;
int i = 0;
mappedDates.Add(min, i);
min = min.AddDays(1);
while (min.Date <= max.Date)
{
++i;
mappedDates.Add(min, i);
min = min.AddDays(1);
}
return mappedDates;
}
然后在视图中我覆盖x函数以返回我放入JSON数据的x值。我也覆盖了tickformat以返回我传递给视图的格式化日期。 查看代码:
<style>
svg {
display: block;
}
#chart1 svg{
height: 500px;
min-width: 100px;
min-height: 100px;
}
</style>
<script>
var chart;
var data2 = JSON.parse(@Html.Raw(Json.Encode(ViewBag.data)));
var data = data2[0];
var m_xaxisLabels = JSON.parse(@Html.Raw(Json.Encode(ViewBag.xaxislabels)));
nv.addGraph(function() {
chart = nv.models.lineChart();
chart
.x(function(d,i)
{
return d.x;
})
chart.xAxis.tickFormat(function(d, i){
return m_xaxisLabels[d].date;
});
chart.yAxis
.axisLabel('Voltage (v)')
.tickFormat(d3.format(',.2f'));
chart.showXAxis(true);
d3.select('#chart1 svg')
.datum(data)
.transition().duration(500)
.call(chart);
nv.utils.windowResize(chart.update);
chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });
return chart;
});
</script>
<h2>@ViewBag.name</h2>
<div id="chart1">
<svg></svg>
</div>
现在它有效!: