123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620 |
- using ScottPlot.Drawing;
- using ScottPlot.Plottable;
- using ScottPlot.Renderable;
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Collections.Specialized;
- using System.Drawing;
- using System.Linq;
- namespace ScottPlot
- {
- /// <summary>
- /// This module holds state for figure dimensions, axis limits, plot contents, and styling options.
- /// A plot can be duplicated by copying the full state of this settings module.
- /// </summary>
- public class Settings
- {
- /// <summary>
- /// This List contains all plottables managed by this Plot.
- /// Render order is from lowest (first) to highest (last).
- /// </summary>
- public readonly ObservableCollection<IPlottable> Plottables = new();
- /// <summary>
- /// Unique value that changes any time the list of plottables is modified.
- /// </summary>
- public int PlottablesIdentifier { get; private set; } = 0;
- /// <summary>
- /// Return the next color from PlottablePalette based on the current number of plottables
- /// </summary>
- public Color GetNextColor() => PlottablePalette.GetColor(Plottables.Count);
- // renderable objects the user can customize
- public readonly FigureBackground FigureBackground = new FigureBackground();
- public readonly DataBackground DataBackground = new DataBackground();
- public readonly BenchmarkMessage BenchmarkMessage = new BenchmarkMessage();
- public readonly ErrorMessage ErrorMessage = new ErrorMessage();
- public readonly Legend CornerLegend = new Legend();
- public readonly ZoomRectangle ZoomRectangle = new ZoomRectangle();
- public (double xMin, double xMax, double yMin, double yMax) ZoomUnitArea { get; private set; }
- public Palette PlottablePalette = Palette.Category10;
- public Int32 WfmIntensity { get; set; } = 50;
- public (Int32 left, Int32 top, Int32 right, Int32 bottom) Margin { get; set; } = (0, 0, 0, 0);
- // the Axes list stores styling info for each axis and its limits
- public List<Axis> Axes = new List<Axis>() {
- new DefaultRightAxis(),//默认的右边刻度
- new DefaultLeftAxis(),//默认的左边刻度
- new DefaultBottomAxis(),//默认的底边刻度
- new DefaultTopAxis()//默认的上边刻度
- };
- public int[] XAxisIndexes => Axes.Where(x => x.IsHorizontal).Select(x => x.AxisIndex).Distinct().ToArray();
- public int[] YAxisIndexes => Axes.Where(x => x.IsVertical).Select(x => x.AxisIndex).Distinct().ToArray();
- public Axis GetXAxis(int xAxisIndex) => Axes.Where(x => x.IsHorizontal && x.AxisIndex == xAxisIndex).First();
- public Axis GetYAxis(int yAxisIndex) => Axes.Where(x => x.IsVertical && x.AxisIndex == yAxisIndex).First();
- public bool AllAxesHaveBeenSet => Axes.All(x => x.Dims.HasBeenSet);
- public EqualScaleMode EqualScaleMode = EqualScaleMode.Disabled;
- // shortcuts to fixed axes indexes
- public Axis YAxis => Axes[0];//默认Y轴
- public Axis YAxis2 => Axes[1];
- public Axis XAxis => Axes[2];//默认X轴
- public Axis XAxis2 => Axes[3];
- // public fields represent primary X and Y axes
- public int Width => (int)XAxis.Dims.FigureSizePx;
- public int Height => (int)YAxis.Dims.FigureSizePx;
- public float DataOffsetX => XAxis.Dims.DataOffsetPx;
- public float DataOffsetY => YAxis.Dims.DataOffsetPx;
- public float DataWidth => XAxis.Dims.DataSizePx;
- public float DataHeight => YAxis.Dims.DataSizePx;
- public Settings()
- {
- Plottables.CollectionChanged += (object sender, NotifyCollectionChangedEventArgs e) => PlottablesIdentifier++;
- }
- /// <summary>
- /// Return figure dimensions for the specified X and Y axes
- /// </summary>
- public PlotDimensions GetPlotDimensions(int xAxisIndex, int yAxisIndex, double scaleFactor)
- {
- var xAxis = GetXAxis(xAxisIndex);
- var yAxis = GetYAxis(yAxisIndex);
- // determine figure dimensions based on primary X and Y axis
- var figureSize = new SizeF(XAxis.Dims.FigureSizePx, YAxis.Dims.FigureSizePx);//整个图片大小
- var dataSize = new SizeF(XAxis.Dims.DataSizePx, YAxis.Dims.DataSizePx);//波形绘制区域大小
- var dataOffset = new PointF(XAxis.Dims.DataOffsetPx, YAxis.Dims.DataOffsetPx);//左上角的偏移量
- // determine axis limits based on specific X and Y axes
- (double xMin, double xMax) = xAxis.Dims.RationalLimits();
- (double yMin, double yMax) = yAxis.Dims.RationalLimits();
- var limits = (xMin, xMax, yMin, yMax);
- return new PlotDimensions(figureSize, dataSize, dataOffset, limits, scaleFactor,(xAxis.GetMinorLogScale(), yAxis.GetMinorLogScale()));
- }
- /// <summary>
- /// Set the default size for rendering images
- /// </summary>
- public void Resize(float width, float height)
- {
- foreach (Axis axis in Axes)//设置所有坐标轴的大小
- axis.Dims.Resize(axis.IsHorizontal ? width : height);
- }
- /// <summary>
- /// 更新通道的垂直标记
- /// </summary>
- /// <param name="position"></param>
- /// <param name="scale"></param>
- /// <param name="unitPrefix"></param>
- /// <param name="scaleUnit"></param>
- /// <param name="color"></param>
- /// <param name="interval"></param>
- /// <param name="isUnitPrefix"></param>
- /// <param name="tickDecimalPlaces"></param>
- public void ResetChannelParameter(Int32 position, double scale, string unitPrefix, string scaleUnit, Color color ,Int32 interval = 1000,Boolean isUnitPrefix=true, Int32 tickDecimalPlaces = 4)
- {
- YAxis.Dims.Update(position, scale, unitPrefix, scaleUnit, interval, isUnitPrefix, tickDecimalPlaces);
- YAxis.Dims.SetTickLabelColor(color);
- }
- /// <summary>
- /// 更新水平标记
- /// </summary>
- /// <param name="position"></param>
- /// <param name="scale"></param>
- /// <param name="unitPrefix"></param>
- /// <param name="scaleUnit"></param>
- /// <param name="color"></param>
- /// <param name="interval"></param>
- /// <param name="isUnitPrefix"></param>
- /// <param name="tickDecimalPlaces"></param>
- public void ResetTimebaseParameter(Int32 position, double scale, string unitPrefix, string scaleUnit, Color color, Int32 interval = 1000, Boolean isUnitPrefix = true, Int32 tickDecimalPlaces = 4)
- {
- XAxis.Dims.Update(position, scale, unitPrefix, scaleUnit, interval, isUnitPrefix, tickDecimalPlaces);
- XAxis.Dims.SetTickLabelColor(color);
- }
- /// <summary>
- /// Reset axis limits to their defauts
- /// </summary>
- public void ResetAxisLimits()
- {
- //foreach (Axis axis in Axes)
- // axis.Dims.ResetLimits();
- }
- /// <summary>
- /// Define axis limits for a particuar axis
- /// </summary>
- public void AxisSet(double? xMin, double? xMax, double? yMin, double? yMax, int xAxisIndex = 0, int yAxisIndex = 0)
- {
- GetXAxis(xAxisIndex).Dims.SetAxis(xMin, xMax);
- GetYAxis(yAxisIndex).Dims.SetAxis(yMin, yMax);
- }
- /// <summary>
- /// Define axis limits for a particuar axis
- /// </summary>
- public void AxisSet(AxisLimits limits, int xAxisIndex = 0, int yAxisIndex = 0)
- {
- GetXAxis(xAxisIndex).Dims.SetAxis(limits.XMin, limits.XMax);
- GetYAxis(yAxisIndex).Dims.SetAxis(limits.YMin, limits.YMax);
- }
- /// <summary>
- /// Return X and Y axis limits
- /// </summary>
- public AxisLimits AxisLimits(int xAxisIndex, int yAxisIndex)
- {
- var xAxis = GetXAxis(xAxisIndex);
- var yAxis = GetYAxis(yAxisIndex);
- return new AxisLimits(xAxis.Dims.Min, xAxis.Dims.Max, yAxis.Dims.Min, yAxis.Dims.Max);
- }
- /// <summary>
- /// Pan all axes by the given pixel distance
- /// </summary>
- public void AxesPanPx(float dxPx, float dyPx)
- {
- //List<int> modifiedXs = new List<int>();
- //foreach (Axis axis in Axes.Where(x => x.IsHorizontal))
- //{
- // if (!modifiedXs.Contains(axis.AxisIndex))
- // {
- // axis.Dims.PanPx(axis.IsHorizontal ? dxPx : dyPx);
- // modifiedXs.Add(axis.AxisIndex);
- // }
- //}
- //List<int> modifiedYs = new List<int>();
- //foreach (Axis axis in Axes.Where(x => x.IsVertical))
- //{
- // if (!modifiedYs.Contains(axis.AxisIndex))
- // {
- // axis.Dims.PanPx(axis.IsHorizontal ? dxPx : dyPx);
- // modifiedYs.Add(axis.AxisIndex);
- // }
- //}
- }
- /// <summary>
- /// Zoom all axes by the given pixel distance
- /// </summary>
- public void AxesZoomPx(float xPx, float yPx, bool lockRatio = false)
- {
- //if (lockRatio)
- // (xPx, yPx) = (Math.Max(xPx, yPx), Math.Max(xPx, yPx));
- //foreach (Axis axis in Axes)
- //{
- // double deltaPx = axis.IsHorizontal ? xPx : yPx;
- // double delta = deltaPx * axis.Dims.UnitsPerPx;
- // double deltaFrac = delta / (Math.Abs(delta) + axis.Dims.Span);
- // axis.Dims.Zoom(Math.Pow(10, deltaFrac));
- //}
- }
- /// <summary>
- /// Zoom all axes by the given fraction
- /// </summary>
- public void AxesZoomTo(double xFrac, double yFrac, float xPixel, float yPixel)
- {
- //foreach (Axis axis in Axes)
- //{
- // double frac = axis.IsHorizontal ? xFrac : yFrac;
- // float centerPixel = axis.IsHorizontal ? xPixel : yPixel;
- // double center = axis.Dims.GetUnit(centerPixel);
- // axis.Dims.Zoom(frac, center);
- //}
- }
- /// <summary>
- /// Automatically adjust X and Y axis limits of all axes to fit the data
- /// </summary>
- public void AxisAutoAll(double horizontalMargin = .1, double verticalMargin = .1)
- {
- //AxisAutoAllX(horizontalMargin);
- //AxisAutoAllY(verticalMargin);
- }
- /// <summary>
- /// Automatically adjust axis limits for all axes which have not yet been set
- /// </summary>
- public void AxisAutoUnsetAxes()
- {
- /* Extra logic here ensures axes index only get auto-set once
- * in the case that multiple axes share the same axis index
- */
- //var xAxes = Axes.Where(x => x.IsHorizontal);
- //var yAxes = Axes.Where(x => x.IsVertical);
- //var setIndexesX = xAxes.Where(x => x.Dims.HasBeenSet && !x.Dims.IsNan).Select(x => x.AxisIndex).Distinct().ToList();
- //var setIndexesY = yAxes.Where(x => x.Dims.HasBeenSet && !x.Dims.IsNan).Select(x => x.AxisIndex).Distinct().ToList();
- //foreach (Axis axis in xAxes)
- //{
- // if (axis.Dims.HasBeenSet && !axis.Dims.IsNan)
- // continue;
- // if (setIndexesX.Contains(axis.AxisIndex))
- // continue;
- // setIndexesX.Add(axis.AxisIndex);
- // AxisAutoX(axis.AxisIndex);
- //}
- //foreach (Axis axis in yAxes)
- //{
- // if (axis.Dims.HasBeenSet && !axis.Dims.IsNan)
- // continue;
- // if (setIndexesY.Contains(axis.AxisIndex))
- // continue;
- // setIndexesY.Add(axis.AxisIndex);
- // AxisAutoY(axis.AxisIndex);
- //}
- }
- /// <summary>
- /// If a scale lock mode is in use, modify the axis limits accordingly
- /// </summary>
- public void EnforceEqualAxisScales()
- {
- switch (EqualScaleMode)
- {
- case EqualScaleMode.Disabled:
- return;
- case EqualScaleMode.PreserveX:
- double yHalfSize = (YAxis.Dims.DataSizePx / 2) * XAxis.Dims.UnitsPerPx;
- AxisSet(null, null, YAxis.Dims.Center - yHalfSize, YAxis.Dims.Center + yHalfSize);
- return;
- case EqualScaleMode.PreserveY:
- double xHalfSize = (XAxis.Dims.DataSizePx / 2) * YAxis.Dims.UnitsPerPx;
- AxisSet(XAxis.Dims.Center - xHalfSize, XAxis.Dims.Center + xHalfSize, null, null);
- return;
- case EqualScaleMode.ZoomOut:
- double maxUnitsPerPx = Math.Max(XAxis.Dims.UnitsPerPx, YAxis.Dims.UnitsPerPx);
- double halfX = (XAxis.Dims.DataSizePx / 2) * maxUnitsPerPx;
- double halfY = (YAxis.Dims.DataSizePx / 2) * maxUnitsPerPx;
- AxisSet(XAxis.Dims.Center - halfX, XAxis.Dims.Center + halfX, YAxis.Dims.Center - halfY, YAxis.Dims.Center + halfY);
- return;
- default:
- throw new InvalidOperationException("unknown scale lock mode");
- }
- }
- /// <summary>
- /// Automatically adjust X axis limits to fit the data
- /// </summary>
- public void AxisAutoAllX(double margin = .1)
- {
- //int[] xAxisIndexes = Axes.Where(x => x.IsHorizontal).Select(x => x.AxisIndex).Distinct().ToArray();
- //foreach (int i in xAxisIndexes)
- // AxisAutoX(i, margin);
- }
- /// <summary>
- /// Automatically adjust Y axis limits to fit the data
- /// </summary>
- public void AxisAutoAllY(double margin = .1)
- {
- //int[] yAxisIndexes = Axes.Where(x => x.IsVertical).Select(x => x.AxisIndex).Distinct().ToArray();
- //foreach (int i in yAxisIndexes)
- // AxisAutoY(i, margin);
- }
- private void AxisAutoX(int xAxisIndex, double margin = .1)
- {
- double min = double.NaN;
- double max = double.NaN;
- double zoomFrac = 1 - margin;
- var plottableLimits = Plottables.Where(x => x is IPlottable)
- .Select(x => (IPlottable)x)
- .Where(x => x.IsVisible)
- .Where(x => x.XAxisIndex == xAxisIndex)
- .Select(x => x.GetAxisLimits())
- .ToArray();
- foreach (var limits in plottableLimits)
- {
- if (!double.IsNaN(limits.XMin))
- min = double.IsNaN(min) ? limits.XMin : Math.Min(min, limits.XMin);
- if (!double.IsNaN(limits.XMax))
- max = double.IsNaN(max) ? limits.XMax : Math.Max(max, limits.XMax);
- }
- if (double.IsNaN(min) && double.IsNaN(max))
- return;
- var xAxis = GetXAxis(xAxisIndex);
- xAxis.Dims.SetAxis(min, max);
- xAxis.Dims.Zoom(zoomFrac);
- }
- private void AxisAutoY(int yAxisIndex, double margin = .1)
- {
- double min = double.NaN;
- double max = double.NaN;
- double zoomFrac = 1 - margin;
- var plottableLimits = Plottables.Where(x => x is IPlottable)
- .Select(x => (IPlottable)x)
- .Where(x => x.IsVisible)
- .Where(x => x.YAxisIndex == yAxisIndex)
- .Select(x => x.GetAxisLimits())
- .ToArray();
- foreach (var limits in plottableLimits)
- {
- if (!double.IsNaN(limits.YMin))
- min = double.IsNaN(min) ? limits.YMin : Math.Min(min, limits.YMin);
- if (!double.IsNaN(limits.YMax))
- max = double.IsNaN(max) ? limits.YMax : Math.Max(max, limits.YMax);
- }
- if (double.IsNaN(min) && double.IsNaN(max))
- return;
- var yAxis = GetYAxis(yAxisIndex);
- yAxis.Dims.SetAxis(min, max);
- yAxis.Dims.Zoom(zoomFrac);
- }
- /// <summary>
- /// Store axis limits (useful for storing state upon a MouseDown event)
- /// </summary>
- public void RememberAxisLimits()
- {
- AxisAutoUnsetAxes();
- foreach (Axis axis in Axes)
- axis.Dims.Remember();
- }
- /// <summary>
- /// Recall axis limits (useful for recalling state from a previous MouseDown event)
- /// </summary>
- public void RecallAxisLimits()
- {
- foreach (Axis axis in Axes)
- axis.Dims.Recall();
- }
- public float MouseDownX { get; private set; }
- public float MouseDownY { get; private set; }
- /// <summary>
- /// Remember mouse position (do this before calling MousePan or MouseZoom)
- /// </summary>
- public void MouseDown(float mouseDownX, float mouseDownY)
- {
- RememberAxisLimits();
- MouseDownX = mouseDownX;
- MouseDownY = mouseDownY;
- }
- /// <summary>
- /// Pan all axes based on the mouse position now vs that last given to MouseDown()
- /// </summary>
- public void MousePan(float mouseNowX, float mouseNowY)
- {
- RecallAxisLimits();
- AxesPanPx(MouseDownX - mouseNowX, mouseNowY - MouseDownY);
- }
- /// <summary>
- /// Zoom all axes based on the mouse position now vs that last given to MouseDown()
- /// </summary>
- public void MouseZoom(float mouseNowX, float mouseNowY)
- {
- RecallAxisLimits();
- AxesZoomPx(mouseNowX - MouseDownX, MouseDownY - mouseNowY);
- }
- public void MouseZoomRect(float mouseNowX, float mouseNowY, bool finalize = false)
- {
- float left = Math.Min(MouseDownX, mouseNowX);
- float right = Math.Max(MouseDownX, mouseNowX);
- float top = Math.Min(MouseDownY, mouseNowY);
- float bottom = Math.Max(MouseDownY, mouseNowY);
- float width = right - left;
- float height = bottom - top;
- if (finalize)
- {
- double x1 = XAxis.Dims.GetUnit(left);
- double x2 = XAxis.Dims.GetUnit(right);
- double y1 = YAxis.Dims.GetUnit(bottom);
- double y2 = YAxis.Dims.GetUnit(top);
- ZoomRectangle.Clear();
- //AxisSet(x1, x2, y1, y2);
- //更新zoom区域
- ZoomUnitArea = (x1, x2, y1, y2);
- }
- else
- {
- // TODO: dont require data offset shifting prior to calling this
- ZoomRectangle.Set(left - DataOffsetX, top - DataOffsetY, width, height);
- }
- }
- /// <summary>
- /// 清除预览的ZoomRectangle
- /// </summary>
- public void ClearZoomRectangle()
- {
- ZoomRectangle.Clear();
- }
- /// <summary>
- /// 获取zoom区域
- /// </summary>
- /// <param name="mouseNowX"></param>
- /// <param name="mouseNowY"></param>
- /// <returns></returns>
- [Obsolete]
- public (double xMin, double xMax, double yMin, double yMax) GetMouseZoomRect(float mouseNowX, float mouseNowY)
- {
- float left = Math.Min(MouseDownX, mouseNowX);
- float right = Math.Max(MouseDownX, mouseNowX);
- float top = Math.Min(MouseDownY, mouseNowY);
- float bottom = Math.Max(MouseDownY, mouseNowY);
- float width = right - left;
- float height = bottom - top;
- double x1 = XAxis.Dims.GetUnit(left);
- double x2 = XAxis.Dims.GetUnit(right);
- double y1 = YAxis.Dims.GetUnit(bottom);
- double y2 = YAxis.Dims.GetUnit(top);
- return (x1, x2, y1, y2);
- }
- /// <summary>
- /// Ensure all axes have the same size and offset as the primary X and Y axis
- /// </summary>
- public void CopyPrimaryLayoutToAllAxes()
- {
- foreach (Axis axis in Axes)
- {
- if (axis.IsHorizontal)
- axis.Dims.Resize(Width, DataWidth, DataOffsetX);
- else
- axis.Dims.Resize(Height, DataHeight, DataOffsetY);
- }
- }
- public void LayoutAuto()
- {
- foreach (int xAxisIndex in XAxisIndexes)
- LayoutAuto(xAxisIndex, 0);
- foreach (int yAxisIndex in YAxisIndexes)
- LayoutAuto(0, yAxisIndex);
- }
- private void LayoutAuto(int xAxisIndex, int yAxisIndex)
- {
- // TODO: separate this into distinct X and Y functions (requires refactoring plottable interface)
- bool atLeastOneAxisIsZero = xAxisIndex == 0 || yAxisIndex == 0;
- if (!atLeastOneAxisIsZero)
- throw new InvalidOperationException();
- // Adjust padding around the data area to accommodate title and tick labels.
- //
- // This is a chicken-and-egg problem:
- // * TICK DENSITY depends on the DATA AREA SIZE
- // * DATA AREA SIZE depends on LAYOUT PADDING
- // * LAYOUT PADDING depends on MAXIMUM LABEL SIZE
- // * MAXIMUM LABEL SIZE depends on TICK DENSITY
- //
- // To solve this, start by assuming data area size == figure size and layout padding == 0,
- // then calculate ticks, then set padding based on the largest tick, then re-calculate ticks.
- // axis limits shall not change
- var dims = GetPlotDimensions(xAxisIndex, yAxisIndex, scaleFactor: 1.0);
- var limits = (dims.XMin, dims.XMax, dims.YMin, dims.YMax);
- var figSize = new SizeF(Width, Height);
- // first-pass tick calculation based on full image size
- var dimsFull = new PlotDimensions(figSize, figSize, new PointF(0, 0), limits, scaleFactor: 1,(dims.XMinorTickDistribution, dims.YMinorTickDistribution));
- foreach (var axis in Axes)
- {
- bool isMatchingXAxis = axis.IsHorizontal && axis.AxisIndex == xAxisIndex;
- bool isMatchingYAxis = axis.IsVertical && axis.AxisIndex == yAxisIndex;
- if (isMatchingXAxis || isMatchingYAxis)
- {
- axis.RecalculateTickPositions(dimsFull);
- axis.RecalculateAxisSize();
- }
- }
- // now adjust our layout based on measured axis sizes
- RecalculateDataPadding();
- // now recalculate ticks based on new layout
- var dataSize = new SizeF(DataWidth, DataHeight);
- var dataOffset = new PointF(DataOffsetX, DataOffsetY);
- var dims3 = new PlotDimensions(figSize, dataSize, dataOffset, limits, scaleFactor: 1.0, (dims.XMinorTickDistribution, dims.YMinorTickDistribution));
- foreach (var axis in Axes)
- {
- bool isMatchingXAxis = axis.IsHorizontal && axis.AxisIndex == xAxisIndex;
- bool isMatchingYAxis = axis.IsVertical && axis.AxisIndex == yAxisIndex;
- if (isMatchingXAxis || isMatchingYAxis)
- {
- axis.RecalculateTickPositions(dims3);
- }
- }
- // adjust the layout based on measured tick label sizes
- RecalculateDataPadding();
- }
- private void RecalculateDataPadding()
- {
- Edge[] edges = { Edge.Left, Edge.Right, Edge.Top, Edge.Bottom };
- foreach (var edge in edges)
- {
- float offset = 0;
- foreach (var axis in Axes.Where(x => x.Edge == edge))
- {
- axis.SetOffset(offset);
- offset += axis.GetSize();
- }
- }
- //float padLeft = Axes.Where(x => x.Edge == Edge.Left).Select(x => x.GetSize()).Sum();
- //float padRight = Axes.Where(x => x.Edge == Edge.Right).Select(x => x.GetSize()).Sum();
- //float padBottom = Axes.Where(x => x.Edge == Edge.Bottom).Select(x => x.GetSize()).Sum();
- //float padTop = Axes.Where(x => x.Edge == Edge.Top).Select(x => x.GetSize()).Sum();
- //屏蔽多坐标带来的边界计算
- float padLeft = Margin.left;
- float padRight = Margin.right;
- float padBottom = Margin.bottom;
- float padTop = Margin.top;
- foreach (Axis axis in Axes)
- {
- if (axis.IsHorizontal)
- axis.Dims.SetPadding(padLeft, padRight);//设置上下左右宽度
- else
- axis.Dims.SetPadding(padTop, padBottom);
- }
- }
- }
- }
|