void
TestData
	(
	Test2DPlotDirector* dir
	)
{
JIndex i;

	JX2DPlotWidget* plot = dir->GetPlotWidget();
	plot->ShowLegend();

	JArray<JFloat> x(100),y(100), xPErr(101),xMErr(101), yPErr(101), yMErr(101);
	JKLRand r;

	JFloat delta = kJPi/50.0;
	for (i=0; i<=100; i++)
		{
		x.AppendElement(i*delta);
		y.AppendElement(sin(i*delta));

		xPErr.AppendElement(r.UniformDouble(0.0, 0.1));
		xMErr.AppendElement(r.UniformDouble(0.0, 0.1));
		yPErr.AppendElement(r.UniformDouble(0.0, 0.1));
		yMErr.AppendElement(r.UniformDouble(0.0, 0.1));
		}

	J2DPlotData* data;
	JBoolean ok = J2DPlotData::Create(&data, x, y, kJFalse);
	assert( ok );
	ok = data->SetXErrors(xPErr, xMErr);
	assert( ok );
	ok = data->SetYErrors(yPErr, yMErr);
	assert( ok );

	plot->AddCurve(data, kJTrue, "sin(x)", kJTrue, kJTrue);

	x.RemoveAll();
	y.RemoveAll();

	delta = kJPi/5000.0;
	for (i=0; i<=10000; i++)
		{
		x.AppendElement(i*delta);
		y.AppendElement(cos(i*delta));
		}

	plot->AddCurve(x, y, kJFalse, "cos(x)", &i, kJTrue, kJFalse);

	plot->SetTitle("Error bars");
}
JPlotFitProxy::JPlotFitProxy
	(
	JPlotFitFunction*	fit,
	J2DPlotWidget* 		plot, 
	JPlotDataBase* 		fitData
	)
	:
	JPlotFitFunction(plot, fitData, 0, 0),
	itsErrors(NULL),
	itsHasGOF(fit->HasParameterErrors()),
	itsGOFName(fit->HasGoodnessOfFit()),
	itsFnString(fit->GetFitFunctionString())
{
	if (itsHasGOF)
		{
		fit->GetGoodnessOfFitName(&itsGOFName);
		fit->GetGoodnessOfFit(&itsGOF);
		}
	itsParms	= new GVarList();
	assert(itsParms != NULL);
	itsParms->AddVariable("x", 0);
	const JSize count	= fit->GetParameterCount();
	SetParameterCount(count);
	for (JIndex i = 1; i <= count; i++)
		{
		JString name;
		JBoolean ok	= fit->GetParameterName(i, &name);
		assert(ok);
		JFloat value;
		ok	= fit->GetParameter(i, &value);
		assert(ok);
		itsParms->AddVariable(name, value);
		}

	if (fit->HasParameterErrors())
		{
		SetHasParameterErrors(kJTrue);
		itsErrors	= new JArray<JFloat>;
		assert(itsErrors != NULL);
		for (JIndex i = 1; i <= count; i++)
			{
			JFloat value;
			JBoolean ok	= fit->GetParameterError(i, &value);
			assert(ok);
			itsErrors->AppendElement(value);
			}
		}

	J2DPlotData* diff	= fit->GetDiffData();
	J2DPlotData* data;
	if (J2DPlotData::Create(&data, diff->GetXData(), diff->GetYData(), kJFalse))
		{
		const JArray<JFloat>* xerrors;
		if (diff->GetXPErrorData(&xerrors))
			{
			data->SetXErrors(*xerrors);
			}
		const JArray<JFloat>* yerrors;
		if (diff->GetYPErrorData(&yerrors))
			{
			data->SetYErrors(*yerrors);
			}
		SetDiffData(data);
		}
	JFloat xMin;
	JFloat xMax;
	fit->GetXRange(&xMin, &xMax);
	SetXRange(xMin, xMax);
	itsFn	= NULL;
	JParseFunction(itsFnString, itsParms, &itsFn);
	SetHasGoodnessOfFit(itsHasGOF);
}