存在空点时如何继续图表?
How to continue chart when empty points exist?
using System.Web.UI.DataVisualization.Charting.Chart
我的数据是这样的:
...但我的图表没有在缺失数据点之间画线:
如您所见,第 2 列在 2015 年 7 月 9 日的 51 处有一个点,然后在 2015 年 7 月 16 日之前这些点都是空的。我希望图表从 2015 年 7 月 9 日到 2015 年 7 月 16 日的点画一条线。
我怎样才能让它工作?
这是我现有的Series
结构:
var series = chart.Series[header] = new Series(header) {
BorderWidth = 2,
ChartArea = DataTable.TableName,
ChartType = SeriesChartType.FastLine,
Color = legendColors[header],
Enabled = true,
Font = new Font("Lucida Sans Unicode", 6f),
XValueMember = "Week",
YValueMembers = header
};
更新 1:
有了@jstreet 的回答,我现在画了一条线。但是该值表示为 0:
预期的是以下粗虚线应替换代表值 0 的线:
更新二:
修改 for-loop
以手动将 DataPoint
添加到 series
中,遵循 @jstreet 在 code-behind 中添加点的示例:
for (int column = 0; column < seriesHeaders.Length; column++) {
var header = seriesHeaders[column];
var series = chart.Series[header] = new Series(header) {
BorderWidth = 2,
ChartArea = DataTable.TableName,
ChartType = SeriesChartType.FastLine,
Color = legendColors[header],
Enabled = true,
Font = new Font("Lucida Sans Unicode", 6f),
XValueMember = "Week",
YValueMembers = header
};
series.EmptyPointStyle.Color = legendColors[header];
series.EmptyPointStyle.AxisLabel = "Empty";
DataTable.Rows
.OfType<DataRow>()
.Select(r => (double)r[header])
.ToList()
.ForEach(v => {
series.Points.Add(new DataPoint(series) {
IsEmpty = v == Double.NaN,
YValues = new double[] { v == Double.NaN ? 0 : v }
});
});
}
...图表仍将本应为空点的值呈现为 0
值。
更新 3:
DataPoint
s 的修改结构。显然 v == Double.NaN
没有正确评估:
DataTable.Rows
.OfType<DataRow>()
.Select(r => (double)r[header])
.ToList()
.ForEach(v => {
var isEmpty = Double.IsNaN(v);
var value = new double[] { v == Double.NaN ? 0 : v };
series.Points.Add(new DataPoint() {
IsEmpty = isEmpty,
YValues = value
});
});
... 我验证了 Series.Points
集合:
你需要定义一个EmptyPointStyle
,如下图:
<asp:Series Name="Series1" ChartType="Line" XValueType="DateTime">
<Points>
<asp:DataPoint XValue="42005" YValues="50" />
<asp:DataPoint XValue="42036" YValues="70" />
<asp:DataPoint XValue="42064" YValues="30" />
<asp:DataPoint IsEmpty="True" XValue="42095" YValues="0" />
<asp:DataPoint XValue="42156" YValues="60" />
<asp:DataPoint XValue="42186" YValues="40" />
</Points>
<EmptyPointStyle Color="Red" />
</asp:Series>
结果:
编辑:我还可以使用后面的代码添加点数:
protected void Page_Load(object sender, EventArgs e)
{
Chart1.Series[0].Points.Add(new DataPoint { IsEmpty = false, XValue = DateTime.Now.AddDays(1).ToOADate(), YValues = new double[] { 50 } });
Chart1.Series[0].Points.Add(new DataPoint { IsEmpty = false, XValue = DateTime.Now.AddDays(2).ToOADate(), YValues = new double[] { 70 } });
Chart1.Series[0].Points.Add(new DataPoint { IsEmpty = true, XValue = DateTime.Now.AddDays(3).ToOADate(), YValues = new double[] { 0 } });
Chart1.Series[0].Points.Add(new DataPoint { IsEmpty = false, XValue = DateTime.Now.AddDays(4).ToOADate(), YValues = new double[] { 30 } });
Chart1.Series[0].Points.Add(new DataPoint { IsEmpty = false, XValue = DateTime.Now.AddDays(5).ToOADate(), YValues = new double[] { 60 } });
}
我没有遇到你描述的无法设置 IsEmpty
或在图表中得到 0 的问题:
在提供的所有更新之后更改了一行:
ChartType = SeriesChartType.Line, // was FastLine
所以 Series
结构现在看起来像这样:
for (int column = 0; column < seriesHeaders.Length; column++) {
var header = seriesHeaders[column];
var series = chart.Series[header] = new Series(header) {
BorderWidth = 2,
ChartArea = DataTable.TableName,
ChartType = SeriesChartType.Line,
Color = legendColors[header],
Enabled = true,
Font = new Font("Lucida Sans Unicode", 6f),
XValueMember = "Week",
YValueMembers = header
};
series.EmptyPointStyle.Color = legendColors[header];
series.EmptyPointStyle.BorderWidth = 2;
DataTable.Rows
.OfType<DataRow>()
.Select(r => {
var value = (double)r[header];
return new {
isEmpty = Double.IsNaN(value),
yValue = new double[] { value },
xValue = DateTime.Parse(r["Week"].ToString()).ToOADate()
};
})
.ToList()
.ForEach(dp => {
var dataPoint = new DataPoint() {
IsEmpty = dp.isEmpty,
YValues = dp.yValue,
XValue = dp.xValue
};
series.Points.Add(dataPoint);
});
}
图表已正确呈现:
using System.Web.UI.DataVisualization.Charting.Chart
我的数据是这样的:
...但我的图表没有在缺失数据点之间画线:
如您所见,第 2 列在 2015 年 7 月 9 日的 51 处有一个点,然后在 2015 年 7 月 16 日之前这些点都是空的。我希望图表从 2015 年 7 月 9 日到 2015 年 7 月 16 日的点画一条线。
我怎样才能让它工作?
这是我现有的Series
结构:
var series = chart.Series[header] = new Series(header) {
BorderWidth = 2,
ChartArea = DataTable.TableName,
ChartType = SeriesChartType.FastLine,
Color = legendColors[header],
Enabled = true,
Font = new Font("Lucida Sans Unicode", 6f),
XValueMember = "Week",
YValueMembers = header
};
更新 1:
有了@jstreet 的回答,我现在画了一条线。但是该值表示为 0:
预期的是以下粗虚线应替换代表值 0 的线:
更新二:
修改 for-loop
以手动将 DataPoint
添加到 series
中,遵循 @jstreet 在 code-behind 中添加点的示例:
for (int column = 0; column < seriesHeaders.Length; column++) {
var header = seriesHeaders[column];
var series = chart.Series[header] = new Series(header) {
BorderWidth = 2,
ChartArea = DataTable.TableName,
ChartType = SeriesChartType.FastLine,
Color = legendColors[header],
Enabled = true,
Font = new Font("Lucida Sans Unicode", 6f),
XValueMember = "Week",
YValueMembers = header
};
series.EmptyPointStyle.Color = legendColors[header];
series.EmptyPointStyle.AxisLabel = "Empty";
DataTable.Rows
.OfType<DataRow>()
.Select(r => (double)r[header])
.ToList()
.ForEach(v => {
series.Points.Add(new DataPoint(series) {
IsEmpty = v == Double.NaN,
YValues = new double[] { v == Double.NaN ? 0 : v }
});
});
}
...图表仍将本应为空点的值呈现为 0
值。
更新 3:
DataPoint
s 的修改结构。显然 v == Double.NaN
没有正确评估:
DataTable.Rows
.OfType<DataRow>()
.Select(r => (double)r[header])
.ToList()
.ForEach(v => {
var isEmpty = Double.IsNaN(v);
var value = new double[] { v == Double.NaN ? 0 : v };
series.Points.Add(new DataPoint() {
IsEmpty = isEmpty,
YValues = value
});
});
... 我验证了 Series.Points
集合:
你需要定义一个EmptyPointStyle
,如下图:
<asp:Series Name="Series1" ChartType="Line" XValueType="DateTime">
<Points>
<asp:DataPoint XValue="42005" YValues="50" />
<asp:DataPoint XValue="42036" YValues="70" />
<asp:DataPoint XValue="42064" YValues="30" />
<asp:DataPoint IsEmpty="True" XValue="42095" YValues="0" />
<asp:DataPoint XValue="42156" YValues="60" />
<asp:DataPoint XValue="42186" YValues="40" />
</Points>
<EmptyPointStyle Color="Red" />
</asp:Series>
结果:
编辑:我还可以使用后面的代码添加点数:
protected void Page_Load(object sender, EventArgs e)
{
Chart1.Series[0].Points.Add(new DataPoint { IsEmpty = false, XValue = DateTime.Now.AddDays(1).ToOADate(), YValues = new double[] { 50 } });
Chart1.Series[0].Points.Add(new DataPoint { IsEmpty = false, XValue = DateTime.Now.AddDays(2).ToOADate(), YValues = new double[] { 70 } });
Chart1.Series[0].Points.Add(new DataPoint { IsEmpty = true, XValue = DateTime.Now.AddDays(3).ToOADate(), YValues = new double[] { 0 } });
Chart1.Series[0].Points.Add(new DataPoint { IsEmpty = false, XValue = DateTime.Now.AddDays(4).ToOADate(), YValues = new double[] { 30 } });
Chart1.Series[0].Points.Add(new DataPoint { IsEmpty = false, XValue = DateTime.Now.AddDays(5).ToOADate(), YValues = new double[] { 60 } });
}
我没有遇到你描述的无法设置 IsEmpty
或在图表中得到 0 的问题:
在提供的所有更新之后更改了一行:
ChartType = SeriesChartType.Line, // was FastLine
所以 Series
结构现在看起来像这样:
for (int column = 0; column < seriesHeaders.Length; column++) {
var header = seriesHeaders[column];
var series = chart.Series[header] = new Series(header) {
BorderWidth = 2,
ChartArea = DataTable.TableName,
ChartType = SeriesChartType.Line,
Color = legendColors[header],
Enabled = true,
Font = new Font("Lucida Sans Unicode", 6f),
XValueMember = "Week",
YValueMembers = header
};
series.EmptyPointStyle.Color = legendColors[header];
series.EmptyPointStyle.BorderWidth = 2;
DataTable.Rows
.OfType<DataRow>()
.Select(r => {
var value = (double)r[header];
return new {
isEmpty = Double.IsNaN(value),
yValue = new double[] { value },
xValue = DateTime.Parse(r["Week"].ToString()).ToOADate()
};
})
.ToList()
.ForEach(dp => {
var dataPoint = new DataPoint() {
IsEmpty = dp.isEmpty,
YValues = dp.yValue,
XValue = dp.xValue
};
series.Points.Add(dataPoint);
});
}
图表已正确呈现: