0

プログラムで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);
}

そして、各シリーズを手動でデータバインディングします

// 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は、クエリ結果のすべての行の値を転送する単純なクラスです。

4

1 に答える 1

1

すべてのシリーズを調整するには、空のデータポイントhttp://msdn.microsoft.com/en-us/library/dd456677.aspxを使用する必要があると思います。

これは意味します:

  • シリーズ内のすべてのx値のコレクションを構築する
  • これらすべてのx値をシリーズで左結合して、欠落しているすべてのポイントを検出します
  • 欠落しているポイントを空のデータポイントで埋めます

これがお役に立てば幸いです

編集:承認済み/ 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});
      }
   );
于 2012-10-12T15:15:09.593 に答える