/// <summary> /// Sets the size of the array. /// </summary> /// <param name="rows"> The number of rows.</param> /// <param name="cols"> The number of columns.</param> /// <remarks> This will only destroy data if you're making it smaller.</remarks> public void SetSize(int rows, int cols) { // TODO: Plotting - copy old data over data = new double[rows, cols]; // resize the display index if (displayIndex == null) displayIndex = new PlotIndex(rows); else displayIndex.Resize(rows); // add extra column names while (columnNames.Count < cols) { columnNames.Add("column" + columnNameCount.ToString()); columnNameCount++; } // remove unecessary column names if (cols < columnNames.Count) columnNames.RemoveRange(cols, columnNames.Count - cols - 1); }
/// <summary> /// Gets the index of points in the given column that fall between min and max. /// </summary> /// <param name="col"> </param> /// <param name="min"> </param> /// <param name="max"> </param> /// <returns> </returns> public PlotIndex GetColumnIndex(int col, double min, double max) { if (col < 0 || col > NumColumns) throw new Exception("Column out of bounds."); PlotIndex index = new PlotIndex(NumRows); for (int r=0; r<NumRows; r++) { if (!Double.IsNaN(data[r,col]) && (data[r, col] < min || data[r,col] > max)) index[r] = false; } return index; }
/// <summary> /// Compute the plot geometry. /// </summary> public override void ComputeGeometry() { base.ComputeGeometry(); _bounds.Reset(); // generate the colors double[] colorRange; // the range of values that the colors correspond to Color[] colors; // the colors PlotIndex colorIndex = null; // the index of points for the current color if (this[ColumnIndex.Color] < 0) // use the predefined color { colorRange = new double[]{0, 0}; colors = new Color[]{_color}; colorIndex = new PlotIndex(dataSet.NumRows); } else // generate the values from a color map { double min, max; // the min/max of the color column dataSet.ColumnMinMax(this[ColumnIndex.Color], out min, out max); colorRange = Bounds.NiceRange(min, max); colors = colorMap.GetColors(colorRange.Length-1); } // generate shapes double[] shapeRange; // the range of values that the shapes correspond to PlotShape[] shapes; // the shapes PlotIndex shapeIndex = null; // the index of points for the current shape if (this[ColumnIndex.Shape] < 0) // use the predefined shape { shapeRange = new double[]{0, 0}; shapes = new PlotShape[]{shape}; shapeIndex = new PlotIndex(dataSet.NumRows); } else // use predefined shapes { double min, max; // the min/max of the shape column dataSet.ColumnMinMax(this[ColumnIndex.Shape], out min, out max); double[] shapeRange_ = Bounds.NiceRange(min, max); min = shapeRange_[0]; max = shapeRange_[shapeRange_.Length-1]; shapeRange = new double[3]{min, (max+min)/2, max}; shapes = new PlotShape[]{PlotShape.Circle, PlotShape.Square}; } // generate sizes PlotIndex sizeIndex = null; float[] sizes; // the sizes double[] sizeRange; // the range of values that the size correspond to if (this[ColumnIndex.Size] < 0) // use the predefined sizes { sizeRange = new double[]{0,0}; sizes = new float[]{markerSize}; sizeIndex = new PlotIndex(dataSet.NumRows); } else // generate sizes from a range { double min, max; // the min/max of the size column dataSet.ColumnMinMax(this[ColumnIndex.Size], out min, out max); sizeRange = Bounds.NiceRange(min, max, 2.5); sizes = new float[sizeRange.Length-1]; for (int i=0; i<sizes.Length; i++) sizes[i] = (float)2*i + 1f; } _displayList = gl.glGenLists(1); // generate the display list gl.glNewList(_displayList, gl.GL_COMPILE); for (int shapeI=0; shapeI<shapes.Length; shapeI++) // cycle through shapes { // compute the index for this shape if (this[ColumnIndex.Shape] >= 0) shapeIndex = dataSet.GetColumnIndex(this[ColumnIndex.Shape], shapeRange[shapeI], shapeRange[shapeI+1]); // set the marker shape SetupShape(shapes[shapeI]); for (int sizeI=0; sizeI<sizes.Length; sizeI++) // cycle through sizes { // compute the index for this size if (this[ColumnIndex.Size] >= 0) sizeIndex = dataSet.GetColumnIndex(this[ColumnIndex.Size], sizeRange[sizeI], sizeRange[sizeI+1]); // begin the rendering gl.glPointSize(sizes[sizeI]); // set the size for (int colorI=0; colorI<colors.Length; colorI++) // cycle through colors { // compute the index for this color if (this[ColumnIndex.Color] >= 0) colorIndex = dataSet.GetColumnIndex(this[ColumnIndex.Color], colorRange[colorI], colorRange[colorI+1]); colors[colorI].Setup(); PlotIndex thisIndex = dataSet.DisplayIndex.Copy(); thisIndex.Intersect(colorIndex); // apply the color index thisIndex.Intersect(shapeIndex); // apply the shape index thisIndex.Intersect(sizeIndex); // apply the size index // plot the points for this color/shape/size if (markersVisible) gl.glBegin(gl.GL_POINTS); foreach (int r in thisIndex) { double x, y, z; x = dataSet[r, columns[0]]; y = dataSet[r, columns[1]]; z = dataSet[r, columns[2]]; if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z)) continue; ParentAxes.PlotToWorldSpace.Apply(ref x, ref y, ref z); if (markersVisible) gl.glVertex3d(x, y, z); _bounds.Resize(x, y, z); } if (markersVisible) gl.glEnd(); // plot the line for this color/shape/size if (lineVisible) { gl.glLineWidth(lineWidth); gl.glBegin(gl.GL_LINE_STRIP); foreach (int r in thisIndex) { double x, y, z; x = dataSet[r, columns[0]]; y = dataSet[r, columns[1]]; z = dataSet[r, columns[2]]; if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z)) continue; ParentAxes.PlotToWorldSpace.Apply(ref x, ref y, ref z); gl.glVertex3d(x, y, z); } gl.glEnd(); gl.glLineWidth(1); } } // colorI } // sizeI } // shapeI gl.glEndList(); // add legend items if (ParentAxes.Legend != null) { // color legend entries if (colors.Length > 1) { string colorColumn = dataSet.GetColumnName(this[ColumnIndex.Color]); for (int i = 0; i < colors.Length; i++ ) { LegendItem item = new LegendItem(); item.Icon.LineWidth = lineWidth; item.Icon.ShowLine = LineVisible; item.Icon.ShowMarker = MarkersVisible; item.Icon.Color = colors[i]; item.Text = String.Format("{0}: {1} to {2}", colorColumn, colorRange[i], colorRange[i+1]); if (shapes.Length == 1) // only one shape item.Icon.MarkerShape = shapes[0]; if (sizes.Length == 1) // only one size item.Icon.MarkerSize = markerSize; ParentAxes.Legend.Add(item); } } // shape legend entries if (shapes.Length > 1) { string shapeColumn = dataSet.GetColumnName(this[ColumnIndex.Shape]); for (int i = 0; i < shapes.Length; i++) { LegendItem item = new LegendItem(); item.Icon.LineWidth = lineWidth; item.Icon.ShowLine = LineVisible; item.Icon.ShowMarker = MarkersVisible; item.Text = String.Format("{0}: {1} to {2}", shapeColumn, shapeRange[i], shapeRange[i + 1]); item.Icon.MarkerShape = shapes[i]; if (colors.Length == 1) // only one color item.Icon.Color = colors[0]; if (sizes.Length == 1) // only one size item.Icon.MarkerSize = markerSize; ParentAxes.Legend.Add(item); } } // size legend entries if (sizes.Length > 1) { string sizeColumn = dataSet.GetColumnName(this[ColumnIndex.Size]); for (int i = 0; i < sizes.Length; i++) { LegendItem item = new LegendItem(); item.Icon.LineWidth = lineWidth; item.Icon.ShowLine = LineVisible; item.Icon.ShowMarker = MarkersVisible; item.Text = String.Format("{0}: {1} to {2}", sizeColumn, sizeRange[i], sizeRange[i + 1]); item.Icon.MarkerSize = sizes[i]; if (colors.Length == 1) // only one color item.Icon.Color = colors[0]; if (shapes.Length == 1) // only one shape item.Icon.MarkerShape = shapes[0]; ParentAxes.Legend.Add(item); } } // single legend entry, if nothing varies if (colors.Length == 1 && shapes.Length == 1 && sizes.Length == 1) { LegendItem item = new LegendItem(); item.Icon.LineWidth = lineWidth; item.Icon.ShowLine = LineVisible; item.Icon.ShowMarker = MarkersVisible; item.Text = dataSet.GetColumnName(Columns[2]); item.Icon.Color = colors[0]; item.Icon.MarkerShape = shapes[0]; item.Icon.MarkerSize = sizes[0]; ParentAxes.Legend.Add(item); } } }