Шпаргалка по ZedGraph. Как можно совмещать графики друг относительно друга

В комменатриях задали вопрос:

Здравствуйте. Проблема такая. Надо нарисовать два графика: один под другим. Делаю это в двух разных контролах. Нужно следующее: надо, чтобы отметки по осям на нижнем графике были строго под соответствующими отметками верхнего графика. проблема же в том, что за счет разного количества знаков у выводимых по оси У данных область отрисовки графиков может быть разной (разумеется, размеры соответсвующих контролов совпадают). Вопрос: можно ли устанавливать неизменной область отрисовки данных или же контролировать ее положение программно?

То есть, допустим, есть ситуация, покзанная на следующем рисунке:

Здесь для наглядности я еще увеличил размер шрифтов на вертикальной оси второго графика. Пример кода ниже показывает как получить вот такой внешний вид окна, когда левые границы графиков совмещены:

Все примеры объединены в одном solution для Visual Studio 2005 и написаны на языке C#, скачать их можно отсюда.

Проект в примере - GraphAlign

public partial class Form1 : Form
{
    public Form1 ()
    {
        InitializeComponent ();

        DrawGraphs ();
    }

    private double f1 (double x)
    {
        if (x == 0)
        {
            return 1;
        }

        return Math.Sin (x) / x;
    }


    private double f2 (double x)
    {
        double k = 1000;

        if (x == 0)
        {
            return k;
        }

        return k * Math.Sin (x) / x;
    }


    private void DrawGraphs ()
    {
        // Получим панели для рисования
        GraphPane pane1 = zedGraph1.GraphPane;
        GraphPane pane2 = zedGraph2.GraphPane;

        // Очистим список кривых на тот случай, если до этого сигналы уже были нарисованы
        pane1.CurveList.Clear ();
        pane2.CurveList.Clear ();

        // Для большей наглядности сделаем так,
        // чтобы шрифты около осей Y на графиках сильно отличались.
        // Тогда сдвиг между графиками будет более заметен.
        pane1.YAxis.Scale.FontSpec.Size = 10;
        pane2.YAxis.Scale.FontSpec.Size = 35;

        // Создадим список точек для двух графиков
        PointPairList list1 = new PointPairList ();
        PointPairList list2 = new PointPairList ();

        double xmin = -50;
        double xmax = 50;

        // Заполняем список точек
        for (double x = xmin; x <= xmax; x += 0.01)
        {
            list1.Add (x, f1 (x));
            list2.Add (x, f2 (x));
        }

        // Создадим кривые
        LineItem myCurve1 = pane1.AddCurve ("", list1, Color.Blue, SymbolType.None);
        LineItem myCurve2 = pane2.AddCurve ("", list2, Color.Blue, SymbolType.None);

        // Вызываем метод AxisChange (), чтобы обновить данные об осях.
        zedGraph1.AxisChange ();
        zedGraph2.AxisChange ();

        // !!! Теперь мы можем изменить область, которая ограничена осями графика.
        // Chart - это экземпляр класса, который отвечает за сам график.
        // В данном случае мы просто происваиваем размеры прямоугольника
        // одного графика другому, в реальности могут понадобиться проверки
        // того, какой график занимает больше места или более умный расчет размеров.
        // Также надо учесть, что графики могут иметь разные размеры по высоте.
        pane1.Chart.Rect = new RectangleF (pane2.Chart.Rect.X,
            pane2.Chart.Rect.Y,
            pane2.Chart.Rect.Width,
            pane2.Chart.Rect.Height);

        // В нашем случае присваивание размеров можно записать более кратко:
        //pane1.Chart.Rect = pane2.Chart.Rect;


        // Обновляем график
        zedGraph1.Invalidate ();
        zedGraph2.Invalidate ();
    }
}

Вернуться к остальным примерам

Вы можете подписаться на новости сайта через RSS, Группу Вконтакте или Канал в Telegram.
5 stars

Рейтинг 5.0/5. Всего 5 голос(а, ов)



nnn 15.12.2011 - 16:49

вопрос

как сделать тоже самое но с использованием одного контрола, но двух pane-ов?

пробовал описаный вариант, при изменении размеров окна все разъезжается

gygenot 15.02.2012 - 17:13

То же самое для одного ZedGraphControl

В событии перерисовки делаете пересчет:

_graph.Paint+=new System.Windows.Forms.PaintEventHandler(this._GraphPaint);
void _GraphPaint(object sender, System.Windows.Forms.PaintEventArgs e) {
	using (System.Drawing.Graphics g = _graph.CreateGraphics()) {
		_sensorPane.Chart.Rect = _sensorPane.CalcChartRect(g);
		_counterPane.Chart.Rect = _counterPane.CalcChartRect(g);
	}
	if (_sensorPane.Chart.Rect.Width > _counterPane.Chart.Rect.Width) {
		_sensorPane.Chart.Rect = new System.Drawing.RectangleF(
			_counterPane.Chart.Rect.X,
			_sensorPane.Chart.Rect.Y,
			_counterPane.Chart.Rect.Width,
			_sensorPane.Chart.Rect.Height);
	}
	else {
		_counterPane.Chart.Rect = new System.Drawing.RectangleF(
			_sensorPane.Chart.Rect.X,
			_counterPane.Chart.Rect.Y,
			_sensorPane.Chart.Rect.Width,
			_counterPane.Chart.Rect.Height);
	}
}

Подписаться на комментарии
Автор:
Тема:
 Ваш комментарий
 
 
Введите код 789