public void DoPlot() {
	needsDoPlot = true;

	// compute grid dimensions for all the panels
	Dimension d = panels[0].getSize();
	if (d.width <= 0 || d.height <= 0) return;
	int grid = panels[0].Grid();
	nxgrids = d.width/grid;
	if (nxgrids < 1) nxgrids = 1;
	xoff = (d.width - nxgrids*grid)/2;

	nygrids = d.height/PlotCanvas.grid;
	// keep waveform from getting crowded vertically
	if (d.height - (nygrids * grid) < grid)
	    nygrids -= 1;
	if (nygrids < 1) nygrids = 1;
	yoff = (d.height - nygrids*grid)/2;

	// compute size of each horizontal division
	double range = xmax - xmin;
	hdiv = PlotCanvas.ChooseScale(range/nxgrids,hzoom);

	// see if we should set xorigin
	if (xorigin == Double.NEGATIVE_INFINITY)
	    xorigin = Quantize(xmin,hdiv);

	// set up scrollbar
	int max = 10000;
	double sbunit = ((double)max)/range;
	int val = (int)(sbunit*(xorigin - xmin));
	int linc = (int)(sbunit*hdiv);
	int vis = (int)(sbunit*hdiv*nxgrids);
	hbar.removeAdjustmentListener(this);
	hbar.setValues(val,vis,0,max);
	hbar.setUnitIncrement(linc < 1 ? 1 : linc);
	hbar.setBlockIncrement(vis < 1 ? 1 : vis);
	hbar.addAdjustmentListener(this);

	for (int i = 0; i < npanels; i += 1) panels[i].Plot();
	needsDoPlot = false;
    }