我们可以在WPF中一起绘制散点图和曲面图吗

时间:2019-09-25 06:07:46

标签: lightningchart

我想在曲面图中显示散点。在闪电图中这可行吗?

谢谢

1 个答案:

答案 0 :(得分:1)

是的,有可能。

请参阅LC WPF演示应用程序中的ExampleSurfaceMouseEditing。 它显示了Surface的每个数据值中的散点,并显示了如何通过用鼠标拖动一个点来修改表面几何Y值。

enter image description here

using System;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Controls;

using Arction.Wpf.Charting;
using Arction.Wpf.Charting.Series3D;
using Arction.Wpf.Charting.Views.View3D;

namespace DemoAppWpf
{
    /// <summary>
    /// 3D surface data modifying by mouse. Illustrates MovePoint feature of View3D. 
    /// </summary>
    public partial class ExampleSurfaceMouseEdit : Example
    {
        /// <summary>
        /// LightningChart component.
        /// </summary>
        LightningChartUltimate _chart;

        /// <summary>
        /// 3D surface.
        /// </summary>
        SurfaceGridSeries3D _surface;

        /// <summary>
        /// Surface verteces.
        /// </summary>
        PointLineSeries3D _points;

        /// <summary>
        /// Mouse state for editing the surface.
        /// </summary>
        bool _editing = false;

        /// <summary>
        /// Index of editable vertice.
        /// </summary>
        int _editingPointIndex;

        /// <summary>
        /// Surface vertices size.
        /// </summary>
        const float NormalPointSize = 1f;

        /// <summary>
        /// Size for selected surface vertices.
        /// </summary>
        const float LargePointSize = 2f;

        /// <summary>
        /// Surface vertices color.
        /// </summary>
        static Color NormalPointColor = Colors.Gray;

        /// <summary>
        /// Color for selected surface vertices.
        /// </summary>
        static Color HighlightedPointColor = Colors.Yellow;

        public ExampleSurfaceMouseEdit()
        {
            InitializeComponent();
            CreateChart();
        }

        /// <summary>
        /// Create chart.
        /// </summary>
        private void CreateChart()
        {
            _chart = new LightningChartUltimate();

            // Disable rendering, strongly recommended before updating chart properties.
            _chart.BeginUpdate();

            _chart.ChartName = "Surface mouse edit chart";
            _chart.Title.Text = "Move mouse over surface, and press mouse button down to start moving a point";

            _chart.ActiveView = ActiveView.View3D;
            View3D view = _chart.View3D;

            // Disable rotation from left button, so it can be used for adjusting points.
            view.ZoomPanOptions.LeftMouseButtonAction = MouseButtonAction3D.None;
            view.ZoomPanOptions.RightMouseButtonAction = MouseButtonAction3D.Rotate;
            view.Camera.RotationX += 20;

            // Create Surface.
            _surface = new SurfaceGridSeries3D(view, Axis3DBinding.Primary, Axis3DBinding.Primary, Axis3DBinding.Primary);
            _surface.ContourLineType = ContourLineType3D.None;
            _surface.Fill = SurfaceFillStyle.PalettedByY;
            _surface.SetRangesXZ(10, 90, 10, 90);
            _surface.MouseInteraction = false;
            _surface.WireframeType = SurfaceWireframeType3D.WireframePalettedByY;
            view.SurfaceGridSeries3D.Add(_surface);

            // Create series of poits to interract with surface. 
            _points = new PointLineSeries3D(_chart.View3D, Axis3DBinding.Primary, Axis3DBinding.Primary, Axis3DBinding.Primary);
            _points.ShowInLegendBox = false;
            _points.PointStyle.Shape3D = PointShape3D.Sphere;
            _points.PointStyle.Size3D.SetValues(1, 1, 1);
            _points.Material.DiffuseColor = Color.FromArgb(255, 120, 120, 120);
            _points.MouseInteraction = true;
            _points.MouseHighlight = MouseOverHighlight.None;
            _points.LineVisible = false;
            _points.IndividualPointColors = true;
            _points.IndividualPointSizes = true;
            view.PointLineSeries3D.Add(_points);

            SurfacePoint[,] surfaceData;
            SeriesPoint3D[] pointsData;

            // Set data for surface and points 
            CreateData(out surfaceData, out pointsData, _surface.RangeMinX, _surface.RangeMaxX, _surface.RangeMinZ, _surface.RangeMaxZ);
            _surface.Data = surfaceData;
            _points.Points = pointsData;

            // Registrate mouse events.
            _chart.PreviewMouseLeftButtonDown += _chart_MouseDown;
            _chart.PreviewMouseLeftButtonUp += _chart_MouseUp;
            _chart.MouseMove += _chart_MouseMove;

            // Allow chart rendering.
            _chart.EndUpdate();

            (Content as Grid).Children.Add(_chart);

            base.ChartsCreated(_chart);
        }

