/// <summary> /// Initialize after entering VT. /// </summary> /// <param name="icelc"></param> void IRequireEnterLeave.Enter(IChartEnterLeaveContext icelc) { EnsureAxes(icelc as IChartComponentContext); EnsureValuePath(icelc as IChartComponentContext); Layer = icelc.CreateLayer(); _trace.Verbose($"{Name} enter v:{ValueAxisName} {ValueAxis} c:{CategoryAxisName} {CategoryAxis} d:{DataSourceName}"); if (PathTemplate == null) { if (Theme?.PathTemplate == null) { if (icelc is IChartErrorInfo icei) { icei.Report(new ChartValidationResult(NameOrType(), $"No {nameof(PathTemplate)} and {nameof(Theme.PathTemplate)} was not found", new[] { nameof(PathTemplate), nameof(Theme.PathTemplate) })); } } } AssignFromRef(icelc as IChartErrorInfo, NameOrType(), nameof(PathStyle), nameof(Theme.PathColumnSeries), PathStyle == null, Theme != null, Theme.PathColumnSeries != null, () => PathStyle = Theme.PathColumnSeries ); BindPaths = new Evaluators(CategoryPath, ValuePath, ValueLabelPath); if (!BindPaths.IsValid) { if (icelc is IChartErrorInfo icei) { icei.Report(new ChartValidationResult(NameOrType(), $"ValuePath: must be specified", new[] { nameof(ValuePath) })); } } }
/// <summary> /// Undo effects of Enter(). /// </summary> /// <param name="icelc"></param> void IRequireEnterLeave.Leave(IChartEnterLeaveContext icelc) { _trace.Verbose($"{Name} leave"); BindPaths = null; ValueAxis = null; CategoryAxis = null; icelc.DeleteLayer(Layer); Layer = null; }
/// <summary> /// Ctor. /// </summary> /// <param name="state">Starting state; SHOULD be empty.</param> /// <param name="rc">The recycler.</param> /// <param name="evs">Evaluators.</param> internal RenderState_ValueAndLabel(List <SIS> state, Recycler <EL, SIS> rc, Evaluators evs) : base(state, rc) { #pragma warning disable IDE0016 // Use 'throw' expression if (evs == null) { throw new ArgumentNullException(nameof(evs)); } if (evs.by == null) { throw new ArgumentNullException(nameof(evs.by)); } #pragma warning restore IDE0016 // Use 'throw' expression this.evs = evs; }
/// <summary> /// Initialize after entering VT. /// </summary> /// <param name="icelc"></param> void IRequireEnterLeave.Enter(IChartEnterLeaveContext icelc) { EnsureAxes(icelc as IChartComponentContext); EnsureValuePath(icelc as IChartComponentContext); Layer = icelc.CreateLayer(Segments); _trace.Verbose($"enter v:{ValueAxisName}:{ValueAxis} c:{CategoryAxisName}:{CategoryAxis} d:{DataSourceName}"); AssignFromRef(icelc as IChartErrorInfo, NameOrType(), nameof(PathStyle), nameof(Theme.PathLineSeries), PathStyle == null, Theme != null, Theme.PathLineSeries != null, () => PathStyle = Theme.PathLineSeries ); BindTo(this, nameof(PathStyle), Segments, FrameworkElement.StyleProperty); BindPaths = new Evaluators(CategoryPath, ValuePath, ValueLabelPath); if (!BindPaths.IsValid) { // report } }
void IRequireEnterLeave.Enter(IChartEnterLeaveContext icelc) { EnsureAxes(icelc as IChartComponentContext); Layer = icelc.CreateLayer(); _trace.Verbose($"{Name} enter v:{ValueAxisName} {ValueAxis} c:{CategoryAxisName} {CategoryAxis} d:{DataSourceName}"); BindPaths = new Evaluators(CategoryPath, ValueLabelPath, ColumnStack.Select(cs => cs.ValuePath)); if (!BindPaths.IsValid) { for (int ix = 0; ix < ColumnStack.Count; ix++) { if (String.IsNullOrEmpty(ColumnStack[ix].ValuePath)) { if (icelc is IChartErrorInfo icei) { icei.Report(new ChartValidationResult(NameOrType(), $"ValuePath[{ix}] was not set, NO values are generated", new[] { $"ValuePath[{ix}]" })); } } } } }
/// <summary> /// Initialize after entering VT. /// </summary> /// <param name="icelc"></param> public void Enter(IChartEnterLeaveContext icelc) { EnsureAxes(icelc as IChartComponentContext); Layer = icelc.CreateLayer(); _trace.Verbose($"enter v:{ValueAxisName}:{ValueAxis} c:{CategoryAxisName}:{CategoryAxis} d:{DataSourceName}"); AssignFromRef(icelc as IChartErrorInfo, NameOrType(), nameof(PathStyle), nameof(Theme.PathMarkerSeries), PathStyle == null, Theme != null, Theme.PathMarkerSeries != null, () => PathStyle = Theme.PathMarkerSeries ); AssignFromRef(icelc as IChartErrorInfo, NameOrType(), nameof(ReversePathStyle), nameof(PathStyle), ReversePathStyle == null, true, PathStyle != null, () => ReversePathStyle = PathStyle ); BindPaths = new Evaluators(CategoryPath, OpenValuePath, HighValuePath, LowValuePath, CloseValuePath, ValueLabelPath); if (!BindPaths.IsValid) { if (icelc is IChartErrorInfo icei) { var props = new List <String>(); if (String.IsNullOrEmpty(OpenValuePath)) { props.Add(nameof(OpenValuePath)); } if (String.IsNullOrEmpty(HighValuePath)) { props.Add(nameof(HighValuePath)); } if (String.IsNullOrEmpty(LowValuePath)) { props.Add(nameof(LowValuePath)); } if (String.IsNullOrEmpty(CloseValuePath)) { props.Add(nameof(CloseValuePath)); } icei.Report(new ChartValidationResult(NameOrType(), $"{String.Join(",", props)}: must be specified", props)); } } }
/// <summary> /// Core element creation. /// </summary> /// <param name="index"></param> /// <param name="valuex"></param> /// <param name="valuey"></param> /// <param name="item"></param> /// <param name="recycler"></param> /// <param name="evs"></param> /// <returns></returns> ItemState <Path> ElementPipeline(int index, double valuex, double valuey, object item, Recycler <Path, ItemState <Path> > recycler, Evaluators evs) { var mappedy = ValueAxis.For(valuey); var mappedx = CategoryAxis.For(valuex); var markerx = mappedx + MarkerOffset; _trace.Verbose($"[{index}] {valuey} ({markerx},{mappedy})"); var mk = MarkerTemplate.LoadContent() as Geometry; // TODO allow MK to be other things like (Path or Image). // TODO allow a MarkerTemplateSelector and a value Selector/Formatter // no path yet var el = recycler.Next(null); if (el == null) { return(null); } var shim = new GeometryWithOffsetShim <Geometry>() { PathData = mk }; el.Item2.DataContext = shim; BindTo(shim, nameof(shim.Offset), el.Item2, Canvas.LeftProperty); var cs = evs.LabelFor(item); if (cs == null) { return(new ItemState_Matrix <Path>(index, mappedx, MarkerOffset, mappedy, el.Item2)); } else { return(new ItemStateCustom_Matrix <Path>(index, mappedx, MarkerOffset, mappedy, cs, el.Item2)); } }
internal State(List <ItemState <Path> > sis, Recycler <Path, ItemState <Path> > rc, Evaluators evs) : base(sis, rc) { this.evs = evs; }
/// <summary> /// Prepare the item state, but no <see cref="Geometry"/>. /// </summary> /// <param name="index"></param> /// <param name="valuex"></param> /// <param name="valuey"></param> /// <param name="item"></param> /// <param name="evs"></param> /// <returns></returns> ItemState <Path> ElementPipeline(int index, double valuex, double valuey, object item, Evaluators evs) { var mappedy = ValueAxis.For(valuey); var mappedx = CategoryAxis.For(valuex); var linex = mappedx + CategoryAxisOffset; _trace.Verbose($"{Name}[{index}] v:({valuex},{valuey}) m:({linex},{mappedy})"); var cs = evs.LabelFor(item); if (cs == null) { return(new ItemState <Path>(index, mappedx, CategoryAxisOffset, mappedy, Segments)); } else { return(new ItemStateCustom <Path>(index, mappedx, CategoryAxisOffset, mappedy, cs, Segments)); } }
/// <summary> /// Create the next series state. /// </summary> /// <param name="index"></param> /// <param name="valuex"></param> /// <param name="item"></param> /// <param name="recycler"></param> /// <param name="evs"></param> /// <returns>New instance or NULL.</returns> SeriesItemState ElementPipeline(int index, double valuex, object item, Recycler <Path, SeriesItemState> recycler, Evaluators evs) { var leftx = CategoryAxis.For(valuex); var barx = BarOffset; var rightx = barx + BarWidth; var sis = evs.byl == null ? new SeriesItemState(index, leftx, BarOffset) : new SeriesItemState_Custom(index, leftx, BarOffset, evs.byl.For(item)); for (int ix = 0; ix < evs.bys.Length; ix++) { var valuey = CoerceValue(item, evs.bys[ix]); if (double.IsNaN(valuey)) { continue; } var colbase = valuey >= 0 ? sis.Max : sis.Min; var colend = colbase + valuey; var y1 = ValueAxis.For(colend); var y2 = ValueAxis.For(colbase); var topy = Math.Max(y1, y2); var bottomy = Math.Min(y1, y2); sis.UpdateLimits(y1); _trace.Verbose($"{Name}[{index},{ix}] {valuey} ({barx},{topy}) ({rightx},{bottomy}) sis ({sis.Min},{sis.Max})"); var path = recycler.Next(null); if (path == null) { return(null); } var shim = new GeometryWithOffsetShim <RectangleGeometry>() { PathData = new RectangleGeometry() { Rect = new Rect(new Point(barx, topy), new Point(rightx, bottomy)) } }; path.Item2.DataContext = shim; BindTo(ColumnStack[ix], "PathStyle", path.Item2, FrameworkElement.StyleProperty); // bind offset BindTo(shim, nameof(shim.Offset), path.Item2, Canvas.LeftProperty); UpdateLimits(valuex, sis.Min, sis.Max); sis.Elements.Add(new Tuple <double, Path>(valuey, path.Item2)); } return(sis); }
internal State(List <SeriesItemState> sis, Recycler <Path, SeriesItemState> rc, Evaluators evs) : base(sis, rc) { this.evs = evs; }
/// <summary> /// Core element creation. /// </summary> /// <param name="index"></param> /// <param name="valuex"></param> /// <param name="valuey"></param> /// <param name="item"></param> /// <param name="recycler"></param> /// <param name="evs"></param> /// <returns></returns> ItemState <Image> ElementPipeline(int index, double valuex, double valuey, object item, Recycler <Image, ItemState <Image> > recycler, Evaluators evs) { var mappedy = ValueAxis.For(valuey); var mappedx = CategoryAxis.For(valuex); var markerx = mappedx + MarkerOffset; _trace.Verbose($"[{index}] {valuey} ({markerx},{mappedy})"); // TODO allow a MarkerTemplateSelector and a value Selector/Formatter // no path yet var el = recycler.Next(null); if (el == null) { return(null); } var cs = evs.LabelFor(item); if (cs == null) { return(new ItemState_Matrix <Image>(index, mappedx, MarkerOffset, mappedy, el.Item2)); } else { return(new ItemStateCustom_Matrix <Image>(index, mappedx, MarkerOffset, mappedy, cs, el.Item2)); } }