📄 plotobs.cpp
字号:
FileIO(INIT_VARS);
if(src == FILE_READ) {
FileIO(FILE_READ);
}
}
FreqDist::~FreqDist()
{
int i;
if(curr_data) delete(curr_data); curr_data = 0L;
if(ssRef) free(ssRef); ssRef = 0L;
if(plots) {
for(i = 0; i < nPlots; i++) if(plots[i]) DeleteGO(plots[i]);
free(plots); plots=0L;
}
if(name) free(name); name=0L;
}
void
FreqDist::DoPlot(anyOutput *o)
{
int i;
if(!plots || !o || !data || !parent) return;
parent->Command(CMD_REG_AXISPLOT, (void*)this, o);
if(use_xaxis || use_yaxis) ApplyAxes(o);
for(i = 0; i < nPlots; i++) {
if(plots[i]) {
if(plots[i]->Id >= GO_PLOT && plots[i]->Id < GO_GRAPH){
if(((Plot*)plots[i])->hidden == 0) plots[i]->DoPlot(o);
}
else plots[i]->DoPlot(o);
}
}
if(use_xaxis || use_yaxis) parent->Command(CMD_AXIS, 0L, o);
}
bool
FreqDist::Command(int cmd, void *tmpl, anyOutput *o)
{
int i;
switch (cmd) {
case CMD_MOUSE_EVENT:
if(hidden || ((MouseEvent*)tmpl)->Action != MOUSE_LBUP || CurrGO) return false;
case CMD_LEGEND:
if(plots) for(i = 0; i < nPlots; i++) {
if(plots[i]){
if(plots[i]->Id >= GO_PLOT && plots[i]->Id < GO_GRAPH){
if(((Plot*)plots[i])->hidden == 0) plots[i]->Command(cmd, tmpl, o);
}
else plots[i]->Command(cmd, tmpl, o);
}
}
return false;
case CMD_HIDE_MARK:
if(plots) for(i = 0; i < nPlots; i++) if(plots[i]){
if(tmpl == (void*)plots[i]) {
plots[i]->DoMark(o, false);
return true;
}
else if(plots[i]->Command(cmd, tmpl, o)) return true;
}
return false;
case CMD_DELOBJ:
if(plots && tmpl && parent) for(i = 0; i < nPlots; i++) if(plots[i]){
if(tmpl == (void*)plots[i]) {
DeleteGO(plots[i]); plots[i]=0L;
if(i == 1) type=0;
parent->Command(CMD_REDRAW, 0L, o);
return true;
}
}
return false;
case CMD_UPDATE:
if(data && parent && plots) {
ProcData(0);
if(!curr_data) return false;
for(i = 0; i < nPlots; i++) if(plots[i]) {
plots[i]->Command(CMD_SET_DATAOBJ, curr_data, o);
plots[i]->Command(CMD_UPDATE, 0L, o);
}
}
return false;
case CMD_SET_DATAOBJ:
Id = GO_FREQDIST;
data = (DataObj *)tmpl;
return true;
case CMD_MRK_DIRTY:
dirty = true;
case CMD_SETSCROLL: case CMD_REDRAW:
if(parent) return parent->Command(cmd, tmpl, o);
return false;
case CMD_USEAXIS:
return UseAxis(*((int*)tmpl));
case CMD_AUTOSCALE:
if(hidden) return false;
if(dirty){
Bounds.Xmin = Bounds.Ymin = HUGE_VAL;
Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
}
else{
if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH &&
Bounds.Xmax > Bounds.Xmin && Bounds.Ymax > Bounds.Ymin) {
((Plot*)parent)->CheckBounds(Bounds.Xmin, Bounds.Ymin);
((Plot*)parent)->CheckBounds(Bounds.Xmax, Bounds.Ymax);
return true;
}
}
dirty = false;
if(plots) for(i = 0; i < nPlots; i++) {
if(plots[i]){
if(plots[i]->Id >= GO_PLOT && plots[i]->Id < GO_GRAPH){
if(((Plot*)plots[i])->hidden == 0) plots[i]->Command(cmd, tmpl, o);
}
else plots[i]->Command(cmd, tmpl, o);
}
}
if(parent && parent->Id >= GO_PLOT && parent->Id < GO_GRAPH &&
Bounds.Xmax > Bounds.Xmin && Bounds.Ymax > Bounds.Ymin) {
((Plot*)parent)->CheckBounds(Bounds.Xmin, Bounds.Ymin);
((Plot*)parent)->CheckBounds(Bounds.Xmax, Bounds.Ymax);
return true;
case CMD_DROP_GRAPH:
if(tmpl && plots && nPlots >1) {
if(plots[1]) DeleteGO(plots[1]);
plots[1] = (GraphObj*)tmpl; dirty = true; plots[1]->parent = this;
plots[1]->Command(CMD_SET_DATAOBJ, curr_data, o);
Command(CMD_AUTOSCALE, 0L, o);
return true;
}
return false;
}
}
return false;
}
void
FreqDist::ProcData(int sel)
{
AccRange *ar;
int nv, i, j, r, c, ncl, *f_data, cb;
double min = HUGE_VAL, max = -HUGE_VAL, sum, mean, sd, tmp, d, *s_data;
Bar **bars = 0L;
char *fo;
if(!parent || !data || !ssRef || !plots) return;
if(curr_data) delete(curr_data);
if((curr_data = new DataObj()) && (ar = new AccRange(ssRef))) {
nv = ar->CountItems(); ar->GetFirst(&c, &r);
if(!(s_data = (double*)malloc(nv * sizeof(double)))) {
delete(ar); return;
}
for(sum = 0.0, nv = 0; ar->GetNext(&c, &r); ) if(data->GetValue(r, c, &tmp)) {
sum+=tmp; s_data[nv++] = tmp;
}
mean = sum / ((double)nv); delete(ar);
for(sum = 0.0, j = 0; j < nv; j++){
if(s_data[j] > max) max = s_data[j]; if(s_data[j] < min) min = s_data[j];
sum += ((d = (s_data[j] - mean)) * d);
}
sd = sqrt(sum/((double)nv));
step = fabs(step);
if(sel == -1) {
start = min; step = (max - min)/(step != 0.0 ? step : 7.0);
}
else if(sel == -2) {
min = start;
}
ncl = (int)(floor((max-start)/step));
if(plots[0] && (max > (Bounds.Xmax+step/2.0) || min < (Bounds.Xmin-step/2.0))) {
DeleteGO(plots[0]); plots[0] = 0L;
}
if(!plots[0])bars = (Bar**)calloc(ncl, sizeof(Bar*));
f_data = (int*)calloc(ncl+1, sizeof(int));
for(i = 0; i < nv; i++) {
j = (int)(floor((s_data[i] - start)/step));
if(j >= 0 && j < ncl) f_data[j]++;
else if(s_data[i] == max) f_data[j-1]++;
}
if(f_data[ncl]) ncl++;
curr_data->Init(ncl, 2);
for(i = 0; i< ncl; i++) {
curr_data->SetValue(i, 0, tmp = start + i * step + step * .5);
curr_data->SetValue(i, 1, (double)f_data[i]);
if(bars) {
bars[i] = new Bar(this, 0L, tmp, (double)f_data[i], BAR_VERTB | BAR_RELWIDTH, 0, i, 1, i);
}
}
free(s_data); free(f_data);
if(bars && (plots[0] = new PlotScatt(this, data, ncl, bars))){
plots[0]->Command(CMD_BAR_FILL, &BarFill, 0L);
plots[0]->SetColor(COL_BAR_LINE, BarLine.color);
plots[0]->SetSize(SIZE_BAR_LINE, BarLine.width);
}
if(plots[0]){
plots[0]->Command(CMD_SET_DATAOBJ, curr_data, 0L);
plots[0]->Command(CMD_AUTOSCALE, 0L, 0L);
}
if(type && (fo = (char*)malloc(1000))) {
cb = sprintf(fo, "[1=Function]\n");
cb += sprintf(fo+cb,"x1= %g\n", min);
cb += sprintf(fo+cb,"x2= %g\n", max);
cb += sprintf(fo+cb,"xstep= %g\n", (max-min)/100.0);
cb += sprintf(fo+cb,"Line= 0.4 6 0x000000ff 0x0\n");
cb += sprintf(fo+cb,"f_xy=\"A=%g; SD=%g; M=%g\\n", nv*step, sd, mean);
cb += sprintf(fo+cb,"ex=(x-M)/SD; ex=-0.5*ex*ex\\n");
cb += sprintf(fo+cb,"y=(A/(SD*2.5066283))*exp(ex)\\n\"\n");
OpenGraph(this, 0L, (unsigned char *)fo);
free(fo);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Regression line and symbols
Regression::Regression(GraphObj *par, DataObj *d):Plot(par, d)
{
FileIO(INIT_VARS);
Id = GO_REGRESSION;
}
Regression::Regression(int src):Plot(0L, 0L)
{
int i;
FileIO(INIT_VARS);
if(src == FILE_READ) {
FileIO(FILE_READ);
//now set parent in all children
if(rLine) rLine->parent = this;
if(sde) sde->parent = this;
if(Symbols)
for(i = 0; i < nPoints; i++) if(Symbols[i]) Symbols[i]->parent = this;
}
}
Regression::~Regression()
{
Command(CMD_FLUSH, 0L, 0L);
if(name) free(name); name=0L;
Undo.InvalidGO(this);
}
double
Regression::GetSize(int select)
{
return Plot::GetSize(select);
}
bool
Regression::SetSize(int select, double value)
{
int i;
switch(select & 0xfff){
case SIZE_SYMBOL:
case SIZE_SYM_LINE:
if(Symbols) for(i = 0; i < nPoints; i++)
if(Symbols[i]) Symbols[i]->SetSize(select, value);
return true;
}
return false;
}
bool
Regression::SetColor(int select, DWORD col)
{
int i;
switch(select) {
case COL_SYM_LINE:
case COL_SYM_FILL:
if(Symbols) for(i = 0; i < nPoints; i++)
if(Symbols[i]) Symbols[i]->SetColor(select, col);
return true;
}
return false;
}
void
Regression::DoPlot(anyOutput *o)
{
int i;
parent->Command(CMD_REG_AXISPLOT, (void*)this, o);
if(use_xaxis || use_yaxis) ApplyAxes(o);
if(sde){
if(rLine && sde->Command(CMD_DROP_OBJECT, rLine, o)) rLine = 0L;
sde->DoPlot(o);
}
if(rLine) rLine->DoPlot(o);
if(Symbols) for(i = 0; i < nPoints; i++)
if(Symbols[i]) Symbols[i]->DoPlot(o);
if(use_xaxis || use_yaxis) parent->Command(CMD_AXIS, 0L, o);
dirty = false;
}
bool
Regression::Command(int cmd, void *tmpl, anyOutput *o)
{
int i, j;
static MouseEvent *mev;
bool bEmpty,bRedraw = false;
LineDEF *ld;
switch (cmd) {
case CMD_MOUSE_EVENT:
if(hidden) return false;
mev = (MouseEvent *) tmpl;
switch(mev->Action) {
case MOUSE_LBUP:
if(Symbols) for (i = nPoints-1; i >= 0; i--)
if(Symbols[i] && Symbols[i]->Command(cmd, tmpl, o))return true;
if(rLine && rLine->Command(cmd, tmpl, o)) return true;
if(sde && sde->Command(cmd, tmpl, o)) return true;
break;
}
break;
case CMD_LEGEND:
if(tmpl && ((GraphObj*)tmpl)->Id == GO_LEGEND && rLine && rLine->Id == GO_REGLINE) {
ld = rLine->GetLine();
if(Symbols) {
for (i = 0; i < nPoints && i < 100; i++)
if(Symbols[i]) ((Legend*)tmpl)->HasSym(ld, Symbols[i]);
}
else ((Legend*)tmpl)->HasFill(ld, 0L);
return true;
}
return false;
case CMD_MRK_DIRTY:
if(rLine || sde) Recalc();
dirty = true;
case CMD_SETSCROLL:
case CMD_REDRAW:
if(parent) return parent->Command(cmd, tmpl, o);
return false;
case CMD_USEAXIS:
UseAxis(*((int*)tmpl));
return true;
case CMD_DROP_OBJECT:
if(tmpl && ((GraphObj*)tmpl)->Id == GO_REGLINE && !rLine) {
rLine = (RegLine *)tmpl;
rLine->parent = this;
return true;
}
break;
case CMD_FLUSH:
if(yRange) free(yRange); if(xRange) free(xRange);
yRange = xRange = 0L;
if(rLine) DeleteGO(rLine);
if(sde) DeleteGO(sde);
rLine = 0L; sde = 0L;
if(Symbols) for (i = nPoints-1; i >= 0; i--)
if(Symbols[i]) DeleteGO(Symbols[i]);
if(Symbols) free(Symbols);
Symbols = 0L;
return true;
case CMD_AUTOSCALE:
if(dirty){
Bounds.Xmin = Bounds.Ymin = HUGE_VAL;
Bounds.Xmax = Bounds.Ymax = -HUGE_VAL;
}
else return true;
dirty = false;
case CMD_SET_DATAOBJ:
if(cmd == CMD_SET_DATAOBJ) {
Id = GO_REGRESSION;
data = (DataObj *)tmpl;
}
if(rLine) rLine->Command(cmd, tmpl, o);
if(Symbols) for (i = 0; i < nPoints; i++)
if(Symbols[i]) Symbols[i]->Command(cmd, tmpl, o);
return true;
case CMD_SYMTEXT: case CMD_SYM_RANGETEXT:
case CMD_SYMTEXTDEF: case CMD_SYM_TYPE:
if(Symbols) for(i = 0; i < nPoints; i++)
if(Symbols[i]) Symbols[i]->Command(cmd, tmpl, o);
return true;
case CMD_HIDE_MARK:
return false;
case CMD_SAVE_SYMBOLS:
return SavVarObs((GraphObj **)Symbols, nPoints, 0L);
case CMD_UPDATE:
if(Symbols) {
SavVarObs((GraphObj**)Symbols, nPoints, UNDO_CONTINUE);
for(i = 0; i < nPoints; i++)
if(Symbols[i]) Symbols[i]->Command(cmd, tmpl, o);
if(rLine || sde) Recalc();
return true;
}
return false;
case CMD_DELOBJ:
if(!parent || !o) return false;
dirty = bEmpty = bRedraw = false;
if(Symbols) for(i = 0; i < nPoints; i++)
if(Symbols[i] && (void*)Symbols[i] == tmpl) {
bRedraw = true;
o->HideMark();
Undo.DeleteGO((GraphObj**)(&Symbols[i]), 0L, o);
for(j = 0, bEmpty = true; j < nPoints; j++) {
if(Symbols[j]) {
bEmpty = false;
break;
}
}
if(!bEmpty && dirty) Command(CMD_AUTOSCALE, 0L, o);
break;
}
if(rLine && (void*)rLine == tmpl) {
Undo.DeleteGO((GraphObj**)(&rLine), 0L, o);
if(!Symbols && !sde) parent->Command(CMD_DELOBJ_CONT, this, o);
else bRedraw = true;
}
if(sde && (void*)sde == tmpl) {
sde->Command(CMD_RMU, 0L, 0L);
Undo.DeleteGO((GraphObj**)(&sde), 0L, o);
if(!Symbols && !rLine) parent->Command(CMD_DELOBJ_CONT, this, o);
else bRedraw = true;
}
if(bEmpty && Symbols) {
Undo.DropMemory(this, (void**)(&Symbols), UNDO_CONTINUE);
bRedraw = false;
if(!rLine && !sde) parent->Command(CMD_DELOBJ_CONT, this, o);
else bRedraw = true;
}
if(bRedraw)parent->Command(CMD_REDRAW, 0L, o);
return bRedraw;
}
return false;
}
void
Regression::Recalc()
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -