/// <summary> /// Phase: render-components. /// </summary> /// <param name="ls">Layout state.</param> protected void Phase_RenderComponents(LayoutState ls) { foreach (IRequireRender irr in Render_Components.Items /*Components.Where((cc2) => !(cc2 is IChartAxis) && (cc2 is IRequireRender) && !(cc2 is IRequireRenderPostAxesFinalized))*/) { var ctx = ls.RenderFor(irr as ChartComponent, Surface, Components, DataContext); irr.Render(ctx); } }
/// <summary> /// Phase: render post-axes-finalized. /// </summary> /// <param name="ls">Layout state.</param> protected void Phase_RenderPostAxesFinalized(LayoutState ls) { foreach (IRequireRender irr in Render_Components_PostAxis.Items /*Components.Where((cc2) => !(cc2 is IChartAxis) && (cc2 is IRequireRender) && (cc2 is IRequireRenderPostAxesFinalized))*/) { var ctx = ls.RenderFor(irr as ChartComponent, Surface, Components, DataContext); _trace.Verbose($"render-post-axes-finalized {(irr as ChartComponent).Name} rect:{ctx.Area}"); irr.Render(ctx); } }
/// <summary> /// Phase: transforms. /// </summary> /// <param name="ls">Layout state.</param> protected void Phase_Transforms(LayoutState ls) { foreach (IRequireTransforms irt in Transforms_All.Items /*Components.Where((cc2) => cc2 is IRequireTransforms)*/) { var ctx = ls.RenderFor(irt as ChartComponent, Surface, Components, DataContext); _trace.Verbose($"transforms {irt} {ctx.Area}"); irt.Transforms(ctx); } }
/// <summary> /// Phase: after-axes-finalized. /// </summary> /// <param name="ls">Layout state.</param> protected void Phase_AxesFinalized(LayoutState ls) { foreach (var iraaf in AfterAxesFinalized.Items) { var cc = iraaf as ChartComponent; var ctx = ls.RenderFor(cc, Surface, Components, DataContext); _trace.Verbose($"axes-finalized {cc.Name} rect:{ctx.Area}"); iraaf.AxesFinalized(ctx); } }
/// <summary> /// Process incremental updates to a <see cref="DataSource"/>. /// </summary> /// <param name="ncca">The operation. Only <see cref="NotifyCollectionChangedAction.Add"/> and <see cref="NotifyCollectionChangedAction.Remove"/> are supported.</param> /// <param name="ls">Current layout state.</param> /// <param name="ds">The <see cref="DataSource"/> that changed.</param> /// <param name="startIndex">Starting index of update.</param> /// <param name="items">Item(s) involved in the update.</param> protected void IncrementalUpdate(NotifyCollectionChangedAction ncca, LayoutState ls, DataSource ds, int startIndex, IList items) { _trace.Verbose($"incr-update {ncca} '{ds.Name}' {ds} @{startIndex}+{items.Count}"); ls.Type = RenderType.Incremental; // Phase I: reset axes Phase_ResetAxes(); // Phase II: Phase_Layout (skipped) // Phase III: this loop comprises the DSRP foreach (var irdsu in DataSourceUpdates_All.Items.Where(irdsu2 => irdsu2.UpdateSourceName == ds.Name) /* Components.Where(xx => xx is IRequireDataSourceUpdates irdsu2 && irdsu2.UpdateSourceName == ds.Name)*/) { var cc = irdsu as ChartComponent; _trace.Verbose($"incr {ncca} '{cc.Name}' {cc}"); var ctx = ls.RenderFor(cc, Surface, Components, DataContext); switch (ncca) { case NotifyCollectionChangedAction.Add: irdsu.Add(ctx, startIndex, items); break; case NotifyCollectionChangedAction.Remove: irdsu.Remove(ctx, startIndex, items); break; } } // TODO above stage MAY generate additional update events, e.g. to ISeriesItemValues, that MUST be collected and distributed // TODO do it here and not allow things to directly connect to each other, so render pipeline stays under control Phase_AxisLimits(cc2 => cc2 is IRequireDataSourceUpdates irdsu2 && irdsu2.UpdateSourceName == ds.Name && cc2 is IProvideValueExtents); // Phase IV: render non-axis components (IRequireRender) // trigger render on other components since values they track may have changed foreach (IRequireRender irr in Render_NotAnAxis.Items.Where(cc2 => !(cc2 is IRequireDataSourceUpdates irdsu2 && irdsu2.UpdateSourceName == ds.Name)) /*Components.Where((cc2) => !(cc2 is IChartAxis) && !(cc2 is IRequireDataSourceUpdates irdsu2 && irdsu2.UpdateSourceName == ds.Name) && (cc2 is IRequireRender))*/) { var ctx = ls.RenderFor(irr as ChartComponent, Surface, Components, DataContext); irr.Render(ctx); } Phase_AxisLimits(cc2 => !(cc2 is IRequireDataSourceUpdates irdsu2 && irdsu2.UpdateSourceName == ds.Name) && cc2 is IProvideValueExtents); // Phase V: axis-finalized Phase_AxesFinalized(ls); // Phase VI: render axes Phase_RenderAxes(ls); // Phase VII: transforms Phase_Transforms(ls); }
/// <summary> /// Phase: axes have seen all values let them render (IRequireRender). /// </summary> /// <param name="ls">Layout state.</param> protected void Phase_RenderAxes(LayoutState ls) { foreach (var irr in Render_AllAxes.Items /*Axes.Where((cc2) => cc2 is IRequireRender)*/) { var ctx = ls.RenderFor(irr as ChartComponent, Surface, Components, DataContext); _trace.Verbose(() => { var axis = irr as IChartAxis; return($"limits {(irr as ChartComponent).Name} ({axis.Minimum},{axis.Maximum}) r:{axis.Range} rect:{ctx.Area}"); }); irr.Render(ctx); } }