/// <summary>
 /// Perform a full layout and rendering pass.
 /// At least ONE component reported as dirty.
 /// The full rendering sequence is: axis-reset, layout, render, transforms.
 /// SETs <see cref="LayoutState.Type"/> to FALSE.
 /// </summary>
 /// <param name="ls">Layout state.</param>
 protected void FullLayout(LayoutState ls)
 {
     ls.Type = RenderType.Full;
     ls.InitializeLayoutContext(Padding);
     _trace.Verbose($"full starting {ls.LayoutRect}");
     // Phase I: reset axes
     Phase_ResetAxes();
     // Phase II: claim space (IRequireLayout)
     Phase_Layout(ls);
     // Phase III: data source rendering pipeline (IDataSourceRenderer)
     Phase_RenderDataSources(ls);
     //Phase_AxisLimits((cc2) => cc2 is DataSeries && (cc2 is IProvideValueExtents));
     Phase_AxisLimits(ValueExtents_DataSeries.Items);
     // Phase IV: render non-axis components (IRequireRender)
     Phase_RenderComponents(ls);
     //Phase_AxisLimits((cc2) => !(cc2 is DataSeries) && (cc2 is IProvideValueExtents));
     Phase_AxisLimits(ValueExtents_NotDataSeries.Items);
     // Phase V: axes finalized
     Phase_AxesFinalized(ls);
     // Phase VI: post-axes finalized
     Phase_RenderPostAxesFinalized(ls);
     // Phase VII: render axes (IRequireRender)
     Phase_RenderAxes(ls);
     // Phase VIII: configure all transforms
     Phase_Transforms(ls);
 }
 /// <summary>
 /// Adjust layout and transforms based on size change.
 /// SETs <see cref="LayoutState.Type"/> to <see cref="RenderType.TransformsOnly"/>.
 /// </summary>
 /// <param name="ls">Layout state.</param>
 protected void TransformsLayout(LayoutState ls)
 {
     ls.Type = RenderType.TransformsOnly;
     ls.InitializeLayoutContext(Padding);
     _trace.Verbose($"transforms-only starting {ls.LayoutRect}");
     Phase_Layout(ls);
     Phase_Transforms(ls);
 }