BarPlot
首先在XML文件中添加一个hostview: PTGraphHostingView name="IDC_PLOTHOSTVIEW_BY"
CPTGraphHostingView* host;
double yMax;
CString plothost;
host = (CPTGraphHostingView*)DuiGetDlgItem(_T("IDC_PLOTHOSTVIEW_BY"));
plothost = _T("benyue");
yMax = Upper(m_byYMax);
CPTLegend* legend;
CPTPlotSymbol symbol;
CPTXYGraph* graph;
一个hostview中需要先设置一个画布CPTXYGraph对象,BarPlot只能添加到这个画布对象中 ,当一个界面中有多个hostview时,这些hostview中的BarPlot需要知道自己属于哪个hostview,字符串变量plothost就是用来标识所处的hostview的。
由于BarPlot需要绘制坐标轴,所以首先需要知道Y轴绘制的逻辑值的最大值,yMax就是这个最大值。
graph = (CPTXYGraph*)host->GetHostedGraph();
if (graph == NULL)
{
graph = new CPTXYGraph;
host->SetHostedGraph(graph);
}
host->Reset();
CPTXYGraph是支持XY轴坐标系的画布,确保只设置一次,因为这段代码可能会多次执行,所以先判断一下是否为NUL。
host->Reset()这行代码也是考虑到这段代码可能被多次执行的原因,Reset()函数会把自己的画布里的坐标轴的刻度值清空,否则多次设置坐标轴会导致坐标刻度重复增加。
legend = host->Legend();
legend->align = CPTLegendAlignTop;
取得图例,并设置图例放在顶部。
graph->originPoint.x = 70;
graph->originPoint.y = 50;
设置画布中坐标轴的原点
如图,灰色为画布,坐标轴原点距离画布原点横向距离70像素,垂直距离50像素。
CPTTextStyle xLabelTextStyle;//X轴坐标标签字体
xLabelTextStyle.fontSize = 12;
xLabelTextStyle.color = RGB(20, 20, 20);
CPTAxis *x = graph->AxisSet()->xAxis();//X轴
x->majorTickLength = 5;//主刻度长度,按像素
x->minorTicksPerInterval = 1;//主刻度之间几个细分刻度
x->minorTickLength = 2;//细分刻度的长度,按像素
x->tickDirection = CPTSignNegative;//刻度方向,CPTSignNegative代表从X坐标轴向下绘制,CPTSignPositive代表从X坐标轴向上绘制
x->labelTextStyle = xLabelTextStyle;
以上为X轴刻度及标签的基本设置。
int year,month,days;
GetCurrentMonth(year, month);//本月
days=GetDays(year, month);//本月的天数
CString s;
CString location;
CPTAxisLabel* label;
for (int i = 0; i < days; i++)
{
location.Format(_T("%d"), i + 1);
if (i % 3 == 1 || i==days-1)
s.Format(_T("%d日"), i + 1);
else
s.Empty();
label = x->NewLabel(location, s);
label->offset = -1 * (x->majorTickLength + x->labelOffset);
label->rotation = -45 * PI / 180;
x->AddMajorTickLocations(location);
}
以上为添加X轴主刻度,location为一个字符串,与刻度是一一对应的关系,不可重复,需要几个刻度就添加几个location
CPTTextStyle yLabelTextStyle;//Y轴坐标标签字体
yLabelTextStyle.fontSize = 18;
yLabelTextStyle.color = RGB(20, 20, 20);
CPTAxis *y = graph->AxisSet()->yAxis();//Y轴
y->labelTextStyle = yLabelTextStyle;
y->majorTickLength = 3;
y->minorTicksPerInterval = 1;
y->minorTickLength = 2;
y->tickDirection = CPTSignPositive;
以上为Y轴刻度及标签的基本设置。
int majorIncrement = (int)(yMax / 5);
int minorIncrement = majorIncrement / 2;
if (majorIncrement == 0)
majorIncrement = 1;
if (minorIncrement == 0)
minorIncrement = 1;
以上代码按Y值的最大值均分成5个刻度,会按按主刻度绘制5条平行于X轴的直线,再将主刻度一分为二为细分刻度。
for (int j = minorIncrement; j <= yMax; j += minorIncrement)
{
location.Format(_T("%d"), j);
int mod = j%majorIncrement;
if (mod == 0)
{
s.Format(_T("%d"), j);
label = y->NewLabel(location, s);
label->offset = -1 * (y->majorTickLength + y->labelOffset);
y->AddMajorTickLocations(location);//添加主刻度
}
else
{
y->AddMinorTickLocations(location);//添加细分刻度
}
}
以上代码添加刻度值,注意,Y轴刻度的location必须是对应的刻度值。
CPTBarPlot* plot;
CPTLineStyle ls;
ls.lineWidth = 9;
for (int i = 0; i<2; i++)
{
plot = new CPTBarPlot;
plot->host = plothost;//hostview标识符
s.Format(_T("%d"), i);
plot->identifier = s;//标识符
plot->barWidth = 4;// bar的宽度,按像素
plot->barWidthOffset = 2;//与下一个plot之间的间隔,按像素
plot->dataSource = this;//数据源代理
if (i == 0)
{
plot->legendTitle.Format(_T("销售金额"));//图例名称
ls.lineColor = RGB(115, 225, 65);//plot的颜色
}
else if (i == 1)
{
plot->legendTitle.Format(_T("退货金额"));//图例名称
ls.lineColor = RGB(245, 85, 70);//plot的颜色
}
plot->dataLineStyle = ls;
graph->addPlot(plot);//将plot添加到画布
legend->AddPlot(plot);//将该plot添加到图例
}
host->ShowLegend();//显示图例
如上图,里面有两个BarPlot,绿色的一个,红色的一个。
barWidth与barWidthOffset
barWidth:Bar的宽度
barWidthOffset:Bar与下一个Bar之间的间隔,如下图:
W1与W2是每个Bar的宽度,sep1为Bar1与Bar2的间隔距离,w为主刻度宽度,左右两侧的宽度x是根据w、W1、W2、sep1自动计算出来的。
数据源代理,实现CPTBarPlotDataSource接口
-
int numberOfRecordsForPlot(CPTPlot* plot)
返回X轴主刻度数量 -
NSNumber numberForPlot(CPTPlot *plot, UINT fieldEnum, UINT recordIndex)
根据X轴主刻度索引recordIndex返回对应的Y值
NSNumber CDuiPanelRp24::numberForPlot(CPTPlot *plot, UINT fieldEnum, UINT recordIndex)
{
NSNumber ret;
if (fieldEnum == CPTScatterPlotFieldX)
{
ret.idata = recordIndex;
}
else
{
IParameters* pi;
CString netwr;
CString month;
month.Format(_T("%d"), recordIndex + 1);
CString id = plot->identifier;
CString host = plot->host;
if (host == _T("bennian"))
{
switch (_ttoi(id))
{
case 0:
pi=m_bennian.IParametersOfKey(month);
pi->GetParameter(_T("xsje"), netwr);
break;
case 1:
pi = m_bennian.IParametersOfKey(month);
pi->GetParameter(_T("thje"), netwr);
break;
}
}
}
}