// Make rows of bars in the X and Z directions.
        private void MakeRowColumnBars(double xmin, double ymin,
                                       double zmin, double dx, double gap,
                                       double[,] values, string[] frontLabels, string[] sideLabels,
                                       Brush[,] barBrushes, Brush[] bgBrushes, Brush[] fgBrushes,
                                       FontFamily ff, Model3DGroup group)
        {
            int    numX = values.GetUpperBound(0) + 1;
            int    numZ = values.GetUpperBound(1) + 1;
            double x    = xmin;
            double z;
            double fontSize = 0.3;

            for (int ix = 0; ix < numX; ix++)
            {
                z = zmin;
                for (int iz = 0; iz < numZ; iz++)
                {
                    // Make the bar.
                    MeshGeometry3D barMesh = new MeshGeometry3D();
                    Point3D        corner  = new Point3D(x, ymin, z);
                    barMesh.AddBox(corner,
                                   D3.XVector(dx),
                                   D3.YVector(YScale * values[ix, iz]),
                                   D3.ZVector(dx));
                    group.Children.Add(barMesh.MakeModel(barBrushes[ix, iz]));

                    z += dx + gap;
                }

                // Display the front label.
                const double textWid = 2;
                MakeLabel(frontLabels[ix],
                          new Point3D(x + dx, ymin, z + textWid),
                          D3.ZVector(-textWid), D3.XVector(-dx),
                          bgBrushes[ix], fgBrushes[ix], fontSize, ff,
                          HorizontalAlignment.Left, VerticalAlignment.Center, group);

                x += dx + gap;
            }

            // Display the side labels.
            z = zmin + dx;
            double xmax = xmin + numX * dx + (numX - 1) * gap;

            for (int iz = 0; iz < numZ; iz++)
            {
                const double textWid = 2;
                MakeLabel(sideLabels[iz],
                          new Point3D(xmax + gap, ymin, z),
                          D3.XVector(textWid), D3.ZVector(-dx),
                          Brushes.Transparent, Brushes.Black, fontSize, ff,
                          HorizontalAlignment.Left, VerticalAlignment.Center, group);
                //MakeLabel(sideLabels[iz],
                //    new Point3D(xmin - textWid - gap, ymin, z),
                //    D3.XVector(textWid), D3.ZVector(-dx),
                //    Brushes.Transparent, Brushes.Black, fontSize, ff,
                //    HorizontalAlignment.Left, VerticalAlignment.Center, group);
                z += dx + gap;
            }
        }
        // Make a row of bars in the X direction.
        private void MakeBars(double xmin, double ymin,
                              double zmin, double dx, double gap,
                              double[] values, string[] frontLabels, string[] topLabels,
                              Brush[] barBrushes, Brush[] bgBrushes, Brush[] fgBrushes,
                              FontFamily ff, Model3DGroup group)
        {
            double x        = xmin;
            double fontSize = 0.4;

            for (int i = 0; i < values.Length; i++)
            {
                // Make the bar.
                MeshGeometry3D barMesh = new MeshGeometry3D();
                Point3D        corner  = new Point3D(x, ymin, zmin);
                barMesh.AddBox(corner,
                               D3.XVector(dx),
                               D3.YVector(YScale * values[i]),
                               D3.ZVector(dx));
                group.Children.Add(barMesh.MakeModel(barBrushes[i]));

                // Display the front label.
                const double textWid = 1.8;
                MakeLabel(frontLabels[i],
                          new Point3D(x + dx, ymin, textWid + zmin + dx + gap),
                          D3.ZVector(-textWid), D3.XVector(-dx),
                          bgBrushes[i], fgBrushes[i], fontSize, ff,
                          HorizontalAlignment.Left, VerticalAlignment.Center, group);

                // Display the top label.
                MakeLabel(topLabels[i],
                          new Point3D(x,
                                      ymin + YScale * values[i],
                                      zmin - 0.1),
                          D3.XVector(dx), D3.YVector(dx),
                          Brushes.Transparent, fgBrushes[i], fontSize, ff,
                          HorizontalAlignment.Center, VerticalAlignment.Bottom, group);

                x += dx + gap;
            }
        }
        // Make a row of stacked bars in the X direction.
        private void MakeStackedBars(double xmin, double ymin,
                                     double zmin, double dx, double gap,
                                     double[,] values, string[] frontLabels,
                                     Brush[] barBrushes, Brush bgBrush, Brush fgBrush,
                                     FontFamily ff, Model3DGroup group)
        {
            double x        = xmin;
            int    numX     = values.GetUpperBound(0) + 1;
            int    numZ     = values.GetUpperBound(1) + 1;
            double fontSize = 0.45;

            for (int ix = 0; ix < numX; ix++)
            {
                double y = ymin;
                for (int iz = 0; iz < numZ; iz++)
                {
                    // Make this piece of the bar.
                    MeshGeometry3D barMesh = new MeshGeometry3D();
                    Point3D        corner  = new Point3D(x, y, zmin);
                    barMesh.AddBox(corner,
                                   D3.XVector(dx),
                                   D3.YVector(YScale * values[ix, iz]),
                                   D3.ZVector(dx));
                    group.Children.Add(barMesh.MakeModel(barBrushes[iz]));
                    y += YScale * values[ix, iz];
                }

                // Display the front label.
                const double textWid = 1.5;
                MakeLabel(frontLabels[ix],
                          new Point3D(x + dx, ymin, textWid + zmin + dx + gap),
                          D3.ZVector(-textWid), D3.XVector(-dx),
                          bgBrush, fgBrush, fontSize, FontFamily,
                          HorizontalAlignment.Left, VerticalAlignment.Center, group);

                x += dx + gap;
            }
        }