/// <summary> /// Determines whether the plot items in <paramref name="coll"/> can be plotted as stack. Presumption is that all plot items /// have the same number of plot points, and that all items have the same order of x values associated with the plot points. /// </summary> /// <param name="layer">Plot layer.</param> /// <param name="coll">Collection of plot items.</param> /// <param name="plotDataList">Output: dictionary with associates each plot item with a list of processed plot data.</param> /// <returns>Returns <c>true</c> if the plot items in <paramref name="coll"/> can be plotted as stack; otherwise, <c>false</c>.</returns> public static bool CanUseStyle(IPlotArea layer, PlotItemCollection coll, out Dictionary <G3DPlotItem, Processed3DPlotData> plotDataList) { plotDataList = new Dictionary <G3DPlotItem, Processed3DPlotData>(); AltaxoVariant[] xArray = null; AltaxoVariant[] yArray = null; int idx = -1; foreach (IGPlotItem pi in coll) { if (pi is G3DPlotItem) { idx++; var gpi = (G3DPlotItem)pi; Processed3DPlotData pdata = gpi.GetRangesAndPoints(layer); plotDataList.Add(gpi, pdata); if (xArray == null) { xArray = new AltaxoVariant[pdata.RangeList.PlotPointCount]; yArray = new AltaxoVariant[pdata.RangeList.PlotPointCount]; int j = -1; foreach (int originalIndex in pdata.RangeList.OriginalRowIndices()) { j++; xArray[j] = pdata.GetXPhysical(originalIndex); yArray[j] = pdata.GetYPhysical(originalIndex); } } else // this is not the first item { if (pdata.RangeList.PlotPointCount != xArray.Length) { return(false); } int j = -1; foreach (int originalIndex in pdata.RangeList.OriginalRowIndices()) { j++; if (xArray[j] != pdata.GetXPhysical(originalIndex)) { return(false); } if (yArray[j] != pdata.GetYPhysical(originalIndex)) { return(false); } } } } } return(idx >= 1); }
public void PaintPreprocessing(IPaintContext paintContext, IPlotArea layer, PlotItemCollection coll) { if (!CanUseStyle(layer, coll, out var plotDataDict)) { return; } else { paintContext.AddValue(this, plotDataDict); } AltaxoVariant[] vArray = null; // First, add up all items since we start always with the last item int idx = -1; Processed3DPlotData previousItemData = null; foreach (IGPlotItem pi in coll) { if (pi is G3DPlotItem) { idx++; var gpi = pi as G3DPlotItem; Processed3DPlotData pdata = plotDataDict[gpi]; if (null == pdata) { continue; } vArray = AddUp(vArray, pdata); if (idx > 0) // this is not the first item { int j = -1; foreach (int originalIndex in pdata.RangeList.OriginalRowIndices()) { j++; var rel = new Logical3D( layer.XAxis.PhysicalVariantToNormal(pdata.GetXPhysical(originalIndex)), layer.YAxis.PhysicalVariantToNormal(pdata.GetYPhysical(originalIndex)), layer.ZAxis.PhysicalVariantToNormal(vArray[j])); layer.CoordinateSystem.LogicalToLayerCoordinates(rel, out var pabs); pdata.PlotPointsInAbsoluteLayerCoordinates[j] = pabs; } } // we have also to exchange the accessor for the physical y value and replace it by our own one var localArray = (AltaxoVariant[])vArray.Clone(); var localArrayHolder = new LocalArrayHolder(localArray, pdata); pdata.ZPhysicalAccessor = localArrayHolder.GetPhysical; pdata.PreviousItemData = previousItemData; previousItemData = pdata; } } }
public void Paint(IGraphicsContext3D g, IPlotArea layer, Processed3DPlotData pdata, Processed3DPlotData prevItemData, Processed3DPlotData nextItemData) { if (null == pdata) { throw new ArgumentNullException(nameof(pdata)); } PlotRangeList rangeList = pdata.RangeList; var ptArray = pdata.PlotPointsInAbsoluteLayerCoordinates; layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(0, 0, 0), out var leftFrontBotton); layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(1, 1, 1), out var rightBackTop); double globalBaseValue; if (_usePhysicalBaseValue) { globalBaseValue = layer.ZAxis.PhysicalVariantToNormal(_baseValue); if (double.IsNaN(globalBaseValue)) { globalBaseValue = 0; } } else { globalBaseValue = _baseValue.ToDouble(); } bool useVariableColor = null != _cachedColorForIndexFunction && !_independentColor; var pen = _pen; int j = -1; foreach (int originalRowIndex in pdata.RangeList.OriginalRowIndices()) { j++; double xCenterLogical = layer.XAxis.PhysicalVariantToNormal(pdata.GetXPhysical(originalRowIndex)); double xLowerLogical = xCenterLogical + _xOffsetLogical; double xUpperLogical = xLowerLogical + _xSizeLogical; double yCenterLogical = layer.YAxis.PhysicalVariantToNormal(pdata.GetYPhysical(originalRowIndex)); double yLowerLogical = yCenterLogical + _yOffsetLogical; double yUpperLogical = yLowerLogical + _ySizeLogical; double zCenterLogical = layer.ZAxis.PhysicalVariantToNormal(pdata.GetZPhysical(originalRowIndex)); double zBaseLogical = globalBaseValue; if (_startAtPreviousItem && pdata.PreviousItemData != null) { double prevstart = layer.ZAxis.PhysicalVariantToNormal(pdata.PreviousItemData.GetZPhysical(originalRowIndex)); if (!double.IsNaN(prevstart)) { zBaseLogical = prevstart; zBaseLogical += Math.Sign(zBaseLogical - globalBaseValue) * _previousItemZGap; } } layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(xLowerLogical, yCenterLogical, zBaseLogical), out var lcp); layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(xUpperLogical, yCenterLogical, zBaseLogical), out var ucp); layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(xCenterLogical, yLowerLogical, zBaseLogical), out var clp); layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(xCenterLogical, yUpperLogical, zBaseLogical), out var cup); double penWidth1 = (lcp - ucp).Length; double penWidth2 = (clp - cup).Length; if (_useUniformCrossSectionThickness) { pen = pen.WithUniformThickness(Math.Min(penWidth1, penWidth2)); } else { pen = pen.WithThickness1(penWidth1); pen = pen.WithThickness2(penWidth2); } if (useVariableColor) { pen = pen.WithColor(GdiColorHelper.ToNamedColor(_cachedColorForIndexFunction(originalRowIndex), "VariableColor")); } var isoLine = layer.CoordinateSystem.GetIsoline(new Logical3D(xLowerLogical, yLowerLogical, zBaseLogical), new Logical3D(xLowerLogical, yLowerLogical, zCenterLogical)); g.DrawLine(pen, isoLine); } }
public void Paint(IGraphicsContext3D g, IPlotArea layer, Processed3DPlotData pdata, Processed3DPlotData prevItemData, Processed3DPlotData nextItemData) { PlotRangeList rangeList = pdata.RangeList; var ptArray = pdata.PlotPointsInAbsoluteLayerCoordinates; // paint the style PointD3D leftFrontBotton, rightBackTop; layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(0, 0, 0), out leftFrontBotton); layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(1, 1, 1), out rightBackTop); double globalBaseValue; if (_usePhysicalBaseValue) { globalBaseValue = layer.ZAxis.PhysicalVariantToNormal(_baseValue); if (double.IsNaN(globalBaseValue)) globalBaseValue = 0; } else { globalBaseValue = _baseValue.ToDouble(); } bool useVariableColor = null != _cachedColorForIndexFunction && !_independentColor; var pen = _pen; int j = -1; foreach (int originalRowIndex in pdata.RangeList.OriginalRowIndices()) { j++; double xCenterLogical = layer.XAxis.PhysicalVariantToNormal(pdata.GetXPhysical(originalRowIndex)); double xLowerLogical = xCenterLogical + _xOffsetLogical; double xUpperLogical = xLowerLogical + _xSizeLogical; double yCenterLogical = layer.YAxis.PhysicalVariantToNormal(pdata.GetYPhysical(originalRowIndex)); double yLowerLogical = yCenterLogical + _yOffsetLogical; double yUpperLogical = yLowerLogical + _ySizeLogical; double zCenterLogical = layer.ZAxis.PhysicalVariantToNormal(pdata.GetZPhysical(originalRowIndex)); double zBaseLogical = globalBaseValue; if (_startAtPreviousItem && pdata.PreviousItemData != null) { double prevstart = layer.ZAxis.PhysicalVariantToNormal(pdata.PreviousItemData.GetZPhysical(originalRowIndex)); if (!double.IsNaN(prevstart)) { zBaseLogical = prevstart; zBaseLogical += Math.Sign(zBaseLogical - globalBaseValue) * _previousItemZGap; } } // calculate the size at the base PointD3D lcp, ucp, clp, cup; layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(xLowerLogical, yCenterLogical, zBaseLogical), out lcp); layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(xUpperLogical, yCenterLogical, zBaseLogical), out ucp); layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(xCenterLogical, yLowerLogical, zBaseLogical), out clp); layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(xCenterLogical, yUpperLogical, zBaseLogical), out cup); double penWidth1 = (lcp - ucp).Length; double penWidth2 = (clp - cup).Length; if (_useUniformCrossSectionThickness) { pen = pen.WithUniformThickness(Math.Min(penWidth1, penWidth2)); } else { pen = pen.WithThickness1(penWidth1); pen = pen.WithThickness2(penWidth2); } if (useVariableColor) pen = pen.WithColor(GdiColorHelper.ToNamedColor(_cachedColorForIndexFunction(originalRowIndex), "VariableColor")); var isoLine = layer.CoordinateSystem.GetIsoline(new Logical3D(xLowerLogical, yLowerLogical, zBaseLogical), new Logical3D(xLowerLogical, yLowerLogical, zCenterLogical)); g.DrawLine(pen, isoLine); } }
public void Paint(IGraphicsContext3D g, IPlotArea layer, Processed3DPlotData pdata, Processed3DPlotData prevItemData, Processed3DPlotData nextItemData) { const double logicalClampMinimum = -10; const double logicalClampMaximum = 11; // Plot error bars for the dependent variable (y) PlotRangeList rangeList = pdata.RangeList; var ptArray = pdata.PlotPointsInAbsoluteLayerCoordinates; var columnX = ColumnX; var columnY = ColumnY; var columnZ = ColumnZ; if (columnX == null || columnY == null || columnZ == null) return; // nothing to do if both error columns are null if (!typeof(double).IsAssignableFrom(columnX.ItemType) || !typeof(double).IsAssignableFrom(columnY.ItemType) || !typeof(double).IsAssignableFrom(columnZ.ItemType)) return; // TODO make this an runtime paint error to be reported var strokePen = _strokePen; foreach (PlotRange r in rangeList) { int lower = r.LowerBound; int upper = r.UpperBound; int offset = r.OffsetToOriginal; for (int j = lower; j < upper; j += _skipFrequency) { int originalRow = j + offset; double symbolSize = null == _cachedSymbolSizeForIndexFunction ? _symbolSize : _cachedSymbolSizeForIndexFunction(originalRow); strokePen = strokePen.WithThickness1(_lineWidth1Offset + _lineWidth1Factor * symbolSize); strokePen = strokePen.WithThickness2(_lineWidth2Offset + _lineWidth2Factor * symbolSize); if (null != _cachedColorForIndexFunction) strokePen = strokePen.WithColor(GdiColorHelper.ToNamedColor(_cachedColorForIndexFunction(originalRow), "VariableColor")); if (null != strokePen.LineEndCap) strokePen = strokePen.WithLineEndCap(strokePen.LineEndCap.WithMinimumAbsoluteAndRelativeSize(symbolSize * _endCapSizeFactor + _endCapSizeOffset, 1 + 1E-6)); // Calculate target AltaxoVariant targetX, targetY, targetZ; switch (_meaningOfValues) { case ValueInterpretation.AbsoluteDifference: { targetX = pdata.GetXPhysical(originalRow) + columnX[originalRow]; targetY = pdata.GetYPhysical(originalRow) + columnY[originalRow]; targetZ = pdata.GetZPhysical(originalRow) + columnZ[originalRow]; } break; case ValueInterpretation.AbsoluteValue: { targetX = columnX[originalRow]; targetY = columnY[originalRow]; targetZ = columnZ[originalRow]; } break; default: throw new NotImplementedException(nameof(_meaningOfValues)); } var logicalTarget = layer.GetLogical3D(targetX, targetY, targetZ); var logicalOrigin = layer.GetLogical3D(pdata, originalRow); if (!_independentOnShiftingGroupStyles && (0 != _cachedLogicalShiftX || 0 != _cachedLogicalShiftY || 0 != _cachedLogicalShiftZ)) { logicalOrigin.RX += _cachedLogicalShiftX; logicalOrigin.RY += _cachedLogicalShiftY; logicalOrigin.RZ += _cachedLogicalShiftZ; logicalTarget.RX += _cachedLogicalShiftX; logicalTarget.RY += _cachedLogicalShiftY; logicalTarget.RZ += _cachedLogicalShiftZ; } if (!Calc.RMath.IsInIntervalCC(logicalOrigin.RX, logicalClampMinimum, logicalClampMaximum)) continue; if (!Calc.RMath.IsInIntervalCC(logicalOrigin.RY, logicalClampMinimum, logicalClampMaximum)) continue; if (!Calc.RMath.IsInIntervalCC(logicalOrigin.RZ, logicalClampMinimum, logicalClampMaximum)) continue; if (!Calc.RMath.IsInIntervalCC(logicalTarget.RX, logicalClampMinimum, logicalClampMaximum)) continue; if (!Calc.RMath.IsInIntervalCC(logicalTarget.RY, logicalClampMinimum, logicalClampMaximum)) continue; if (!Calc.RMath.IsInIntervalCC(logicalTarget.RZ, logicalClampMinimum, logicalClampMaximum)) continue; var isoLine = layer.CoordinateSystem.GetIsoline(logicalOrigin, logicalTarget); if (null == isoLine) continue; if (_useManualVectorLength) { double length = _vectorLengthOffset + _vectorLengthFactor * symbolSize; double isoLineLength = isoLine.TotalLineLength; isoLine = isoLine.ShortenedBy(RADouble.NewAbs(0), RADouble.NewAbs(isoLineLength - length)); if (null == isoLine) continue; } if (_useSymbolGap) { double gap = _symbolGapOffset + _symbolGapFactor * symbolSize; if (gap != 0) { isoLine = isoLine.ShortenedBy(RADouble.NewAbs(gap / 2), RADouble.NewAbs(0)); if (null == isoLine) continue; } } g.DrawLine(strokePen, isoLine); } } }
public void Paint(IGraphicsContext3D g, IPlotArea layer, Processed3DPlotData pdata, Processed3DPlotData prevItemData, Processed3DPlotData nextItemData) { const double logicalClampMinimum = -10; const double logicalClampMaximum = 11; // Plot error bars for the dependent variable (y) PlotRangeList rangeList = pdata.RangeList; var ptArray = pdata.PlotPointsInAbsoluteLayerCoordinates; var columnX = ColumnX; var columnY = ColumnY; var columnZ = ColumnZ; if (columnX == null || columnY == null || columnZ == null) { return; // nothing to do if both error columns are null } if (!typeof(double).IsAssignableFrom(columnX.ItemType) || !typeof(double).IsAssignableFrom(columnY.ItemType) || !typeof(double).IsAssignableFrom(columnZ.ItemType)) { return; // TODO make this an runtime paint error to be reported } var strokePen = _strokePen; foreach (PlotRange r in rangeList) { int lower = r.LowerBound; int upper = r.UpperBound; int offset = r.OffsetToOriginal; for (int j = lower; j < upper; j += _skipFrequency) { int originalRow = j + offset; double symbolSize = null == _cachedSymbolSizeForIndexFunction ? _symbolSize : _cachedSymbolSizeForIndexFunction(originalRow); strokePen = strokePen.WithThickness1(_lineWidth1Offset + _lineWidth1Factor * symbolSize); strokePen = strokePen.WithThickness2(_lineWidth2Offset + _lineWidth2Factor * symbolSize); if (null != _cachedColorForIndexFunction) { strokePen = strokePen.WithColor(GdiColorHelper.ToNamedColor(_cachedColorForIndexFunction(originalRow), "VariableColor")); } if (null != strokePen.LineEndCap) { strokePen = strokePen.WithLineEndCap(strokePen.LineEndCap.WithMinimumAbsoluteAndRelativeSize(symbolSize * _endCapSizeFactor + _endCapSizeOffset, 1 + 1E-6)); } // Calculate target AltaxoVariant targetX, targetY, targetZ; switch (_meaningOfValues) { case ValueInterpretation.AbsoluteDifference: { targetX = pdata.GetXPhysical(originalRow) + columnX[originalRow]; targetY = pdata.GetYPhysical(originalRow) + columnY[originalRow]; targetZ = pdata.GetZPhysical(originalRow) + columnZ[originalRow]; } break; case ValueInterpretation.AbsoluteValue: { targetX = columnX[originalRow]; targetY = columnY[originalRow]; targetZ = columnZ[originalRow]; } break; default: throw new NotImplementedException(nameof(_meaningOfValues)); } var logicalTarget = layer.GetLogical3D(targetX, targetY, targetZ); var logicalOrigin = layer.GetLogical3D(pdata, originalRow); if (!_independentOnShiftingGroupStyles && (0 != _cachedLogicalShiftX || 0 != _cachedLogicalShiftY || 0 != _cachedLogicalShiftZ)) { logicalOrigin.RX += _cachedLogicalShiftX; logicalOrigin.RY += _cachedLogicalShiftY; logicalOrigin.RZ += _cachedLogicalShiftZ; logicalTarget.RX += _cachedLogicalShiftX; logicalTarget.RY += _cachedLogicalShiftY; logicalTarget.RZ += _cachedLogicalShiftZ; } if (!Calc.RMath.IsInIntervalCC(logicalOrigin.RX, logicalClampMinimum, logicalClampMaximum)) { continue; } if (!Calc.RMath.IsInIntervalCC(logicalOrigin.RY, logicalClampMinimum, logicalClampMaximum)) { continue; } if (!Calc.RMath.IsInIntervalCC(logicalOrigin.RZ, logicalClampMinimum, logicalClampMaximum)) { continue; } if (!Calc.RMath.IsInIntervalCC(logicalTarget.RX, logicalClampMinimum, logicalClampMaximum)) { continue; } if (!Calc.RMath.IsInIntervalCC(logicalTarget.RY, logicalClampMinimum, logicalClampMaximum)) { continue; } if (!Calc.RMath.IsInIntervalCC(logicalTarget.RZ, logicalClampMinimum, logicalClampMaximum)) { continue; } var isoLine = layer.CoordinateSystem.GetIsoline(logicalOrigin, logicalTarget); if (null == isoLine) { continue; } if (_useManualVectorLength) { double length = _vectorLengthOffset + _vectorLengthFactor * symbolSize; double isoLineLength = isoLine.TotalLineLength; isoLine = isoLine.ShortenedBy(RADouble.NewAbs(0), RADouble.NewAbs(isoLineLength - length)); if (null == isoLine) { continue; } } if (_useSymbolGap) { double gap = _symbolGapOffset + _symbolGapFactor * symbolSize; if (gap != 0) { isoLine = isoLine.ShortenedBy(RADouble.NewAbs(gap / 2), RADouble.NewAbs(0)); if (null == isoLine) { continue; } } } g.DrawLine(strokePen, isoLine); } } }