diff --git a/Graphics/Graph2D.cpp b/Graphics/Graph2D.cpp
index e81edfee3f59d8c0c0c783c0fc4b1852adda3f48..6380e1af89747d163915a1eee688a4c7aac8ec8e 100644
--- a/Graphics/Graph2D.cpp
+++ b/Graphics/Graph2D.cpp
@@ -1,4 +1,4 @@
-// $Id: Graph2D.cpp,v 1.60 2007-08-29 18:41:06 geuzaine Exp $
+// $Id: Graph2D.cpp,v 1.61 2007-08-31 09:18:16 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -22,10 +22,10 @@
 #include "GmshUI.h"
 #include "Draw.h"
 #include "PView.h"
+#include "gl2ps.h"
+#include "Context.h"
 
-void Draw_Graph2D()
-{
-}
+extern Context_T CTX;
 
 void Draw_Text2D()
 {
@@ -45,3 +45,378 @@ void Draw_Text2D()
     }
   }
 }
+
+static bool getGraphData(PView *p, std::vector<double> &x, double &xmin, 
+			 double &xmax, std::vector<std::vector<double> > &y, 
+			 double &ymin, double ymax) 
+{
+  PViewData *data = p->getData();
+  PViewOptions *opt = p->getOptions();
+
+  int numy = 0;
+  if(opt->Type == PViewOptions::Plot2DSpace){
+    numy = 1;
+  }
+  else if(opt->Type == PViewOptions::Plot2DTime){
+    numy = 0;
+    for(int i = 0; i < data->getNumElements(); i++)
+      if(data->getDimension(i) < 2) numy++;
+  }
+  
+  if(!numy) return false;
+  y.resize(numy);
+
+  for(int i = 0; i < data->getNumElements(); i++){
+    int dim = data->getDimension(i);
+    if(dim < 2){
+      int numNodes = data->getNumNodes(i);
+      int numComp = data->getNumComponents(i);
+      for(int ts = 0; ts < data->getNumTimeSteps(); ts++){
+	if(opt->Type == PViewOptions::Plot2DSpace) ts = opt->TimeStep;
+	for(int j = 0; j < numNodes; j++){
+	  double val[9], xyz[3];
+	  data->getNode(i, j, xyz[0], xyz[1], xyz[2]);
+	  for(int k = 0; k < numComp; k++)
+	    data->getValue(i, j, k, ts, val[k]);
+	  double vx = ComputeScalarRep(3, xyz);
+	  double vy = ComputeScalarRep(numComp, val);
+	  if(opt->Type == PViewOptions::Plot2DTime){
+	    x.push_back(ts);
+	    y[i].push_back(vy);
+	  }
+	  else if(opt->Type == PViewOptions::Plot2DSpace){
+	    x.push_back(vx);
+	    y[0].push_back(vy);
+	  }
+	}
+	if(opt->Type == PViewOptions::Plot2DSpace) break;
+      }
+    }
+  }
+
+  if(x.empty()) return false;
+
+  xmin = xmax = x[0];
+  ymin = ymax = y[0][0];
+  for(unsigned int i = 1; i < x.size(); i++){
+    xmin = std::min(xmin, x[i]);
+    xmax = std::max(xmax, x[i]);
+    for(unsigned int j = 0; j < y.size(); j++){
+      ymin = std::min(ymin, y[j][i]);
+      ymax = std::max(ymax, y[j][i]);
+    }
+  }
+
+  return true;
+}
+
+static void drawGraphAxes(PView *p, double xleft, double ytop, double width,
+			  double height, double xmin, double xmax)
+{
+  PViewData *data = p->getData();
+  PViewOptions *opt = p->getOptions();
+
+  if(!opt->Axes) return;
+
+  char label[1024];    
+  float font_h = gl_height() ? gl_height() : 1; // total font height
+  float font_a = font_h - gl_descent(); // height above ref. point
+
+  const double tic = 5.;
+
+  glPointSize(CTX.point_size);
+  gl2psPointSize(CTX.point_size * CTX.print.eps_point_size_factor);
+
+  glLineWidth(CTX.line_width);
+  gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
+
+  glColor4ubv((GLubyte *) & opt->color.axes);
+
+  // bare axes
+  glBegin(GL_LINE_STRIP);
+  glVertex2d(xleft, ytop);
+  glVertex2d(xleft, ytop - height);
+  glVertex2d(xleft + width, ytop - height);
+  if(opt->Axes > 1) {
+    glVertex2d(xleft + width, ytop);
+    glVertex2d(xleft, ytop);
+  }
+  glEnd();
+
+  // y label
+  if(opt->Type == PViewOptions::Plot2DSpace && opt->ShowTime > 2){
+    char tmp[256];
+    sprintf(tmp, opt->Format, data->getTime(opt->TimeStep));
+    sprintf(label, "%s (%s)", p->getName().c_str(), tmp);
+  }
+  else if(opt->Type == PViewOptions::Plot2DSpace && opt->ShowTime > 0){
+    sprintf(label, "%s (%d)", p->getName().c_str(), opt->TimeStep);
+  }
+  else
+    sprintf(label, "%s", p->getName().c_str());
+  glRasterPos2d(xleft, ytop + font_h + tic);
+  Draw_String_Center(label);
+  
+  // x label
+  sprintf(label, "%s", opt->AxesLabel[0]);
+  glRasterPos2d(xleft + width / 2, ytop - height - 2 * font_h - 2 * tic);
+  Draw_String_Center(label);
+
+  // y tics and horizontal grid
+  if(opt->NbIso > 0){
+    int nb = opt->NbIso;
+    if(opt->ShowScale && (opt->NbIso * font_h > height))
+      nb = (int)floor(height / font_h);
+    double dy = height / (double)nb;
+    double dv = (opt->TmpMax - opt->TmpMin) / (double)nb;
+    for(int i = 0; i < nb + 1; i++){
+      if(opt->Axes > 0){
+	glBegin(GL_LINES);
+	glVertex2d(xleft, ytop - i * dy);
+	glVertex2d(xleft + tic, ytop - i * dy);
+	if(opt->Axes > 1) {
+	  glVertex2d(xleft + width - tic, ytop - i * dy);
+	  glVertex2d(xleft + width, ytop - i * dy);
+	}
+	glEnd();
+	if(opt->Axes > 2 && i != 0 && i != nb) {
+	  glEnable(GL_LINE_STIPPLE);
+	  glLineStipple(1, 0x1111);
+	  gl2psEnable(GL2PS_LINE_STIPPLE);
+	  gl2psLineWidth(1. * CTX.print.eps_line_width_factor);
+	  glBegin(GL_LINES);
+	  glVertex2d(xleft, ytop - i * dy);
+	  glVertex2d(xleft + width, ytop - i * dy);
+	  glEnd();
+	  glDisable(GL_LINE_STIPPLE);
+	  gl2psDisable(GL2PS_LINE_STIPPLE);
+	  gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
+	}
+      }
+      if(opt->ShowScale) {
+	sprintf(label, opt->Format, (i == nb) ? opt->TmpMin : (opt->TmpMax - i * dv));
+	glRasterPos2d(xleft - 2 * tic, ytop - i * dy - font_a / 3.);
+	Draw_String_Right(label);
+      }
+    }
+  }
+
+  // x tics and vertical grid
+  if(opt->AxesTics[0] > 0){
+    int nb = opt->AxesTics[0];
+    if(opt->Axes) {
+      sprintf(label, opt->AxesFormat[0], - M_PI * 1.e-4);
+      if((nb - 1) * gl_width(label) > width)
+	nb = (int)(width / gl_width(label)) + 1;
+    }
+    if(nb == 1) nb++;
+    
+    double dx = width / (double)(nb - 1);
+    double ybot = ytop - height;
+    
+    for(int i = 0; i < nb; i++) {
+      if(opt->Axes) {
+	glBegin(GL_LINES);
+	glVertex2d(xleft + i * dx, ybot);
+	glVertex2d(xleft + i * dx, ybot + tic);
+	if(opt->Axes > 1) {
+	  glVertex2d(xleft + i * dx, ytop);
+	  glVertex2d(xleft + i * dx, ytop - tic);
+	}
+	glEnd();
+	if(opt->Axes > 2 && i != 0 && i != nb - 1) {
+	  glEnable(GL_LINE_STIPPLE);
+	  glLineStipple(1, 0x1111);
+	  gl2psEnable(GL2PS_LINE_STIPPLE);
+	  gl2psLineWidth(1. * CTX.print.eps_line_width_factor);
+	  glBegin(GL_LINES);
+	  glVertex2d(xleft + i * dx, ytop);
+	  glVertex2d(xleft + i * dx, ybot);
+	  glEnd();
+	  glDisable(GL_LINE_STIPPLE);
+	  gl2psDisable(GL2PS_LINE_STIPPLE);
+	  gl2psLineWidth(CTX.line_width * CTX.print.eps_line_width_factor);
+	}
+	
+	if(nb == 1)
+	  sprintf(label, opt->AxesFormat[0], xmin);
+	else
+	  sprintf(label, opt->AxesFormat[0],
+		  xmin + i * (xmax - xmin) / (double)(nb - 1));
+	glRasterPos2d(xleft + i * dx, ybot - font_h - tic);
+	Draw_String_Center(label);
+      }
+    }
+  }
+  
+}
+
+static void addGraphPoint(PView *p, double xleft, double ytop, double width, 
+			  double height, double x, double y, double xmin, 
+			  double xmax, double ymin, double ymax)
+{
+  PViewOptions *opt = p->getOptions();
+
+  double px = xleft;
+  if(xmin != xmax) px += (x - xmin) / (xmax - xmin) * width;
+
+  if(opt->SaturateValues) {
+    if(y > ymax)
+      y = ymax;
+    else if(y < ymin)
+      y = ymin;
+  }
+  
+  double ybot = ytop - height;
+  double py = ybot;
+  if(ymax != ymin) py += (y - ymin) / (ymax - ymin) * height;
+
+  if(y >= ymin && y <= ymax) {
+    unsigned int col = opt->getColor(y, ymin, ymax, true);
+    glColor4ubv((GLubyte *) &col);
+    if(opt->IntervalsType == PViewOptions::Numeric) {
+      glRasterPos2d(px + 3, py + 3);
+      char label[256];
+      sprintf(label, opt->Format, y);
+      Draw_String(label);
+    }
+    else
+      glVertex2d(px, py);
+  }
+}
+
+static void drawGraphCurves(PView *p, double xleft, double ytop, double width,
+			    double height, std::vector<double> &x, double xmin,
+			    double xmax, std::vector<std::vector<double> > &y)
+{
+  PViewData *data = p->getData();
+  PViewOptions *opt = p->getOptions();
+
+  glPointSize(opt->PointSize);
+  gl2psPointSize(opt->PointSize * CTX.print.eps_point_size_factor);
+
+  glLineWidth(opt->LineWidth);
+  gl2psLineWidth(opt->LineWidth * CTX.print.eps_line_width_factor);
+
+  if(opt->IntervalsType == PViewOptions::Iso ||
+     opt->IntervalsType == PViewOptions::Discrete ||
+     opt->IntervalsType == PViewOptions::Numeric){
+    glBegin(GL_POINTS);
+    for(unsigned int i = 0; i < y.size(); i++)
+      for(unsigned int j = 0; j < x.size(); j++)
+	addGraphPoint(p, xleft, ytop, width, height, x[j], y[i][j], 
+		      xmin, xmax, opt->TmpMin, opt->TmpMax);
+    glEnd();    
+  }
+
+  if(opt->IntervalsType == PViewOptions::Discrete ||
+     opt->IntervalsType == PViewOptions::Continuous){
+    for(unsigned int i = 0; i < y.size(); i ++) {
+      if(opt->UseStipple){
+	glEnable(GL_LINE_STIPPLE);
+	glLineStipple(opt->Stipple[i % 10][0], opt->Stipple[i % 10][1]);
+	gl2psEnable(GL2PS_LINE_STIPPLE);
+      }
+      glBegin(GL_LINE_STRIP);
+      for(unsigned int j = 0; j < x.size(); j++)
+	addGraphPoint(p, xleft, ytop, width, height, x[j], y[i][j], 
+		      xmin, xmax, opt->TmpMin, opt->TmpMax);
+      glEnd();
+      if(opt->UseStipple){
+	glDisable(GL_LINE_STIPPLE);
+	gl2psDisable(GL2PS_LINE_STIPPLE);
+      }
+    }
+  }
+}
+
+static void drawGraph(PView *p, double xleft, double ytop, double width, double height)
+{
+  PViewData *data = p->getData();
+  PViewOptions *opt = p->getOptions();
+  
+  if(opt->RangeType == PViewOptions::Custom){
+    opt->TmpMin = opt->CustomMin;
+    opt->TmpMax = opt->CustomMax;
+  }
+  else if(opt->RangeType == PViewOptions::PerTimeStep){
+    opt->TmpMin = data->getMin(opt->TimeStep);
+    opt->TmpMax = data->getMax(opt->TimeStep);
+  }
+  else{
+    opt->TmpMin = data->getMin();
+    opt->TmpMax = data->getMax();
+  }
+  
+  std::vector<double> x;
+  std::vector<std::vector<double> > y;
+  double xmin, xmax, ymin, ymax;
+  if(!getGraphData(p, x, xmin, xmax, y, ymin, ymax)) return;
+  drawGraphAxes(p, xleft, ytop, width, height, xmin, xmax);
+  drawGraphCurves(p, xleft, ytop, width, height, x, xmin, xmax, y);
+}
+
+void Draw_Graph2D()
+{
+  std::vector<PView*> graphs;
+  for(unsigned int i = 0; i < PView::list.size(); i++){
+    PViewData *data = PView::list[i]->getData();
+    PViewOptions *opt = PView::list[i]->getOptions();
+    if(!data->getDirty() && opt->Visible && opt->Type != PViewOptions::Plot3D)
+      graphs.push_back(PView::list[i]);
+  }
+  if(graphs.empty()) return;
+
+  double xsep = 0., ysep = 5 * gl_height();
+
+  gl_font(CTX.gl_font_enum, CTX.gl_fontsize);
+  char label[1024];
+  for(unsigned int i = 0; i < graphs.size(); i++) {
+    PViewOptions *opt = graphs[i]->getOptions();
+    sprintf(label, opt->Format, -M_PI * 1.e-4);
+    xsep = std::max(xsep, gl_width(label));
+  }
+  
+  for(unsigned int i = 0; i < graphs.size(); i++) {
+    PView *p = graphs[i];
+    PViewOptions *opt = graphs[i]->getOptions();
+    if(!opt->AutoPosition) {
+      double x = opt->Position[0], y = opt->Position[1];
+      int center = Fix2DCoordinates(&x, &y);
+      drawGraph(p, x - (center & 1 ? opt->Size[0]/2. : 0), 
+		y + (center & 2 ? opt->Size[1]/2. : 0), 
+		opt->Size[0], opt->Size[1]);
+    }
+    else{
+      double winw = CTX.viewport[2] - CTX.viewport[0];
+      double winh = CTX.viewport[3] - CTX.viewport[1];
+      if(graphs.size() == 1){
+	double fracw = 0.75, frach = 0.75;
+	double w = fracw * winw - xsep;
+	double h = frach * winh - ysep;
+	double x = CTX.viewport[0] + (1 - fracw) / 2. * winw;
+	double y = CTX.viewport[1] + (1 - frach) / 2. * winh;
+	drawGraph(p, x + 0.95 * xsep, CTX.viewport[3] - (y + 0.4 * ysep), w, h);
+      }
+      else if(graphs.size() == 2){
+	double fracw = 0.75, frach = 0.85;
+	double w = fracw * winw - xsep;
+	double h = frach * winh / 2. - ysep;
+	double x = CTX.viewport[0] + (1 - fracw) / 2. * winw;
+	double y = CTX.viewport[1] + (1 - frach) / 3. * winh;
+	if(i == 1) y += (h + ysep + (1 - frach) / 3. * winh);
+	drawGraph(p, x + 0.95 * xsep, CTX.viewport[3] - (y + 0.4 * ysep), w, h);
+      }
+      else{
+	double fracw = 0.85, frach = 0.85;
+	double w = fracw * winw / 2. - xsep;
+	double h = frach * winh / 2. - ysep;
+	double x = CTX.viewport[0] + (1 - fracw) / 3. * winw;
+	if(i == 1 || i == 3) x += (w + xsep + (1-fracw)/3. * winw);
+	double y = CTX.viewport[1] + (1 - frach) / 3. * winh;
+	if(i == 2 || i == 3) y += (h + ysep + (1 - frach) / 3. * winh);
+	drawGraph(p, x + 0.95 * xsep, CTX.viewport[3] - (y + 0.4 * ysep), w, h);
+      }
+    }
+  }
+}
diff --git a/Graphics/Post.cpp b/Graphics/Post.cpp
index b489352160dbbcdd7a331d4a0ffbd6bd936e1f43..11067ce10fcbba8f65400ff844a594b83a088eb7 100644
--- a/Graphics/Post.cpp
+++ b/Graphics/Post.cpp
@@ -1,4 +1,4 @@
-// $Id: Post.cpp,v 1.125 2007-08-28 23:12:49 geuzaine Exp $
+// $Id: Post.cpp,v 1.126 2007-08-31 09:18:16 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -60,25 +60,14 @@ SVector3 normal3(double xyz[NMAX][3], int i0=0, int i1=1, int i2=2)
   return n;
 }
 
