private void UpdateThrottlerUnlocked() { // before measure every element in the chart // we copy the properties that might change while we are updating the chart // this call should be thread safe // ToDo: ensure it is thread safe... viewDrawMargin = chartView.DrawMargin; controlSize = chartView.ControlSize; yAxes = chartView.YAxes.Select(x => x.Copy()).ToArray(); xAxes = chartView.XAxes.Select(x => x.Copy()).ToArray(); measureWorker = new object(); series = chartView.Series.Select(series => { // a good implementation of ISeries<T> // must use the measureWorker to identify // if the points are already fetched. // this way no matter if the Series.Values collection changes // the fetch method will always return the same collection for the // current measureWorker instance series.Fetch(this); return(series); }).ToArray(); legendPosition = chartView.LegendPosition; legendOrientation = chartView.LegendOrientation; legend = chartView.Legend; // ... this is a reference type.. this has no sense tooltipPosition = chartView.TooltipPosition; tooltipFindingStrategy = chartView.TooltipFindingStrategy; tooltip = chartView.Tooltip; //... no sense again... animationsSpeed = chartView.AnimationsSpeed; easingFunction = chartView.EasingFunction; Measure(); }
/// <inheritdoc cref="HoverArea.IsPointerOver(LvcPoint, TooltipFindingStrategy)"/> public override bool IsPointerOver(LvcPoint pointerLocation, TooltipFindingStrategy strategy) { var startAngle = StartAngle % 360; // -0.01 is a work around to avoid the case where the last slice (360) would be converted to 0 also var endAngle = (EndAngle - 0.01) % 360; var dx = CenterX - pointerLocation.X; var dy = CenterY - pointerLocation.Y; var beta = Math.Atan(dy / dx) * (180 / Math.PI); if ((dx > 0 && dy < 0) || (dx > 0 && dy > 0)) { beta += 180; } if (dx < 0 && dy > 0) { beta += 360; } var r = Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)); return(startAngle <= beta && endAngle >= beta && r < Radius); // previously -> startAngle <= beta && endAngle >= beta && r < Radius ? 0 : float.MaxValue; }
/// <inheritdoc cref="GetDistanceToPoint(PointF, TooltipFindingStrategy)"/> public override float GetDistanceToPoint(PointF point, TooltipFindingStrategy strategy) { var startAngle = StartAngle % 360; // -0.01 is a work around to avoid the case where the last slice (360) would be converted to 0 also var endAngle = (EndAngle - 0.01) % 360; var dx = CenterX - point.X; var dy = CenterY - point.Y; var beta = Math.Atan(dy / dx) * (180 / Math.PI); if (dx > 0 && dy < 0 || dx > 0 && dy > 0) { beta += 180; } if (dx < 0 && dy > 0) { beta += 360; } var r = Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2)); return(startAngle <= beta && endAngle >= beta && r < Radius ? 0 : float.MaxValue); }
/// <summary> /// Determines whether the area is trigger by the specified point in the user interface. /// </summary> /// <param name="point">The point.</param> /// <param name="strategy">The strategy.</param> /// <returns> /// <c>true</c> if [is trigger by] [the specified point]; otherwise, <c>false</c>. /// </returns> public abstract bool IsTriggerBy(PointF point, TooltipFindingStrategy strategy);
/// <summary> /// Determines whether the area is trigger by the specified point in the user interface. /// </summary> /// <param name="point">The point.</param> /// <param name="strategy">The strategy.</param> /// <returns> /// <c>true</c> if [is trigger by] [the specified point]; otherwise, <c>false</c>. /// </returns> public abstract float GetDistanceToPoint(PointF point, TooltipFindingStrategy strategy);
/// <summary> /// Determines whether the pointer is over the area. /// </summary> /// <param name="pointerLocation">The pointer location.</param> /// <param name="strategy">The strategy.</param> /// <returns></returns> public abstract bool IsPointerOver(LvcPoint pointerLocation, TooltipFindingStrategy strategy);