        private void _chart_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (_editingPointIndex >= 0)
                _editing = true;
        }

        private void _chart_MouseUp(object sender, MouseButtonEventArgs e)
        {
            _editing = false;

            ResetPointsToNormalState();
            _editingPointIndex = -1;
        }

        private void _chart_MouseMove(object sender, MouseEventArgs e)
        {
            // Right mouse button is set for Rotation; if it is pressed no further execution of the code here is required.
            if (e.RightButton == MouseButtonState.Pressed)
                return;

            var position = e.GetPosition(_chart);

            if (_editing)
            {
                _chart.BeginUpdate();

                PointDouble3D startPoint = new PointDouble3D(_points.Points[_editingPointIndex].X, _points.Points[_editingPointIndex].Y, _points.Points[_editingPointIndex].Z);

                // Move the point in Y dimension 
                var movedPoint = _chart.View3D.MovePoint(Axis3DBinding.Primary, new PointDouble3D(startPoint.X, startPoint.Y, startPoint.Z),
                    new PointFloatXY((float)position.X, (float)position.Y), MovementDimension.Y);

                _points.Points[_editingPointIndex].X = movedPoint.X;
                _points.Points[_editingPointIndex].Y = movedPoint.Y;
                _points.Points[_editingPointIndex].Z = movedPoint.Z;
                _points.InvalidateData();

                _surface.Data[_editingPointIndex / _surface.SizeZ, _editingPointIndex % _surface.SizeZ].Y = movedPoint.Y;
                _surface.InvalidateData();

                _chart.EndUpdate();
            }
            else
            {
                int pointIndex = -1;
                bool overLine = false;
                bool overPoint = false;
                if (_points.IsMouseOver((int)position.X, (int)position.Y, out pointIndex, out overLine, out overPoint, true))
                {
                    _chart.BeginUpdate();

                    if (pointIndex != _editingPointIndex && _editingPointIndex >= 0)
                        ResetPointsToNormalState();

                    _editingPointIndex = pointIndex;
                    _points.Points[pointIndex].SizeFactor = LargePointSize;
                    _points.Points[pointIndex].Color = HighlightedPointColor;
                    _points.InvalidateData();

                    _chart.EndUpdate();
                }
                else
                {
                    ResetPointsToNormalState();
                }
            }
        }

        /// <summary>
        /// Reset points to normal state 
        /// </summary>
        void ResetPointsToNormalState()
        {
            if (_editingPointIndex >= 0)
            {
                int pointCount = _points.Points.Length;
                for (int i = 0; i < pointCount; i++)
                {
                    _points.Points[i].SizeFactor = NormalPointSize;
                    _points.Points[i].Color = NormalPointColor;
                }
                _points.InvalidateData();
            }
        }

        /// <summary>
        /// Create data array for surface.
        /// <param name="pointsData">Points</param>
        /// <param name="surfaceData">Surface data</param>
        /// <param name="xMax">X Max</param>
        /// <param name="xMin">X Min</param>
        /// <param name="zMax">Z Max</param>
        /// <param name="zMin">Z Min</param>
        /// </summary>
        void CreateData(out SurfacePoint[,] surfaceData, out SeriesPoint3D[] pointsData, double xMin, double xMax, double zMin, double zMax)
        {
            int xCount = 50;
            int zCount = 30;
            surfaceData = new SurfacePoint[xCount, zCount];
            pointsData = new SeriesPoint3D[xCount * zCount];
            double xStep = (xMax - xMin) / (double)(xCount - 1);
            double zStep = (zMax - zMin) / (double)(zCount - 1);
            double y;

            for (int xIndex = 0; xIndex < xCount; xIndex++)
            {
                for (int zIndex = 0; zIndex < zCount; zIndex++)
                {
                    y = 30 + 20.0 * Math.Sin(0.01 * (double)(xIndex * zIndex) + 0.2);

                    if ((xIndex + 5) % 20 == 0)
                        y += 20;

                    if ((zIndex + 5) % 20 == 0)
                        y += 30;

                    surfaceData[xIndex, zIndex].Y = y;
                    pointsData[xIndex * zCount + zIndex] = new SeriesPoint3D(xMin + (double)xIndex * xStep, y, zMin + (double)zIndex * zStep, NormalPointColor, NormalPointSize);
                }
            }
        }

        public override void Dispose()
        {
            // Don't forget to clear chart grid child list.
            (Content as Grid).Children.Clear();

            if (_chart != null)
            {
                _chart.Dispose();
                _chart = null;
            }

            // Disposing of unmanaged resources done.
            base.DisposedOf();
        }
    }
}
相关问题