-double normValue(int numComp, double val[9])
-{
-  if(numComp == 1)
-    return val[0];
-  else if(numComp == 3)
-    return sqrt(val[0] * val[0] + val[1] * val[1] + val[2] * val[2]);
-  else if(numComp == 9)
-    return ComputeVonMises(val);
-  return 0.;
-}
-
 SVector3 getPointNormal(PView *p, double v)
 {
   PViewOptions *opt = p->getOptions();
   SVector3 n(0., 0., 0.);
   if(opt->PointType > 0){
-    // if we draw spheres, we'll use the normalized value (between 0
-    // and 1) stored in the first component of the normals to
-    // change the radius of the sphere
+    // when we draw spheres, we use the normalized value (between 0
+    // and 1) stored in the first component of the normal to modulate
+    // the radius
     double d = opt->TmpMax - opt->TmpMin;
     n[0] = (v - opt->TmpMin) / (d ? d : 1.);
   }
@@ -92,9 +81,9 @@ void getLineNormal(PView *p, double x[2], double y[2], double z[2],
 
   if(opt->LineType > 0){
     if(v){
-      // if we draw tapered cylinders, we'll use the normalized values
+      // when we draw tapered cylinders, we use the normalized values
       // (between 0 and 1) stored in the first component of the
-      // normals to modulate the width of the cylinder
+      // normals to modulate the width
       double d = opt->TmpMax - opt->TmpMin;
       n[0][0] = (v[0] - opt->TmpMin) / (d ? d : 1.);
       n[1][0] = (v[1] - opt->TmpMin) / (d ? d : 1.);
@@ -231,9 +220,9 @@ void changeCoordinates(PView *p, int iele, int numNodes, int numComp,
   
   if(opt->Raise[0] || opt->Raise[1] || opt->Raise[2]){
     for(int i = 0; i < numNodes; i++){
-      double norm = normValue(numComp, val[i]);
+      double v = ComputeScalarRep(numComp, val[i]);
       for(int j = 0; j < 3; j++)
-	xyz[i][j] += opt->Raise[j] * norm;
+	xyz[i][j] += opt->Raise[j] * v;
     }
   }
 
@@ -767,7 +756,7 @@ void addVectorElement(PView *p, int iele, int numNodes, int numEdges,
 
   if(opt->VectorType == PViewOptions::Displacement){
     for(int i = 0; i < numNodes; i++)
-      val2[i][0] = normValue(numComp2, val2[i]);
+      val2[i][0] = ComputeScalarRep(numComp2, val2[i]);
 
     // add scalar element with correct min/max
     double min = opt->TmpMin, max = opt->TmpMax;
@@ -810,10 +799,9 @@ void addVectorElement(PView *p, int iele, int numNodes, int numEdges,
 
   if(opt->GlyphLocation == PViewOptions::Vertex){
     for(int i = 0; i < numNodes; i++){
-      double norm = normValue(3, val[i]);
-      double norm2 = normValue(numComp2, val2[i]);
-      if(norm2 >= opt->ExternalMin && norm2 <= opt->ExternalMax){
-	unsigned int color = opt->getColor(norm2, opt->ExternalMin, opt->ExternalMax);
+      double v2 = ComputeScalarRep(numComp2, val2[i]);
+      if(v2 >= opt->ExternalMin && v2 <= opt->ExternalMax){
+	unsigned int color = opt->getColor(v2, opt->ExternalMin, opt->ExternalMax);
 	unsigned int col[2] = {color, color};
 	double dxyz[3][2];
 	for(int j = 0; j < 3; j++){
@@ -839,15 +827,12 @@ void addVectorElement(PView *p, int iele, int numNodes, int numEdges,
     for(int j = 0; j < 3; j++) d[j] /= (double)numNodes;
     for(int j = 0; j < numComp2; j++) d2[j] /= (double)numNodes;
 
-    double norm = normValue(3, d);
-    double norm2 = normValue(numComp2, d2);
-
-    // need epsilon since we compare computed results (the average)
+    // need tolerance since we compare computed results (the average)
     // instead of the raw data used to compute bounds
-    const double eps = 1.e-15;
-    if(norm2 >= opt->ExternalMin * (1. - eps) &&
-       norm2 <= opt->ExternalMax * (1. + eps)){
-      unsigned int color = opt->getColor(norm2, opt->ExternalMin, opt->ExternalMax);
+    double v2 = ComputeScalarRep(numComp2, d2);
+    if(v2 >= opt->ExternalMin * (1. - 1.e-15) &&
+       v2 <= opt->ExternalMax * (1. + 1.e-15)){
+      unsigned int color = opt->getColor(v2, opt->ExternalMin, opt->ExternalMax);
       unsigned int col[2] = {color, color};
       double dxyz[3][2];
       for(int i = 0; i < 3; i++){
@@ -912,12 +897,15 @@ void addElementsInArrays(PView *p, bool preprocessNormalsOnly=false)
 
     if(opt->ShowElement) 
       addOutlineElement(p, numEdges, xyz, preprocessNormalsOnly);
-    if(numComp == 1 && opt->DrawScalars)
-      addScalarElement(p, numEdges, xyz, val, preprocessNormalsOnly);
-    else if(numComp == 3 && opt->DrawVectors)
-      addVectorElement(p, i, numNodes, numEdges, xyz, val, preprocessNormalsOnly);
-    else if(numComp == 9 && opt->DrawTensors)
-      addTensorElement(p, numNodes, numEdges, xyz, val, preprocessNormalsOnly);
+
+    if(opt->IntervalsType != PViewOptions::Numeric){
+      if(numComp == 1 && opt->DrawScalars)
+	addScalarElement(p, numEdges, xyz, val, preprocessNormalsOnly);
+      else if(numComp == 3 && opt->DrawVectors)
+	addVectorElement(p, i, numNodes, numEdges, xyz, val, preprocessNormalsOnly);
+      else if(numComp == 9 && opt->DrawTensors)
+	addTensorElement(p, numNodes, numEdges, xyz, val, preprocessNormalsOnly);
+    }
   }
 }
 
@@ -994,10 +982,16 @@ void drawVectorArray(PView *p, VertexArray *va)
     if(norm && opt->TmpMax){
       double f = CTX.pixel_equiv_x / CTX.s[0] * opt->ArrowSize / 
 	(opt->ArrowSizeProportional ? opt->TmpMax : norm);
+      double dx = v[0] * f, dy = v[1] * f, dz = v[2] * f;
+      double x = p[0], y = p[1], z = p[2];
+      if(opt->CenterGlyphs){
+	x -= 0.5 * dx;
+	y -= 0.5 * dy;
+	z -= 0.5 * dz;
+      }
       Draw_Vector(opt->VectorType, opt->IntervalsType != PViewOptions::Iso,
 		  opt->ArrowRelHeadRadius, opt->ArrowRelStemLength,
-		  opt->ArrowRelStemRadius, p[0], p[1], p[2],
-		  v[0] * f, v[1] * f, v[2] * f, opt->Light);
+		  opt->ArrowRelStemRadius, x, y, z, dx, dy, dz, opt->Light);
     }
   }
 }
@@ -1035,22 +1029,30 @@ void drawNumberGlyphs(PView *p, int numNodes, int numComp,
     }
     pc /= (double)numNodes;
     for(int j = 0; j < numComp; j++) d[j] /= (double)numNodes;
-    double norm = normValue(numComp, d);
-    if(norm >= vmin && norm <= vmax){
-      unsigned int col = opt->getColor(norm, vmin, vmax);
+    double v = ComputeScalarRep(numComp, d);
+    if(v >= vmin && v <= vmax){
+      unsigned int col = opt->getColor(v, vmin, vmax);
       glColor4ubv((GLubyte *) & col);
       glRasterPos3d(pc.x(), pc.y(), pc.z());
-      Draw_String((char*)stringValue(numComp, d, norm, opt->Format).c_str());
+      char *txt = (char*)stringValue(numComp, d, v, opt->Format).c_str();
+      if(opt->CenterGlyphs)
+	Draw_String_Center(txt);
+      else
+	Draw_String(txt);
     }
   }
   else if(opt->GlyphLocation == PViewOptions::Vertex){
     for(int i = 0; i < numNodes; i++){
-      double norm = normValue(numComp, val[i]);
-      if(norm >= vmin && norm <= vmax){
-	unsigned int col = opt->getColor(norm, vmin, vmax);
+      double v = ComputeScalarRep(numComp, val[i]);
+      if(v >= vmin && v <= vmax){
+	unsigned int col = opt->getColor(v, vmin, vmax);
 	glColor4ubv((GLubyte *) & col);
 	glRasterPos3d(xyz[i][0], xyz[i][1], xyz[i][2]);
-	Draw_String((char*)stringValue(numComp, val[i], norm, opt->Format).c_str());
+	char *txt = (char*)stringValue(numComp, val[i], v, opt->Format).c_str();
+	if(opt->CenterGlyphs)
+	  Draw_String_Center(txt);
+	else
+	  Draw_String(txt);
       }
     }
   }
@@ -1198,7 +1200,9 @@ class initPView {
     PViewData *data = p->getData();
     PViewOptions *opt = p->getOptions();
 
-    if(!p->getChanged() || data->getDirty() || !opt->Visible) return;
+    if(data->getDirty() || !p->getChanged()) return;
+
+    if(!opt->Visible || opt->Type != PViewOptions::Plot3D) return;
 
     if(p->va_points) delete p->va_points;
     p->va_points = new VertexArray(1, estimateNumPoints(p));
@@ -1256,7 +1260,7 @@ class drawPView {
     PViewData *data = p->getData();
     PViewOptions *opt = p->getOptions();
     
-    if(!opt->Visible) return;
+    if(!opt->Visible || opt->Type != PViewOptions::Plot3D) return;
     
     glPointSize(opt->PointSize);
     gl2psPointSize(opt->PointSize * CTX.print.eps_point_size_factor);
diff --git a/Numeric/Numeric.cpp b/Numeric/Numeric.cpp
index ef604fe3b88814124b495b4a1c80c9b98219fb6f..4445f1fb40b03f16cd5c532ccf148340c4df2d4f 100644
--- a/Numeric/Numeric.cpp
+++ b/Numeric/Numeric.cpp
@@ -1,4 +1,4 @@
-// $Id: Numeric.cpp,v 1.32 2007-08-25 10:58:34 geuzaine Exp $
+// $Id: Numeric.cpp,v 1.33 2007-08-31 09:18:16 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -495,6 +495,17 @@ double ComputeVonMises(double *V)
                      v31 * v31 + v32 * v32 + v33 * v33));
 }
 
+double ComputeScalarRep(int numComp, double *val)
+{
+  if(numComp == 1)
+    return val[0];
+  else if(numComp == 3)
+    return sqrt(val[0] * val[0] + val[1] * val[1] + val[2] * val[2]);
+  else if(numComp == 9)
+    return ComputeVonMises(val);
+  return 0.;
+}
+
 void eigenvalue(double mat[3][3], double v[3])
 {            
   // characteristic polynomial of T : find v root of
diff --git a/Numeric/Numeric.h b/Numeric/Numeric.h
index 66e147ab057585c1dba1b575cfc5e3ff57088fa2..f7fe97620396237136628ed16edf51d4d55bc268 100644
--- a/Numeric/Numeric.h
+++ b/Numeric/Numeric.h
@@ -91,6 +91,7 @@ double InterpolateIso(double *X, double *Y, double *Z,
 		      double *XI, double *YI ,double *ZI);
 void gradSimplex(double *x, double *y, double *z, double *v, double *grad);
 double ComputeVonMises(double *val);
+double ComputeScalarRep(int numComp, double *val);
 
 /* Numerical routines implemented using either Numerical Recipes or
    the GSL */
diff --git a/Post/PView.h b/Post/PView.h
index 64cb2810576318152ce7b1400403ec65cb93e103..f666e03ffae0a795e829682dd6644c42b4660baf 100644
--- a/Post/PView.h
+++ b/Post/PView.h
@@ -81,6 +81,8 @@ class PView{
   static PView *current();
   PViewOptions *getOptions(){ return _options; }  
   PViewData *getData(){ return _data; }
+  std::string getName(){ return _name; }
+  void setName(std::string val){ _name = val; }
   int getIndex(){ return _index; }
   void setIndex(int val){ _index = val; }
   bool getChanged(){ return _changed; }
diff --git a/Post/PViewData.cpp b/Post/PViewData.cpp
index d8918b4921717a49e465e3d646f57360e6c6f732..ec94388f0e57730096a77d3c8c91bbe6b8fd974f 100644
--- a/Post/PViewData.cpp
+++ b/Post/PViewData.cpp
@@ -1,4 +1,4 @@
-// $Id: PViewData.cpp,v 1.6 2007-08-28 22:54:06 geuzaine Exp $
+// $Id: PViewData.cpp,v 1.7 2007-08-31 09:18:16 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -133,6 +133,14 @@ void PViewDataList::finalize()
   setDirty(false);
 }
 
+double PViewDataList::getTime(int step)
+{
+  if(step < 0 || step >= List_Nbr(Time)) return 0.;
+  double val;
+  List_Read(Time, step, &val);
+  return val;
+}
+
 double PViewDataList::getMin(int step)
 {
   if(step < 0) return Min;
diff --git a/Post/PViewData.h b/Post/PViewData.h
index 0d592b2bc82e9c43b109bd114989882dc5a976ed..80a01c2ca6b21c9fde7bc3aba1102ac9396fa472 100644
--- a/Post/PViewData.h
+++ b/Post/PViewData.h
@@ -41,6 +41,7 @@ class PViewData {
   virtual void setDirty(bool val){ _dirty = val; }
   virtual void finalize(){}
   virtual int getNumTimeSteps() = 0;
+  virtual double getTime(int step){ return 0.; }
   virtual double getMin(int step=-1) = 0;
   virtual double getMax(int step=-1) = 0;
   virtual SBoundingBox3d getBoundingBox() = 0;
@@ -120,6 +121,7 @@ class PViewDataList : public PViewData {
   ~PViewDataList();
   void finalize();
   int getNumTimeSteps(){ return NbTimeStep; }
+  double getTime(int step);
   double getMin(int step=-1);
   double getMax(int step=-1);
   SBoundingBox3d getBoundingBox(){ return BBox; }
diff --git a/Post/PViewOptions.cpp b/Post/PViewOptions.cpp
index 8c55d88832efe8422e93ffabe4a6d6554c48b4ec..af38899d737f6aa7dcdd889861e0edcb48b0a19e 100644
--- a/Post/PViewOptions.cpp
+++ b/Post/PViewOptions.cpp
@@ -1,4 +1,4 @@
-// $Id: PViewOptions.cpp,v 1.13 2007-08-29 18:41:06 geuzaine Exp $
+// $Id: PViewOptions.cpp,v 1.14 2007-08-31 09:18:16 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -32,7 +32,11 @@
 PViewOptions::PViewOptions()
 {
   // FIXME: remove this once Options.cpp uses PViewOptions!
-  Type = Plot3D;
+
+  //Type = Plot3D;
+  //Type = Plot2DTime;
+  Type = Plot2DSpace;
+
   AutoPosition = 1;
   strcpy(Format, "%g");
   Axes = 1;
@@ -57,7 +61,7 @@ PViewOptions::PViewOptions()
   Visible = 1;
   IntervalsType = Continuous;
   //IntervalsType = Discrete;
-  IntervalsType = Iso;
+  //IntervalsType = Iso;
   //IntervalsType = Numeric;
   NbIso = 15;
   ArrowSizeProportional = 1;
@@ -70,11 +74,12 @@ PViewOptions::PViewOptions()
   ShowElement = 0;
   ShowTime = ShowScale = 1;
   ScaleType = Linear;
-  //VectorType = Arrow3D;
-  VectorType = Segment;
+  VectorType = Arrow3D;
+  //VectorType = Segment;
   //VectorType = Displacement;
   TensorType = VonMises;
   GlyphLocation = COG;
+  CenterGlyphs = 0;
   TimeStep = 0;
   DrawStrings = DrawPoints = DrawLines = DrawTriangles = DrawQuadrangles =
     DrawTetrahedra = DrawHexahedra = DrawPrisms = DrawPyramids =
@@ -88,6 +93,7 @@ PViewOptions::PViewOptions()
   UseGenRaise = 0;
   GenRaiseFactor = 0.;
   RangeType = Default;
+  RangeType = PerTimeStep;
   //RangeType = Custom;
   CustomMin = 0;
   CustomMax = 1.;
diff --git a/Post/PViewOptions.h b/Post/PViewOptions.h
index f0b5f9b536cc8595e002a777bf8d76b9f9a51863..ab5bd7142f773c619cf3d79e2c90ddd46b958699 100644
--- a/Post/PViewOptions.h
+++ b/Post/PViewOptions.h
@@ -89,7 +89,7 @@ class PViewOptions {
   int SaturateValues, FakeTransparency;
   int ShowElement, ShowTime, ShowScale;
   int ScaleType, RangeType;
-  int VectorType, TensorType, GlyphLocation;
+  int VectorType, TensorType, GlyphLocation, CenterGlyphs;
   int TimeStep;
   int DrawStrings;
   int DrawPoints, DrawLines, DrawTriangles, DrawQuadrangles;