以编程方式解决了this problem asp.net多系列图表之后,我在另一个多系列图表中发现了另一个问题:
我想显示月度销售报告,显示已批准和拒绝的提案中过去m
个月的变化情况。几个月来,没有任何被拒绝的提案,因此以下查询(C#/ Oracle)会返回一些空结果。
select to_char(c.date,'YYYYMM') ctb_month,
c.approved,
count(distinct c.f1) amt_c,
count(b.f1) amt_b,
sum(nvl(b.value,0)) sum_values
from bens b
join contracts c
on b.contract_id = c.f1
where b.seller = :USR_ID
AND c.date
BETWEEN add_months(:DATAI,:MONTHS) AND :DATAI
group by to_char(c.date,'YYYYMM'), c.approved
order by ctb_month
OBS:在绑定:MONTHS
参数之前,我确保其值为负。
查询结果示例:
CTB_MONTH APPROVED AMT_C AMT_B SUM_VALUES
201209 APPROVED 10 20 1234.56
201209 PENDING 3 3 120.21
201210 APPROVED 12 18 850.52
201210 PENDING 4 4 158.71
201210 REJECTED 1 1 80.40
注意:在这种情况下,201209年当前卖方没有任何被拒绝的提案。
填写图表的代码:
我将较低层传递的数据存储在var report
中,并按照APPROVED
状态对数据进行过滤:
var approved = queryResult
.Where(r => r.APPROVED == "APPROVED")
.ToList()
;
var rejected = queryResult
.Where(r => r.APPROVED == "REJECTED")
.ToList()
;
var pending = queryResult
.Where(r => r.APPROVED == "PENDING")
.ToList()
;
然后,我在循环中创建系列
for (int i = 0; i < 6; i++) {
Series temp = new Series {
XAxisType = AxisType.Primary,
XValueType = ChartValueType.DateTime,
YAxisType = AxisType.Primary,
//mostra só a quantidade de contratos
IsValueShownAsLabel = i % 2 == 0 ? true : false,
ChartType = SeriesChartType.Column,
CustomProperties = "EmptyPointValue=Zero",
Legend = "Legenda"
};
grafico.Series.Add(temp);
}
手动DataBinding每个系列
// approved contracts
grafico.Series[0].Points.DataBindXY(approved, "MONTH", approved, "AMT_C");
grafico.Series[0].LegendText = "Cont. approved";
// approved bens
grafico.Series[1].Points.DataBindXY(approved, "MONTH", approved, "AMT_B");
grafico.Series[1].LegendText = "Ben. approved";
grafico.Series[1].ChartType = SeriesChartType.Line;
// pending contracts
grafico.Series[2].Points.DataBindXY(pending, "MONTH", pending, "AMT_C");
grafico.Series[2].LegendText = "Cont. pending";
// pending bens
grafico.Series[3].Points.DataBindXY(pending, "MONTH", pending, "AMT_B");
grafico.Series[3].LegendText = "Ben. pending";
grafico.Series[3].ChartType = SeriesChartType.Line;
// rejected contracts
grafico.Series[4].Points.DataBindXY(rejected, "MONTH", rejected, "AMT_C");
grafico.Series[4].LegendText = "Cont. rejected";
// rejected bens
grafico.Series[5].Points.DataBindXY(rejected, "MONTH", rejected, "AMT_B");
grafico.Series[5].LegendText = "Ben. rejected";
grafico.Series[5].ChartType = SeriesChartType.Line;
注意:grafico
是我的Chart对象;某些可视设置在<asp:Chart>
标记中定义。
当我运行应用程序时,正确绘制了完整的系列,但不完整的系列(201209 / REJECTED,在上面的例子中)是在错误的X
坐标中绘制的(201210的值是在在这种情况下,201209的列,就好像控件忽略X
方法中传递的DataBindXY
值并按顺序绘制值。
有人知道如何解决这个问题吗? 提前谢谢。
[求助]感谢@jbl,图表现在可以在正确的位置绘制值。
代码:
var allMonths = queryResult
.Select(x => x.MONTH)
.Distinct()
.OrderBy(mes => mes)
;
foreach (var mes in allMonths) {
bool hasData = rejected.Any(r => r.MONTH == mes);
if (hasData == false) {
rejected.Add(new MonthlyData() { MONTH = mes, APPROVED = "REJECTED" });
}
hasData = pending.Any(r => r.MONTH == mes);
if (hasData == false) {
pending.Add(new MonthlyData() { MONTH = mes, APPROVED = "PENDING" });
}
hasData = approved.Any(r => r.MONTH == mes);
if (hasData == false) {
approved.Add(new MonthlyData() { MONTH = mes, APPROVED = "APPROVED" });
}
}
approved = approved.OrderBy(v => v.MONTH).ToList();
pending = pending.OrderBy(v => v.MONTH).ToList();
rejected = rejected.OrderBy(v => v.MONTH).ToList();
grafico.ChartAreas[0].AxisX.Interval = 1;
grafico.ChartAreas[0].AxisX.IntervalType = DateTimeIntervalType.Months;
grafico.ChartAreas[0].AxisX.IntervalOffset = 1;
grafico.ChartAreas[0].AxisX.IntervalOffsetType = DateTimeIntervalType.Months;
注意: MonthlyData是一个简单的类,用于传输查询结果中每一行的值。
答案 0 :(得分:1)
我猜您必须使用空数据点http://msdn.microsoft.com/en-us/library/dd456677.aspx来对齐所有系列
这意味着:
希望这会有所帮助
编辑:你可以尝试(未测试)类似的东西用于已批准的/ AMT_C系列
var allXvalues = queryResult.select(r=>r.CTB_MONTH).Distinct().OrderBy(month=>month).ToList();
allXvalues
.ForEach
(
xvalue=>
{
var p = approved.Where(o=>o.MONTH==xValue).FirstOrDefault();
if(p==null)
grafico.Series[0].Points.Add(new DataPoint(p.MONTH,p.AMT_C));
else
grafico.Series[0].Points.Add(new DataPoint(xvalue,0){IsEmpty=true});
}
);