⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plotobs.cpp

📁 Linux/windows 环境下跨平台开发程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:

	if(Whiskers) {
		for(i = 0; i < nPoints; i++) if(Whiskers[i]) DeleteGO(Whiskers[i]);
		free (Whiskers);
		}
	if(Boxes) {
		for(i = 0; i < nPoints; i++) if(Boxes[i]) DeleteGO(Boxes[i]);
		free (Boxes);
		}
	if(Symbols) {
		for(i = 0; i < nPoints; i++) if(Symbols[i]) DeleteGO(Symbols[i]);
		free (Symbols);
		}
	if(Labels) {
		for(i = 0; i < nPoints; i++) if(Labels[i]) DeleteGO(Labels[i]);
		free (Labels);
		}
	if(TheLine) DeleteGO(TheLine);
	if(curr_data) delete curr_data;		curr_data = 0L;
	if(xRange) free(xRange);			xRange = 0L;
	if(yRange) free(yRange);			yRange = 0L;
	if(case_prefix) free(case_prefix);	case_prefix = 0L;
	if(name) free(name);				name=0L;
	Undo.InvalidGO(this);
}

double
BoxPlot::GetSize(int select)
{
	int i;
	double ft1, ft2, d;

	switch(select){
	case SIZE_BOXMINX:
		if(BoxDist.fx >= 0.0001) return BoxDist.fx;
		if((!Boxes) || (nPoints < 2)) return BoxDist.fx = 1.0;
		ft1 = -HUGE_VAL;	ft2 = HUGE_VAL;		BoxDist.fx= HUGE_VAL;
		for(i = 0; i < nPoints; i++) {
			if(Boxes[i]) {
				ft2 = Boxes[i]->GetSize(SIZE_XPOS);
				d = fabs(ft2-ft1);
				if(d != 0.0 && d < BoxDist.fx) BoxDist.fx = d;
				}
			ft1 = ft2;
			}
		return BoxDist.fx = BoxDist.fx > 0.0001 && BoxDist.fx != HUGE_VAL  ? BoxDist.fx : 1.0;
	case SIZE_BOXMINY:
		if(BoxDist.fy >= 0.0001) return BoxDist.fy;
		if((!Boxes) || (nPoints < 2)) return BoxDist.fy = 1.0;
		ft1 = -HUGE_VAL;	ft2 = HUGE_VAL;		BoxDist.fy= HUGE_VAL;
		for(i = 0; i < nPoints; i++) {
			if(Boxes[i]) {
				ft2 = Boxes[i]->GetSize(SIZE_YPOS);
				d = fabs(ft2-ft1);
				if(d != 0.0 && d < BoxDist.fy) BoxDist.fy = d;
				}
			ft1 = ft2;
			}
		return BoxDist.fy = BoxDist.fy > 0.0001 && BoxDist.fy != HUGE_VAL  ? BoxDist.fy : 1.0;
	default:
		return Plot::GetSize(select);
		}
}

bool
BoxPlot::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;
	case SIZE_WHISKER:		case SIZE_WHISKER_LINE:
		if(Whiskers) for(i = 0; i < nPoints; i++) 
			if(Whiskers[i]) Whiskers[i]->SetSize(select, value);
		return true;
	case SIZE_BOX:			case SIZE_BOX_LINE:
		if(Boxes) for(i = 0; i < nPoints; i++) 
			if(Boxes[i]) Boxes[i]->SetSize(select, value);
		return true;
	case SIZE_LB_XDIST:		case SIZE_LB_YDIST:
		if(Labels) for(i = 0; i < nPoints; i++)
			if(Labels[i]) Labels[i]->SetSize(select, value);
		return true;
	}
	return false;
}

bool
BoxPlot::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;
	case COL_WHISKER:
		if(Whiskers) for(i = 0; i < nPoints; i++)
			if(Whiskers[i]) Whiskers[i]->SetColor(select, col);
		return true;
	case COL_BOX_LINE:
		if(Boxes) for(i = 0; i < nPoints; i++)
			if(Boxes[i]) Boxes[i]->SetColor(select, col);
		return true;
	default:
		return false;
		}
}

void
BoxPlot::DoPlot(anyOutput *o)
{
	if(!parent || !o) return;
	parent->Command(CMD_REG_AXISPLOT, (void*)this, o);
	if(use_xaxis || use_yaxis) ApplyAxes(o);
	ForEach(FE_PLOT, 0L, o);
	dirty = false;
	if(use_xaxis || use_yaxis)parent->Command(CMD_AXIS, 0L, o);
}

