mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 22:02:58 -06:00
365 lines
8.8 KiB
C++
365 lines
8.8 KiB
C++
#include "Pie.h"
|
|
static void DrawPie(Draw& w, Point centre, int r, int start, int alpha, int width, class::Color fill, class::Color outline,uint64 pattern,class::Color background )
|
|
{
|
|
const int dalpha=1;
|
|
int n= alpha/dalpha;
|
|
Vector <Point> vP;
|
|
vP<<centre;
|
|
int ix;
|
|
int iy;
|
|
for (int i=0; i<=n; i++)
|
|
{
|
|
double x=centre.x+ r*cos((start+i*dalpha)*M_PI/1800);
|
|
ix=fround(x);
|
|
double y=centre.y+r*sin((start+i*dalpha)*M_PI/1800);
|
|
iy=fround(y);
|
|
double dxy=(x-ix)*(x-ix)+(y-iy)*(y-iy);
|
|
if(dxy<0.1 || i ==0 || i==n)
|
|
vP<<Point(ix,iy);
|
|
//if(!(dynamic_cast<const DrawingDraw *>(&w)) && !w.IsPrinter()) w.DrawRect(ix,iy,1,1,Blend(fill,background,150));
|
|
if(w.IsGui()) w.DrawRect(ix,iy,1,1,Blend(fill,background,150));
|
|
}
|
|
vP<<centre;
|
|
w.DrawPolygon(vP,fill,width,outline,pattern,Null);
|
|
|
|
}
|
|
|
|
static void DrawScaledPie(Draw& w, Point centre, int r, int start, int alpha, int width=0, class::Color fill=Null, class::Color outline=Black, int scale=1,uint64 pattern=0,class::Color background=White)
|
|
{
|
|
DrawPie(w, centre, scale*r, start, alpha, scale*width, fill, outline,pattern,background);
|
|
}
|
|
|
|
static void DrawMLText(Draw& w, const Rect& box, String content, const Font& f, class::Color textColor=Black)
|
|
{
|
|
int L=box.Width();
|
|
int H=box.Height();
|
|
int count=0;
|
|
Size sz;
|
|
content.Cat(' ');
|
|
while(!content.IsEmpty())
|
|
{
|
|
int pos=0;//current position
|
|
int lastpos=0;
|
|
int toDraw=0;
|
|
|
|
while(toDraw<L && pos>=0)
|
|
{
|
|
lastpos=pos+1;
|
|
pos=content.Find(' ',lastpos);
|
|
sz= GetTextSize(content.Left(pos+1), f);
|
|
toDraw=sz.cx;
|
|
}
|
|
if (pos<0)
|
|
{
|
|
sz= GetTextSize(content, f);
|
|
toDraw=sz.cx;
|
|
if(toDraw<L) lastpos=content.GetCount();
|
|
}
|
|
|
|
w.DrawText(box.left, box.top+count*fround(f.GetHeight()*1.2),content.Left(lastpos), f,textColor);
|
|
sz=GetTextSize(content.Mid(lastpos,pos-lastpos), f);
|
|
if(sz.cx>=L) return;
|
|
count++;
|
|
content=content.Mid(lastpos);
|
|
}
|
|
}
|
|
|
|
|
|
PieChart& PieChart::SetColor(const class::Color& _color)
|
|
{
|
|
backColor=_color;
|
|
return *this;
|
|
}
|
|
|
|
PieChart& PieChart::SetTitle(const String& _title)
|
|
{
|
|
title=_title;
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::SetTitleFont(const Font& fontTitle)
|
|
{
|
|
titleFont=fontTitle;
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::SetTitleColor(const class::Color& colorTitle)
|
|
{
|
|
titleColor=colorTitle;
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::TitlePos(titlePosition pos)
|
|
{
|
|
titlePos=pos;
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::SetTitleGap(const int& gap)
|
|
{
|
|
titleGap=gap;
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::SetRadius(const int& r)
|
|
{
|
|
radius=r;
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::ShowPercent(bool show)
|
|
{
|
|
showPercent=show;
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::SetPercentBack(const class::Color& pbcolor)
|
|
{
|
|
percentBack=pbcolor;
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::SetLegendFont(const Font& fontLegend)
|
|
{
|
|
legendFont=fontLegend;
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::SetLegendTextColor(const class::Color& colorLegend)
|
|
{
|
|
legendTextColor=colorLegend;
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::SetLegendBackColor(const class::Color& colorBack)
|
|
{
|
|
legendBackColor=colorBack;
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::SetLegend_cx(const int& h)
|
|
{
|
|
legend_cx=h;
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::SetLegend_cy(const int& v)
|
|
{
|
|
legend_cy=v;
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::SetShowLegend(bool show)
|
|
{
|
|
showLegend=show;
|
|
return *this;
|
|
}
|
|
void PieChart::AddCategory(const String& name, const double& value, const class::Color& catcolor)
|
|
{
|
|
vNames.Add(name);
|
|
vValues.Add(value);
|
|
vColors.Add(catcolor);
|
|
Refresh();
|
|
}
|
|
void PieChart::RemoveCategory(const int& index)
|
|
{
|
|
if(!vValues.IsEmpty() && vValues.GetCount()>index)
|
|
{
|
|
vNames.Remove(index);
|
|
vValues.Remove(index);
|
|
vColors.Remove(index);
|
|
Refresh();
|
|
}
|
|
}
|
|
PieChart& PieChart::SetCatValue(const int& index, const double& value)
|
|
{
|
|
if(!vValues.IsEmpty() && vValues.GetCount()>index)
|
|
{
|
|
vValues[index]=value;
|
|
Refresh();
|
|
}
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::SetCatName(const int& index, const String& name)
|
|
{
|
|
if(!vNames.IsEmpty() && vNames.GetCount()> index)
|
|
{
|
|
vNames[index]=name;
|
|
Refresh();
|
|
}
|
|
return *this;
|
|
}
|
|
PieChart& PieChart::SetCatColor(const int& index, const class::Color& catcolor)
|
|
{
|
|
if(!vColors.IsEmpty() && vColors.GetCount()> index)
|
|
{
|
|
vColors[index]=catcolor;
|
|
Refresh();
|
|
}
|
|
return *this;
|
|
}
|
|
double PieChart::GetCatValue(const int& index) const
|
|
{
|
|
if(!vValues.IsEmpty() && vValues.GetCount()>index)
|
|
{
|
|
return vValues[index];
|
|
}
|
|
else return -1;
|
|
}
|
|
String PieChart::GetCatName(const int& index) const
|
|
{
|
|
if(!vNames.IsEmpty() && vNames.GetCount()> index)
|
|
{
|
|
return vNames[index];
|
|
}
|
|
else return "";
|
|
}
|
|
Acolor PieChart::GetCatColor(const int& index) const
|
|
{
|
|
if(!vColors.IsEmpty() && vColors.GetCount()> index)
|
|
{
|
|
return vColors[index];
|
|
}
|
|
else return Null;
|
|
}
|
|
int PieChart::GetCatCount() const
|
|
{
|
|
return vColors.GetCount();
|
|
}
|
|
|
|
void PieChart::PaintPie(Draw& w, int scale)
|
|
{
|
|
if(vValues.GetCount()>0)
|
|
{
|
|
double sum=0;
|
|
int alfa0=-900;
|
|
int a0=0;
|
|
for(int i=0;i<vValues.GetCount(); i++)
|
|
{
|
|
sum+=vValues[i];
|
|
}
|
|
int cx,cy;
|
|
if(showLegend) cx=scale*(GetSize().cx+radius-legend_cx)/3;
|
|
else cx=(scale*GetSize().cx)/2;
|
|
|
|
if(titlePos==BOTTOM)
|
|
cy=scale*(GetSize().cy-titleGap-titleFont.GetHeight())/2;
|
|
else
|
|
cy=scale*(GetSize().cy+titleGap+titleFont.GetHeight())/2;
|
|
Acolor bc;
|
|
if (backColor==(Acolor)Null ) bc=LtGray;
|
|
else bc=backColor;
|
|
|
|
for(int i=0;i<vValues.GetCount(); i++)
|
|
{
|
|
|
|
DrawScaledPie(w,Point(cx,cy),
|
|
radius, alfa0, fround(3600.0*vValues.At(i)/sum),1,vColors.At(i),vColors.At(i),scale,0,bc);
|
|
|
|
alfa0+=fround(3600.0*vValues[i]/sum);
|
|
|
|
}
|
|
if(showPercent)
|
|
{
|
|
alfa0=-900;
|
|
for(int i=0;i<vValues.GetCount(); i++)
|
|
{
|
|
a0=alfa0;
|
|
alfa0+=fround(3600.0*vValues[i]/sum);
|
|
String percent=GetPercent(vValues[i],sum);
|
|
Font scaledFont;
|
|
scaledFont.Height(scale*StdFont().GetHeight());
|
|
scaledFont.Width(scale*StdFont().GetWidth());
|
|
Size sz= GetTextSize(percent, scaledFont);
|
|
|
|
int px=cx+int(scale*radius*cos(3.14*(alfa0+a0)/3600)/1.3)-sz.cx/2;
|
|
int py=cy+int(scale*radius*sin(3.14*(alfa0+a0)/3600)/1.3)-sz.cy/2;
|
|
w.DrawRect(px+1-1,py,sz.cx-2+2,1,percentBack);
|
|
w.DrawRect(px-1,py+1,sz.cx+2,sz.cy-2,percentBack);
|
|
w.DrawRect(px+1-1,py+sz.cy-1,sz.cx-2+2,1,percentBack);
|
|
w.DrawText(px, py, percent,scaledFont);
|
|
}
|
|
}
|
|
if(showLegend)
|
|
{
|
|
int lx=2*scale*(GetSize().cx+radius-legend_cx)/3;
|
|
int ly=cy-scale*legend_cy/2;
|
|
w.DrawRect(lx,ly,scale*legend_cx,scale*legend_cy,legendBackColor);
|
|
int nr=GetCatCount();
|
|
int dly=scale*legend_cy/nr;
|
|
for(int i=0;i<nr;i++)
|
|
{
|
|
int fh=scale*(legendFont.GetHeight()-3);
|
|
w.DrawRect(lx+2*scale,ly+scale*3+i*dly,fh,fh,vColors[i]);
|
|
Rect box;
|
|
box.Set(Point(lx+fround(1.8*fh),ly+i*dly),Point(lx+scale*legend_cx,ly+(i+1)*dly));
|
|
Font scaledFont;
|
|
scaledFont.Height(scale*legendFont.GetHeight());
|
|
scaledFont.Width(scale*legendFont.GetWidth());
|
|
::DrawMLText(w, box,vNames[i],scaledFont,legendTextColor);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void PieChart::DrawChart(Draw& w, int scale)
|
|
{
|
|
Size pcsz = GetSize();
|
|
w.DrawRect(scale*pcsz,backColor);
|
|
Size sz;
|
|
sz.cx=0;
|
|
sz.cy=0;
|
|
if(!title.IsEmpty())
|
|
{
|
|
Font FontTitle6;
|
|
FontTitle6=titleFont;
|
|
FontTitle6.Height(scale*titleFont.GetHeight());
|
|
FontTitle6.Width(scale*titleFont.GetWidth());
|
|
sz= GetTextSize(title, FontTitle6);
|
|
if(titlePos==TOP) w.DrawText((scale*GetSize().cx-sz.cx)/2,scale*titleGap,title,FontTitle6,titleColor);
|
|
else if(titlePos==BOTTOM) w.DrawText((scale*GetSize().cx-sz.cx)/2,scale*(GetSize().cy-titleFont.GetHeight()-titleGap),title,FontTitle6,titleColor);
|
|
|
|
}
|
|
PaintPie(w, scale);
|
|
|
|
}
|
|
|
|
void PieChart::Paint(Draw& w)
|
|
{
|
|
DrawChart(w,1);
|
|
}
|
|
String PieChart::GetPercent(double a, double total)
|
|
{
|
|
double p=a*100/total;
|
|
String perc=FormatDouble(p,1);
|
|
perc<<'%';
|
|
return perc;
|
|
}
|
|
Drawing PieChart::GetDrawing()
|
|
{
|
|
DrawingDraw ddw(6*GetSize());
|
|
DrawChart (ddw, 6);
|
|
return ddw;
|
|
}
|
|
Image PieChart::GetImage(int scale)
|
|
{
|
|
ImageDraw idraw(scale*GetSize());
|
|
DrawChart (idraw,scale);
|
|
return idraw;
|
|
}
|
|
|
|
#ifdef PLATFORM_WIN32
|
|
void PieChart::SaveAsMetafile(const char* file)
|
|
{
|
|
WinMetaFileDraw wmfd;
|
|
wmfd.Create(6*GetSize().cx,6*GetSize().cy,"Pie","PieChart",file);
|
|
DrawChart (wmfd, 6);
|
|
wmfd.Close();
|
|
}
|
|
#endif
|
|
|
|
PieChart::PieChart():
|
|
backColor(White),
|
|
titleFont(StdFont(16)),
|
|
titlePos(TOP), titleGap(2),titleColor(Black),
|
|
radius(60),
|
|
showPercent(true),
|
|
percentBack(Null),
|
|
legendFont(StdFont()),
|
|
legendTextColor(Black),legendBackColor(Null),
|
|
legend_cx(60), legend_cy(120),
|
|
showLegend(true)
|
|
{
|
|
Transparent();
|
|
BackPaint();
|
|
}
|
|
PieChart::~PieChart(){}
|
|
|