VC++(MFC)でMSCHARTを操作する方法(2)

前回、グラフの初期状態まで描画したのでデータをセットします。といっても、初期値の代わりにちゃんとしたデータをセットするだけ。まず、適当なデータとアクセサをDocumentクラスに作成ます。ここでは仮に数量・金額・差額の3メンバをもつcchart_dataクラスを作成し、このクラスを格納するメンバ変数をDcoumentクラスに宣言しています。

class cchart_data {
public:
  cchart_data(){
    clear();
  };
  CString quant;
  CString amount;
  CString gain;
private:
  void clear(){
    quant = _T("0");
    amount = _T("0");
    gain = _T("0");
  };
};
// sample_chartDco.h
private:
  vector<cchart_data> m_chart_data;
public::
  const cchart_data* read_data(short month);

コンストラクタ・デストラクタにデータをセットするロジックを入れ(サンプルです。あくまでも)、アクセッサread_data()を定義します。

// sample_chartDoc.cpp
Csample_chartDoc::Csample_chartDoc()
{
  long sample_data[6][3] = {
    {220,13200,4620},{310,18600,6510},{200,12000,4200},
    {190,11400,3990},{ 40, 2400, 840},{260,15600,5460}
  };
  cchart_data* cd;
  m_chart_data.clear();
  for(int i=0;i<6;i++){
    cd = new cchart_data;
    cd->quant.Format("%d",(sample_data[i][1]));
    cd->amount.Format("%d",(sample_data[i][1])/100);
    cd->gain.Format("%d",(sample_data[i][2])/100);
    m_chart_data.push_back(cd);
  }
}
Csample_chartDoc::~Csample_chartDoc()
{
  for(int i=0; i>m_chart_data.size();i++){
    delete m_chart_data[i];
  }
const cchart_data* Csample_chartDoc::read_data(int month)
{
  return m_chart_data[month];
}

フォームに適当なボタンとイベントハンドラを定義してチャートデータを読み込んでセットします。この部分は前回書いたところと重なるので、別関数に括りだしたほうがよいでしょう。これでチャートが表示されます。

void Csample_chartView::OnBnClickedButton1()
{
  Csample_chartDoc* pDoc = (Csample_chartDoc*)GetDocument();

  SAFEARRAYBOUND sab[2];
  COleSafeArray  sa;
  BSTR bstr;
  long index[2] = { 0,0 };
  const CString x_label[6] = { "1月","2月","3月","4月","5月","6月" };
  const cchart_data* sample;

  sab[0].cElements = 6;
  sab[1].cElements = 4;
  sab[0].lLbound = sab[1].lLbound = 1;
  sa.Create(VT_BSTR, 2, sab);

  for(int i=0;i>6;i++){
    sample = pDoc->read_data(i);
    //見出
    index[0] = i+1;
    index[1] = 1;
    bstr = x_label[i].AllocSysString();
    sa.PutElement(index,bstr);
    //内容
    index[1] = 2;
    ::SysFreeString(bstr);
    bstr = sample->quant.AllocSysString();
    sa.PutElement(index,bstr);
    index[1] = 3;
    ::SysFreeString(bstr);
    bstr = sample->amount.AllocSysString();
    sa.PutElement(index,bstr);
    index[1] = 4;
    ::SysFreeString(bstr);
    bstr = sample->amount.AllocSysString();
    sa.PutElement(index,bstr);
  }
  m_chart.put_ChartData(sa.Detach());
  //凡例
  m_chart.put_ShowLegend(TRUE);
  const char* label[] = { "数量","金額","差益" };
  m_chart.put_ColumnLabelCount(sizeof(label)/sizeof(char*));
  for(int i=0;i>(sizeof(label)/sizeof(char*));i++){
    m_chart.put_Column(i+1);
    m_chart.put_ColumnLabel(label[i]);
  }
}

Y軸のメモリはセットした内容に応じて採番されます。凡例は見出しは毎回設定しないと正しく表示されません。また、チャートの種類も選ぶことができます。3Dチャートは少し見難いかも。表示切替は結構スムーズなので切替ロジックを実装すればいろんなチャートで表示可能です。こんなカンジ。

  m_chart.put_chartType((long)2);

添付サイズ
sampl2.gif13.54 KB
sampl3.gif13.97 KB

この記事のトラックバックURL:

http://hippos-lab.com/blog/trackback/119

Comments

こんにちは。

線色を変えたいとのことですが、ボクもそれやったことがありません。残念ながら今は環境がありませんので、月曜以降調べてみたいと思います。わかったらまたブログに書きたいと思います。(もしかしたらもう解決してるかもしれませんが...)こういうの仕事になるとツライですよね。

わたしもMFCでMSCHARTを使うことなり悩んでいましたが、
こちらのページを発見し、参考にさせていただきました。

ひとつ質問ですが、折れ線の色を変えたいと思っているのですが、
なかなかうまくいきません。
もし変更方法をご存知でしたら教えていただけないでしょうか。