bool
BoxPlot::Command(int cmd, void *tmpl, anyOutput *o)
{
	int i;

	switch (cmd) {
	case CMD_MOUSE_EVENT:
		if(hidden) return false;
		if(!CurrGO && ((MouseEvent*)tmpl)->Action == MOUSE_LBUP) return ForEach(cmd, tmpl, o);
		return false;
	case CMD_LEGEND:
		if(((GraphObj*)tmpl)->Id != GO_LEGEND) return false;
		if(Boxes) for (i = 0; i < nPoints; i++)	if(Boxes[i]) Boxes[i]->Command(cmd, tmpl, o);
		if(Symbols) {
			if(TheLine && TheLine->Id == GO_DATALINE) {
				for (i = 0; i < nPoints && i < 100; i++)
					if(Symbols[i]) ((Legend*)tmpl)->HasSym(&TheLine->LineDef, Symbols[i]);
				}
			else {
				for (i = 0; i < nPoints && i < 100; i++)
					if(Symbols[i]) ((Legend*)tmpl)->HasSym(0L, Symbols[i]);
				}
			if(TheLine && TheLine->Id == GO_DATAPOLYGON) TheLine->Command(cmd, tmpl, o);
			}
		else if(TheLine) TheLine->Command(cmd, tmpl, o);
		break;
	case CMD_SET_DATAOBJ:
		Id = GO_BOXPLOT;		data = (DataObj *)tmpl;		dirty = true;
		if(type && xRange && yRange && data) {		//Stat. - Plot ?
			CreateData();
			return ForEach(CMD_SET_DATAOBJ, curr_data, o);
			}
		return ForEach(cmd, tmpl, o);
	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;
		ForEach(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_UPDATE:
		if(Boxes) SavVarObs((GraphObj **)Boxes, nPoints, UNDO_CONTINUE);
		if(Whiskers) SavVarObs((GraphObj **)Whiskers, nPoints, UNDO_CONTINUE);
		if(Symbols) SavVarObs((GraphObj **)Symbols, nPoints, UNDO_CONTINUE);
		if(Labels) SavVarObs((GraphObj **)Labels, nPoints, UNDO_CONTINUE); 
		if(type && xRange && yRange) {		//Stat. - Plot ?
			CreateData();
			ForEach(CMD_SET_DATAOBJ, curr_data, o);
			}
		ForEach(cmd, tmpl, o);
		return dirty = true;
	case CMD_USEAXIS:
		UseAxis(*((int*)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_SETTEXTDEF:
		if(Labels) for(i = 0; i < nPoints; i++)
			if(Labels[i]) Labels[i]->Command(cmd, tmpl, o);
		return true;
	case CMD_DELOBJ:
		if(ForEach(FE_DELOBJ, tmpl, o)) {
			parent->Command(CMD_REDRAW, 0L, o);
			return true;
			}
		return false;
	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_SAVE_SYMBOLS:
		return SavVarObs((GraphObj **)Symbols, nPoints, 0L);
	case CMD_SAVE_BARS:
		return SavVarObs((GraphObj **)Boxes, nPoints, 0L);
	case CMD_SAVE_BARS_CONT:
		return SavVarObs((GraphObj **)Boxes, nPoints, UNDO_CONTINUE);
	case CMD_SAVE_ERRS:
		return SavVarObs((GraphObj **)Whiskers, nPoints, 0L);
	case CMD_SAVE_LABELS:
		return SavVarObs((GraphObj **)Labels, nPoints, 0L);
	case CMD_BOX_TYPE:
		BoxDist.fy = BoxDist.fx = 0.0;
	case CMD_BOX_FILL:
		if(Boxes) for (i = 0; i < nPoints; i++)
			if(Boxes[i]) Boxes[i]->Command(cmd, tmpl, o);
		return true;
	case CMD_WHISKER_STYLE:
		if(Whiskers) for (i = 0; i < nPoints; i++)
			if(Whiskers[i]) Whiskers[i]->Command(cmd, tmpl, o);
		return true;
		}
	return false;
}

bool
BoxPlot::ForEach(int cmd, void *tmpl, anyOutput *o)
{
	GraphObj ***pobs[] = {(GraphObj***)&Boxes, (GraphObj***)&Whiskers, 
		(GraphObj***)&Symbols, (GraphObj***)&Labels};
	GraphObj **p;
	int i, j;
	bool bRet;

	switch(cmd) {
	case FE_DELOBJ:
		if(!o || !parent || !tmpl) return false;
		for(i = 0; i < 4; i++) {
			if(DeleteGOL(pobs[i], nPoints, (GraphObj*) tmpl, o)) return true;
			}
		if(TheLine && tmpl == (void *) TheLine) {
			Undo.DeleteGO((GraphObj**)(&TheLine), 0L, o);
			return true;
			}
		break;
	case FE_PLOT:
		if(TheLine) TheLine->DoPlot(o);
		for(i = 0; i < 4; i++){
			if(p= *pobs[i]) for(j = 0; j < nPoints; j++) {
				if(p[j]) p[j]->DoPlot(o);
				}
			}
		return true;
	case CMD_MOUSE_EVENT:				//invers to plot order
		for(i = 3; i >= 0; i--){
			if(p= *pobs[i]) for(j = nPoints-1; j >= 0; j--) {
				if(p[j]) {
					bRet = p[j]->Command(cmd, tmpl, o);
					if(bRet && cmd == CMD_MOUSE_EVENT) return true;
					}
				}
			}
		if(TheLine) return TheLine->Command(cmd, tmpl, o);
		return false;
	default:							//pass command to all objects
		for(i = 0; i < 4; i++){
			if(p= *pobs[i]) for(j = 0; j < nPoints; j++) {
				if(p[j]) {
					bRet = p[j]->Command(cmd, tmpl, o);
					}
				}
			}
		if(TheLine) return TheLine->Command(cmd, tmpl, o);
		return false;
		}
	return false;
}

void
BoxPlot::CreateData()
{
	int i, j, k, l, m, n, *ny;
	double x, y, ss, d, lo, hi, **ay, *ax, *tay, *q1, *q2, *q3;
	lfPOINT *xy;
	AccRange *rX, *rY;

	if(curr_data) delete curr_data;			curr_data = 0L;
	if(!data || !xRange || !yRange || !xRange[0] || !yRange[0]) return;
	if(!(rX = new AccRange(xRange)) || !(rY = new AccRange(yRange))) return;
	m = rX->CountItems();	n = 0;
	if(m < 2 || !(xy = (lfPOINT*) malloc(m * sizeof(lfPOINT)))) {
		delete rX;	delete rY;
		return;
		}
	ny = (int*) calloc(m, sizeof(int));
	ay = (double**) calloc(m, sizeof(double*));
	ax = (double*) calloc(m, sizeof(double));
	tay = (double*)malloc(m * sizeof(double));
	if(!ny || !ay || !ax || !tay) {
		if(ny) free(ny);	if(ay) free(ay);
		if(ax) free(ax);	if(tay) free(tay);
		delete rX;	delete rY;
		return;
		}
	rX->GetFirst(&i, &j);	rY->GetFirst(&k, &l);
	rX->GetNext(&i, &j);	rY->GetNext(&k, &l);	n=0;
	do {
		if(data->GetValue(j, i, &x) && data->GetValue(l, k, &y)){
			xy[n].fx = x;		xy[n].fy = y;
			n++;
			}
		}while(rX->GetNext(&i, &j) && rY->GetNext(&k, &l));
	delete rX;			delete rY;
	if(!n) {
		if(ny) free(ny);	if(ay) free(ay);
		if(ax) free(ax);	if(tay) free(tay);
		return;
		}
	SortFpArray(n, xy);
	for(i = j = 0; i < (n-1); i++, j++) {
		ax[j] = xy[i].fx;		tay[0] = xy[i].fy;
		ny[j] = 1;
		for(k = 1; xy[i+1].fx == xy[i].fx; k++) {
			tay[k] = xy[i+1].fy;
			i++;		ny[j]++;
			}
		ay[j] = (double*)memdup(tay, k * sizeof(double), 0);
		}
	if(xy[i].fx > xy[i-1].fx) {
		ax[j] = xy[i].fx;		tay[0] = xy[i].fy;
		ny[j] = 1;
		ay[j++] = (double*)memdup(tay, sizeof(double), 0);
		}
	if((type & 0x0004) == 0x0004 || (type & 0x0030) == 0x0030 || (type & 0x0300) == 0x0300) {
		//medians and/or percentiles required
		q1 = (double *)malloc(j * sizeof(double));
		q2 = (double *)malloc(j * sizeof(double));
		q3 = (double *)malloc(j * sizeof(double));
		if(q1 && q2 && q3) {
			for(i = 0; i < j; i++) {
				if(ny[i] > 1) d_quartile(ny[i], ay[i], q1+i, q2+i, q3+i);
				else q1[i] = q2[i] = q3[i] = *ay[i];
				}
			}
		else type = 0;
		}
	else q1 = q2 = q3 = 0L;
	if(type && (curr_data = new DataObj()) && curr_data->Init(j, 8)) {
		for(i = 0; i < j; i++) curr_data->SetValue(i,0,ax[i]);	// set x-values
		for(i = 0; i < j; i++) {								// set means
			if(ny[i] > 1) switch(type & 0x000f) {
				case 0x0001:	default:
					curr_data->SetValue(i, 1, y=d_amean(ny[i], ay[i]));
					break;
				case 0x0002:
					curr_data->SetValue(i, 1, y=d_gmean(ny[i], ay[i]));
					break;
				case 0x0003:
					curr_data->SetValue(i, 1, y=d_hmean(ny[i], ay[i]));
					break;
				case 0x0004:
					curr_data->SetValue(i, 1, y=q2[i]);
					break;
				}
			else curr_data->SetValue(i, 1, y= *ay[i]);
			curr_data->SetValue(i, 6, y);						//label's y
			}
		if((type & 0x00f0) == 0x0010 || (type & 0x00f0) == 0x0020 || (type & 0x00f0) == 0x0050
			|| (type & 0x0f0f) == 0x0201 || (type & 0x0f0f) == 0x0501) for(i = 0; i < j; i++) {
			// set SD, SE, Conf. Intervall
			if(ny[i] > 1) {
				y = d_amean(ny[i], ay[i]);
				for(k = 0, ss = 0.0; k < (ny[i]); k++) {
					ss += ((d=ay[i][k]-y)*d);
					ny[i] = ny[i];
					}
				ss = sqrt(ss/(double)(ny[i]-1));
				}
			else {
				y = *ay[i];		ss = 0.0;
				}
			//Box info is in cols 2 & 3
			if((type & 0x00f0) == 0x0010) {
				curr_data->SetValue(i, 2, y - ss);	curr_data->SetValue(i, 3, y + ss);
				}
			else if((type & 0x00f0) == 0x0020) {
				curr_data->SetValue(i, 2, y - ss/sqrt(ny[i]));	
				curr_data->SetValue(i, 3, y + ss/sqrt(ny[i]));
				}
			else if((type & 0x00f0) == 0x0050) {
				d = ny[i] > 1 ? distinv(t_dist, ny[i]-1, 1, 1.0-(ci_box/100.0), 2.0) : 0;
				curr_data->SetValue(i, 2, y - d*ss/sqrt(ny[i]));	
				curr_data->SetValue(i, 3, y + d*ss/sqrt(ny[i]));
				}
			//Whisker info is in cols 4 & 5
			if((type & 0x0f0f) == 0x0101) {
				curr_data->SetValue(i, 4, y - ss);	curr_data->SetValue(i, 5, y + ss);
				}
			else if((type & 0x0f0f) == 0x0201) {
				curr_data->SetValue(i, 4, y - ss/sqrt(ny[i]));
				curr_data->SetValue(i, 5, y + ss/sqrt(ny[i]));
				}
			else if((type & 0x0f0f) == 0x0501) {
				d = ny[i] > 1 ? distinv(t_dist, ny[i]-1, 1, 1.0-(ci_err/100.0), 2.0) : 0;
				curr_data->SetValue(i, 4, y - d*ss/sqrt(ny[i]));
				curr_data->SetValue(i, 5, y + d*ss/sqrt(ny[i]));
				}
			}
		if((type & 0x00f0) == 0x0040 || (type & 0x0f00) == 0x0400) for(i = 0; i < j; i++) {
			// set min and max
			lo = hi = *ay[i];
 			if(ny[i] > 1) {
				for(k = 1; k < ny[i]; k++) {
					if(ay[i][k] < lo) lo = ay[i][k];
					if(ay[i][k] > hi) hi = ay[i][k];
					}
				}
			if((type & 0x00f0) == 0x0040) {
				curr_data->SetValue(i, 2, lo);	curr_data->SetValue(i, 3, hi);
				}
			if((type & 0x0f00) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -