Можем ли мы создать трехмерный график в 4 квадрантах в Winform C # .NET? - PullRequest
0 голосов
/ 26 сентября 2018

Я хочу создать трехмерный график в форме 4 квадрантов в C # .NET.На мгновение я мог бы сделать, как показано ниже.Если вы видите, что угол графика начинается с (-150, -200).Я хочу начать с (0,0) и расширить в форму квадранта 4.

enter image description here

Пожалуйста, расскажите мне, как я могу преобразовать этот 3D-график вФорма 4-х квадрантов?

Ниже приведен соответствующий код:

void prepare3dChart(Chart chart, ChartArea ca)
    {
        ca.Area3DStyle.Enable3D = true;  
        Series s = new Series();
        chart.Series.Add(s);
        s.ChartType = SeriesChartType.Bubble;  
        s.MarkerStyle = MarkerStyle.Diamond;
        s["PixelPointWidth"] = "100";
        s["PixelPointGapDepth"] = "1";

        chart.ApplyPaletteColors();

        addTestData(chart);
    }
    void addTestData(Chart chart)
    {
        Random rnd = new Random(9);
        double x = 0, y = 0, z = 0;
        for (int i = 0; i < 100; i++)
        {
            AddXY3d(chart.Series[0], x, y, z);          
            x = Math.Sin(i / 11f) * 88 + rnd.Next(3);
            y = Math.Cos(i / 10f) * 88 + rnd.Next(5);
            z = (Math.Sqrt(i * 2f) * 88 + rnd.Next(6));
        }
    }
    int AddXY3d(Series s, double xVal, double yVal, double zVal)
    {
        int p = s.Points.AddXY(xVal, yVal, zVal);           
        s.Points[p].Color = Color.Transparent;
        return p;
    }
    private void chart1_PostPaint(object sender, ChartPaintEventArgs e)
    {
        Chart chart = sender as Chart;

        if (chart.Series.Count < 1) return;
        if (chart.Series[0].Points.Count < 1) return;

        ChartArea ca = chart.ChartAreas[0];

        List<List<PointF>> data = new List<List<PointF>>();
        foreach (Series s in chart.Series)
            data.Add(GetPointsFrom3D(ca, s, s.Points.ToList(), e.ChartGraphics));

        renderLines(data, e.ChartGraphics.Graphics, chart, true);  
        renderPoints(data, e.ChartGraphics.Graphics, chart, 6);  
    }
    List<PointF> GetPointsFrom3D(ChartArea ca, Series s,
                         List<DataPoint> dPoints, ChartGraphics cg)
    {
        var p3t = dPoints.Select(x => new Point3D((float)ca.AxisX.ValueToPosition(x.XValue),
            (float)ca.AxisY.ValueToPosition(x.YValues[0]),
            (float)ca.AxisY.ValueToPosition(x.YValues[1]))).ToArray();
        ca.TransformPoints(p3t.ToArray());

        return p3t.Select(x => cg.GetAbsolutePoint(new PointF(x.X, x.Y))).ToList();
    }
    void renderLines(List<List<PointF>> data, Graphics graphics, Chart chart, bool curves)
    {
        for (int i = 0; i < chart.Series.Count; i++)
        {
            if (data[i].Count > 1)
                using (Pen pen = new Pen(Color.FromArgb(64, chart.Series[i].Color), 2.5f))
                    if (curves) graphics.DrawCurve(pen, data[i].ToArray());
                    else graphics.DrawLines(pen, data[i].ToArray());
        }
    }

    void renderPoints(List<List<PointF>> data, Graphics graphics, Chart chart, float width)
    {
        for (int s = 0; s < chart.Series.Count; s++)
        {
            Series S = chart.Series[s];
            for (int p = 0; p < S.Points.Count; p++)
                using (SolidBrush brush = new SolidBrush(Color.FromArgb(64, S.Color)))
                    graphics.FillEllipse(brush, data[s][p].X - width / 2,
                                         data[s][p].Y - width / 2, width, width);
        }
    }

Я хочу, чтобы на моем 3D-графике было 4 таких квадранта: enter image description here

Спасибо @TaW.Я правильно понял код.

   void prepare3dChart(Chart chart, ChartArea ca)
    {
        ca.Area3DStyle.Enable3D = true;
        ca.BackColor = Color.Transparent;

        ca.AxisX.Minimum = -300;
        ca.AxisX.Maximum = 300;
        ca.AxisY.Minimum = -300;
        ca.AxisY.Maximum = 300;

        ca.AxisX.Crossing = 0;  // move both axes..
        ca.AxisY.Crossing = 0;  // to the middle

        ca.AxisX.Interval = 50;
        ca.AxisY.Interval = 50;

        ca.AxisX.MajorGrid.LineColor = Color.LightGray;
        ca.AxisY.MajorGrid.LineColor = Color.LightGray;

        chart.Series.Clear();
        Series s = new Series();
        chart.Series.Add(s);
        s.ChartType = SeriesChartType.Bubble;  
        s.MarkerStyle = MarkerStyle.Diamond;
        s["PixelPointWidth"] = "100";
        s["PixelPointGapDepth"] = "1";

        chart.ApplyPaletteColors();

        addTestData(chart);
    }

enter image description here

Ответы [ 2 ]

0 голосов
/ 26 сентября 2018

Graph in 3D Cartesion System

Обновленный код:

  void prepare3dChart(Chart chart, ChartArea ca)
    {
        ca.Area3DStyle.Enable3D = true;
        ca.BackColor = Color.Transparent;

        ca.AxisX.Minimum = -300;
        ca.AxisX.Maximum = 300;
        ca.AxisY.Minimum = -300;
        ca.AxisY.Maximum = 300;

        ca.AxisX.Crossing = 0;  // move both axes..
        ca.AxisY.Crossing = 0;  // to the middle

        ca.AxisX.Interval = 50;
        ca.AxisY.Interval = 50;

        ca.AxisX.MajorGrid.LineColor = Color.LightGray;
        ca.AxisY.MajorGrid.LineColor = Color.LightGray;

        chart.Series.Clear();
        Series s = new Series();
        chart.Series.Add(s);
        s.ChartType = SeriesChartType.Bubble;  
        s.MarkerStyle = MarkerStyle.Diamond;
        s["PixelPointWidth"] = "100";
        s["PixelPointGapDepth"] = "1";

        chart.ApplyPaletteColors();

        addTestData(chart);
    }
0 голосов
/ 26 сентября 2018

Вы можете легко оформить диаграмму, чтобы она выглядела так, перемещая обе оси к середине;это делается путем установки их Crossings:

enter image description here

Используется следующий код:

ChartArea ca = chart1.ChartAreas[0];

ca.BackColor = Color.Transparent;

ca.AxisX.Minimum = -300;
ca.AxisX.Maximum = 300;
ca.AxisY.Minimum = -300;
ca.AxisY.Maximum = 300;

ca.AxisX.Crossing = 0;  // move both axes..
ca.AxisY.Crossing = 0;  // to the middle

ca.AxisX.Interval = 100;
ca.AxisY.Interval = 100;

ca.AxisX.MajorGrid.LineColor = Color.LightGray;
ca.AxisY.MajorGrid.LineColor = Color.LightGray;

Обратите внимание, что реальноеПроблема с MSChart в 3d-режиме всегда остается по оси Z, потому что на самом деле ее нет.(Если кому-то интересно, как можно имитировать его, имея много серий, см. здесь . В моем примере используется 32 серии ..)

Вы можете нарисовать его самостоятельно, используя встроенныев функции для 3D-преобразований (TransformPoints), но это очень утомительная работа, особенно когда речь идет о маркировке ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...