Последние изменения - Поиск:
RSS блога RSS блога

Начало

Блог

Программки

    Google+

Плагины

Программирование

Фото

Контакты

Я в твиттере Я в ЖЖ

Шпаргалка по ZedGraph

Оглавление

  1. Как построить график y = f(x) по точкам
  2. Как нарисовать несколько графиков в одних осях
  3. Как изменить пределы отображаемой области по осям
  4. Как нарисовать график в виде отдельных не связанных точек (scatter graph)
  5. Как спрятать горизонтальную линию по уровню y = 0 на графике
  6. Как нарисовать график по вертикали
  7. Как на графике рисовать линии, стрелки и писать текст
  8. Как на одном ZedGraphControl нарисовать несколько графиков
  9. Как задавать расположение отдельных графиков на MasterPane
  10. Как включить отображение сетки и изменять ее внешний вид
  11. Что такое RadarPointList
  12. Как выводить постоянно обновляемые данные
  13. Гистограммы и текстовые оси
  14. Как менять размеры шрифтов у различных элементов графика
  15. Как вернуть масштабу по осям значение по умолчанию
  16. Как рисовать пунктирные и штрихпунктирные линии
  17. Как добавлять и удалять кривые
  18. Как не отображать некоторые кривые в легенде
  19. Как использовать всплывающие подсказки
  20. Как сделать так, чтобы столбцы в гистограмме прилегали друг к другу вплотную
  21. Что такое кластеры и как их использовать в гистограммах
  22. Как изменять существующие кривые
  23. Как управлять отображением больших и маленьких чисел на осях
  24. Как узнать координаты мыши в системе координат графика
  25. Как узнать координаты точки на кривой, ближайшей к точке клика
  26. Как на одном графике нарисовать несколько кривых с разными осями Y
  27. Как можно совмещать графики друг относительно друга
  28. Как изменять фон текстовых объектов
  29. Как ограничить масштабирование графика
  30. Как использовать оси в календарном формате
  31. Как создать гистограмму с использованием календарного типа оси
  32. Как устранить промежутки между данными на календарной оси
  33. Как изменять формат меток на осях
  34. Как создать разрывы на кривой
  35. Как изменять шаг вывода рисок по осям
  36. Как более гибко форматировать надписи по осям
  37. Как зафиксировать размер шрифтов
  38. Как уменьшить количество точек, отображаемых на графике
  39. Как менять заголовки осей и графика
  40. Как установить логарифмический масштаб оси
  41. Как при автоматическом подборе масштаба учитывать только видимую часть графика
  42. Как поворачивать метки под осями
  43. Как с помощью мышки перемещать точки на графике
  44. Как с помощью мышки выделять кривые
  45. Как менять цвета различных элементов графика
  46. Как сделать так, чтобы при перемещении и масштабировании одного графика одновременно перемещался и масштабировался другой график
  47. Как задавать координаты графических объектов относительно видимой части графика
  48. Как нарисовать гистограмму с перекрывающимися столбцами
  49. Как нарисовать горизонтальную гистограмму
  50. Как сохранить нарисованные графики в файл в виде картинки
  51. Как пересчитывать координаты из оконной системы координат в систему координат графика и наоборот
  52. Как изменить контекстное меню
  53. Как запретить контролу менять курсор

Введение

ZedGraph - это очень удобный компонент для рисования графиков под .NET Framework, но, к сожалению, документация к этому контролу довольно скудная. Поэтому здесь я решил сделать что-то вроде шпаргалки или, если угодно, HOWTO по компоненту ZedGraph.

То, что находится дальше на этой странице - это не справка, а просто небольшие примеры, показывающие как использовать какую-нибудь одну из возможностей контрола. Все основные пояснения по использованию той или иной возможности будут написаны в виде комментариев к коду.

Структура всех примеров одинаковая - главное окно, внутри которого располагается экземпляр класса ZedGraphControl. Имя экземпляра класса - zedGraph. В конструкторе окна вызывается метод DrawGraph(), внутри которого и происходит заполнение компонента данными. Поэтому в примерах ниже будут приводиться только функции DrawGraph() и дополнительные функции, которые будут зависеть от примера.

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

Эта шпаргалка со временем будет пополняться новыми примерами.

Краткие сведения о ZedGraph и полезные ссылки

Официальный сайт ZedGraph - http://zedgraph.org
Требования - .NET 1.1 (для версии 4.x) или .NET 2.0 (для версии 5.x)
Страница документации - http://zedgraph.sourceforge.net/documentation/default.html
Еще есть неплохой материал на сайте CodeProject, с которого хорошо начинать изучение этого компонента - http://www.codeproject.com/KB/graphics/zedgraph.aspx

Пожалуйста, оцените материал

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



Daisy 05.12.2008 - 03:05

Большое спасибо, очень помогли! happy smiley

Jenyay 05.12.2008 - 09:22

Очень приятно :)

Anton 18.12.2008 - 12:24

А как установить ширину

никак не получается задать ширину отдельного GraphPane в MasterPane. Как это сделать?
У меня три столбиковых диаграммы и в каждой разное количество баров, надо, чтобы в отдельная диаграмма занимала место (в ширину) в зависимости от количества баров в ней относительно других в этомже MasterPane

Jenyay 18.12.2008 - 21:30

Anton,
С MasterPane я как раз разбираюсь, но по Вашему вопросу пока ничего сказать не могу. В ближайшее время выложу пример с MasterPane, заодно посмотрю можно ли там вручную задавать размеры и расположение отдельных Pane.

Anton 19.12.2008 - 13:37

Короче сам разобрался

В этой функции вычисляю размер необходимый для выделения под GraphPane

Private Function CalcPaneWidth(ByVal allElementsCnt As Single, ByVal paneElementsCnt As Single, ByVal panesWidth As Single) As Single
        Dim ReturnValue As Single = 0
        Dim OnePercent As Double = (panesWidth / allElementsCnt) 'Ширину MasterPane делю на общее количесво баров
        Dim paneWidthPercent As Double = (paneElementsCnt * OnePercent) 'Умножаю на количество баров в конкретном GraphPane
        ReturnValue = CType(paneWidthPercent, Single)
        Return ReturnValue
    End Function

В коде где заполняю графики пишу

SmallRect = mPane.Rect
        SmallRect.Y = 45
        SmallRect.Height = mPane.Rect.Height - 45

        For PaneIndex = 0 To mPane.PaneList.Count - 1

            mPane.Item(PaneIndex).XAxis.IsVisible = True
            mPane.Item(PaneIndex).XAxis.Type = AxisType.Text
            'curPane.YAxis.Type = AxisType.Exponent
            mPane.Item(PaneIndex).XAxis.MajorGrid.IsVisible = True 'Сетка по X
            mPane.Item(PaneIndex).YAxis.MajorGrid.IsVisible = True 'Сетка по Y
            mPane.Item(PaneIndex).Legend.IsVisible = False
            mPane.Item(PaneIndex).YAxis.Scale.FontSpec.Size = 14

            mPane.Item(PaneIndex).Border.IsVisible = False



            mPane.Item(PaneIndex).BaseDimension = 4.0F

            mPane.Item(PaneIndex).Margin.All = 3
            mPane.Item(PaneIndex).Margin.Top = 8
            mPane.Item(PaneIndex).IsFontsScaled = False
            If PaneIndex = 0 Then
                SmallRect.X = 5
                SmallRect.Width = CalcPanewidth(AllElementsCount, mPane.Item(PaneIndex).CurveList.Item(0).Points.Count, mPane.Rect.Width) + 20

            ElseIf PaneIndex = mPane.PaneList.Count - 1 Then
                SmallRect.X = SmallRect.X + mPane.Item(PaneIndex - 1).Rect.Width
                SmallRect.Width = mPane.Rect.Width - SmallRect.X
                mPane.Item(PaneIndex).YAxis.MinSpace = 0
            Else
                SmallRect.X = SmallRect.X + mPane.Item(PaneIndex - 1).Rect.Width
                SmallRect.Width = CalcPanewidth(AllElementsCount, mPane.Item(PaneIndex).CurveList.Item(0).Points.Count, mPane.Rect.Width)
                mPane.Item(PaneIndex).YAxis.MinSpace = 0
            End If
            mPane.Item(PaneIndex).ReSize(CreateGraphics(), SmallRect)

        Next PaneIndex

        mPane.Legend.FontSpec.Size = 16

        mPane.BaseDimension = 12.0F
        mPane.Margin.Top = 22
        mPane.Margin.Left = 5
        mPane.Margin.Right = 35
        mPane.Margin.Bottom = 1
        mPane.Legend.Location.Height = mPane.Legend.Location.Height + 5
        mPane.Legend.Position = LegendPos.InsideTopRight
        mPane.Legend.FontSpec.Size = 25
        Dim r(0) As Integer

        mPane.IsFontsScaled = True

        'Это переопределяло размеры раньше
        'mPane.SetLayout(CreateGraphics(), PaneLayout.SingleRow)

        'Заполняем значениями

        Me.ZedGraphControl1.IsShowPointValues = True
        Me.ZedGraphControl1.AxisChange()
        Me.ZedGraphControl1.Invalidate()

Конечно часть кода вырезал но весь смысл в определении

 mPane.Item(PaneIndex).ReSize(CreateGraphics(), SmallRect)

Результат динамически настраиваемая ширина конечно код сырой но работает

Anton 19.12.2008 - 13:50

Вот фотки того что получилось

Jenyay 19.12.2008 - 14:13

Anton, а красиво смотрится :)
Если Вы не против, то я сделаю на основе Вашего примера пример для шпаргалки.

Vardes 19.12.2008 - 22:24

Такой вопрос, как построить несколько графиков один под другим, не кидая на форму новых компонентов...
Заранее спасибо...

Vardes 19.12.2008 - 23:28

Ещё возникли сложности:
PointPairList работает только с типом double, возникает вопрос, как сделать,чтобы по оси Х располагались строковые переменные, а по оси Y double и именно в линейных графиках?
К примеру Саша - 5 Коля - 8 Вася - 10...

Jenyay 20.12.2008 - 08:56

Vardes,

По поводу нескольких графиков - надо смотреть в сторону MasterPane, скоро я выложу пример такого использования.

А чтобы присвоить меткам на оси строковые значения есть свойство

Pane.XAxis.Scale.TextLabels

Только надо не забыть установить

Pane.XAxis.Type = AxisType.Text;

Anton 22.12.2008 - 07:18

Не жалко

"а красиво смотрится :) Если Вы не против, то я сделаю на основе Вашего примера пример для шпаргалки. "

Да пожалуйста пользуйся winking smiley

sWitch_2009 22.04.2009 - 10:24

Как изменить формат подписей

BarItem.CreateBarLabels(myPane, false, "f0");
Я так понимаю, f0 делает подписи типа int, цифры после запятой обрезаются. А мне надо... для типа double как это будет?

Jenyay 22.04.2009 - 10:31

To sWitch_2009:

На сколько я понял из документации (сам я эту фичу не использовал), последний параметр в CreateBarLabels использует те же строки форматирования, что и double.ToString(). "f0" как раз и означает дробные числа, но после запятой оставить 0 цифр, поэтому можно попробовать что-нибудь вроде "f3" и т.п.

sWitch_2009 23.04.2009 - 11:27

Большое спасибо!!!

Все гениальное просто!happy smiley

sWitch_2009 23.04.2009 - 12:10

Проблема с обновлением графиков

При обновлении
zgc.Invalidate();
следующий график накладывается почему-то на предыдущий, приходится перезапускать форму, чтоб он обновился в соответствии с новыми данными.
Подскажите, пожалуйста, если есть от этого лекарство.

Jenyay 23.04.2009 - 19:35

Это уже надо смотреть на остальной код, так сходу что-то сказать трудно.

sWitch_2009 24.04.2009 - 12:09

Обновление графиков

Если взять хоть даже код с
http://zedgraph.org/wiki/index.php?title=Multi-Colored_Bar_Demo
для построения гистограммы, организовать загрузку диаграммы не сразу при загрузке формы, а по кнопке на этой форме, и в конце кода функции CreateGraph_GradientByZBars( ZedGraphControl z1 ) запросить ZedGraphControl.Invalidate();, то при повторном нажатии кнопки графики будут накладываться друг на друга.

Jenyay 24.04.2009 - 13:38

To sWitch_2009:

Он не наезжает, он просто создает каждый раз новые полоски для Bar. Чтобы этого не было, добавьте вторую строку:

GraphPane myPane = z1.GraphPane;
myPane.CurveList.Clear ();

sWitch_2009 27.04.2009 - 09:25

Спасибо большое!!!

Как хорошо, что вы тут есть!

Никита 12.05.2009 - 16:05

А можно ли найти точки пересечения

А можно ли найти точки пересечения двух Curve средствами самого Zedgraph?

barter 04.06.2009 - 08:35

отменить масштабирование шрифтов

не могу побороть вот это:
если привязать контрол к форме и изменять размер формы, то в месте со всей графикой масштабируются и шрифты заголовков и подписей осей.
подскажите как этого избежать плиз...

Malicious 10.06.2009 - 17:53

отображение промежутка

Здравствуйте. Моя программа отображает показания датчика в зависимости от его положения на прямой, данный поступают непрерывно. Мне необходимо чтобы отображался участок кривой с последними 500 значениями, как можно реализовать это? И еще как лучше организовать перерисовку кривой, если количество значений порядка 10 000 000, я предполагаю что каждый раз перерисовывать кривую будет очень медленно.

Jenyay 10.06.2009 - 20:05

Malicious, я бы не стал сваливать работу по отсечению лишних показаний на ZedGraph, а создал бы что-то вроде списка с конечной длиной, где бы хранились последние показания.

Malicious 11.06.2009 - 09:01

Спасибо за совет

Пробовал использовать Queue, но не получается отрисовать кривую, ZedGraph ругается на несоответствие типов. Как правильно это организовать - не знаю. Поэтому пока что использую способ
Pane.XAxis.Scale.Min = x-500;
Pane.XAxis.Scale.Max = x;
Jenyay не могли бы вы подсказать как мне правильно использовать Queue

Jenyay 11.06.2009 - 09:32

Да, в принципе, и Queue можно использовать. Только нужно по одной точке добавлять в кривую графика. Примерно как это сделано в первом примере здесь.

Malicious 11.06.2009 - 10:35

Ни как не могу разобраться с Queue( Не могли бы вы привести кусочек такого кода для примера?

Jenyay 11.06.2009 - 17:55

Malicious, а создайте, пожалуйста, на форуме соответствующую тему. Просто здесь комментарии разрослись, уже неудобно что-то писать. Я ближе к вечеру постараюсь какой-нибудь пример сделать.

v567 18.06.2009 - 22:47

Проблемы быстрдействия ZedGraph

У меня вот какая проблема.
Необходимо отображать точку в реальном режиме сразу же после ее поступления в программу.
Для чистоты эксперимента слепил простенький тест с ZedGraph.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ZedGraph;

namespace Test
{
    public partial class TestForm : Form
    {
        public GraphPane myP;
        long m1, m2;
        LineItem mySerP;


        public TestForm()
        {
            InitializeComponent();
        }


        // Изменение ZedGraph с учетом изменения размеров формы
        private void SetSize()
        {
            zg6.Location = new Point(0, 0);
            zg6.Size = new Size(this.ClientRectangle.Width, this.ClientRectangle.Height);
            zg6.Refresh();
        }


        // Изменение размеров ФМ06
        private void F06_Resize(object sender, EventArgs e)
        {
            SetSize();         // Изменение размеров ZedGrpah
        }


        private void Form1_Shown(object sender, EventArgs e)
        {
            SetSize();                                                 // Изменение размеров ZedGrpah
            this.Move += new System.EventHandler(this.F06_Resize);
            this.Resize += new System.EventHandler(this.F06_Resize);
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            SetSize();

            myP = zg6.GraphPane;

            // Убираем всякий мусор (титлы и надписи по осям)
            myP.Title.FontSpec.Size = 6;
            myP.Title.Text = " ";           // резервируем поле сверху графика
            myP.XAxis.Title.Text = "";
            myP.YAxis.Title.Text = "";

            // Настройка шрифта осей
            myP.XAxis.Scale.FontSpec.Size = 9;
            myP.YAxis.Scale.FontSpec.Size = 9;
            myP.XAxis.Scale.FontSpec.IsBold = true;
            myP.YAxis.Scale.FontSpec.IsBold = true;

            // Градиентная заливка графика
            myP.Chart.Fill = new Fill(Color.White, Color.Gray, 45F);
            // Градиентная заливка коймы графика
            myP.Fill = new Fill(Color.White, Color.Gray, 45F);

            myP.XAxis.Scale.Min = 0;
            myP.XAxis.Scale.Max = 500;
            myP.YAxis.Scale.Min = 0;
            myP.YAxis.Scale.Max = 500;
            myP.AxisChange();               // перерисовка ZedGraph

            if (mySerP != null) mySerP.Clear();

            double[] XX = new double[1]; double[] YY = new double[1];
            XX[0] = 0; YY[0] = 0;
            mySerP = myP.AddCurve("", XX, YY, Color.DarkBlue);

            // Определяем серии измерений
            mySerP.Symbol.Type = SymbolType.Circle;
            // делаем линии соединяющие точки невидимыми
            mySerP.Line.IsVisible = false;
            // толщина линии 2 пикселя
            mySerP.Line.Width = 10;
            // точки в виде сплошных кругов
            mySerP.Symbol.Fill.Type = FillType.Solid;
            // определяем размер точек
            mySerP.Symbol.Size = 4;
        }


        private void Tm()
        {
            double r;

            m2 = DateTime.Now.Ticks;
            r = 0.0000001 * (m2 - m1);
            label1.Text = "Время выполнения= " + r.ToString("0.0") + "сек";
            zg6.Refresh();
            label1.Refresh();
        }


        private void button1_Click(object sender, EventArgs e)
        {
            double x, y, Sg;

            m1 = DateTime.Now.Ticks;
            Sg = 0.0; x = 0.0;
            while (Sg < (12.0 * Math.PI))
            {
                y = 250.0  + (250.0 * Math.Sin(Sg));
                mySerP.AddPoint((int)(x), (int)(y));
                Sg += (0.5 * 6.0 * Math.PI) / 250.0;
                x += 0.5;

                Tm();
            }
        }
    }
}

Если производить отрисовку поточечно (как в указанном тесте), то тест выполняется слишком долго.

Можно ускорить его работу, например как в примере 2 (заменив Refresh() на Invalidate()),

private void Tm()
        {
            double r;

            m2 = DateTime.Now.Ticks;
            r = 0.0000001 * (m2 - m1);
            label1.Text = "Время выполнения= " + r.ToString("0.0") + "сек";
            //zg6.Refresh();
            zg6.Invalidate();
            label1.Refresh();
        }
 

либо как в примере 3 (перенеся Refresh() из Tm() в конец цикла отрисовки синусоиды.

private void button1_Click(object sender, EventArgs e)
        {
            double x, y, Sg;

            m1 = DateTime.Now.Ticks;
            Sg = 0.0; x = 0.0;
            while (Sg < (12.0 * Math.PI))
            {
                y = 250.0  + (250.0 * Math.Sin(Sg));
                mySerP.AddPoint((int)(x), (int)(y));
                Sg += (0.5 * 6.0 * Math.PI) / 250.0;
                x += 0.5;

                Tm();
            }
            zg6.Refresh();
            // либо zg6.Invalidate();
        }

Однако в этих случаях отрисовка точек производится сразу всех скопом, а их необходимо
отображать одну за другой.

Подскажите как можно решить данную проблему и существенно ускорить работу данного теста.

Jenyay 19.06.2009 - 10:40

v567, Вообще, если нужно рисовать точки последовательно, то лучше для этого использовать таймер, на каждый тик которого добавлять одну точку в список и выводить из все разом. Иначе при том сделано сейчас, скорость вывода точек будет зависеть от скорость компьютера, на котором выполняется программа.

v567 19.06.2009 - 13:18

Таймер не подходит, поскольку работает с определенной дискретностью.
Задача же заключается в том, что необходимо мгновенно отобразить ассинхронно поступающие данные безо всяких задержек. В идеале нужно чтобы точка на графике отображалась сразу же после добавления (например так как это делает TChart в Delphi), а не после вызова
Refresh (или связки Invalidate + Update), который обновляет всю область графика.
Если брать TChart в Delphi, то команда Chart.Series.AddXY сразу же отображает точку на графике.
Аналогичной в ZedGraph процедуре AddPoint для отображения точки почему то требуется дополнительный вызов Refresh.
В результате TChart работает значительно быстрее, чем ZedGraph.

Так как на экране необходимо видеть точку сразу же после прихода данных возникает вопрос: как ускорить поточечную отрисовку в ZedGraph?
Т.е. после прихода точку её нужно сразу же оторазить ничего не дожидаясь и не ожидая прихода других данных.

Jenyay 19.06.2009 - 13:31

А почему тогда нельзя сохранять все точки, которые нужно нарисовать, и рисовать их все разом? Когда появится новая точка, пользователю будет казаться, что они только что добавились, ведь старые останутся на месте.

v567 19.06.2009 - 14:34

Почему нельзя рисовать старые точки? Их можно рисовать хоть по десять проходов. Просто скорость отрисовки падает в разы. Одно дело одну точку нарисовать (предположительно как в TChart), а другое дело перерисовать всю область графика (как в Zedgraph после Refresh). Как бы там ни было, но аналогичный тест в delphi работает менее секунды zedgraph же пашет секунд 15.

Jenyay 19.06.2009 - 14:49

Значит я не правильно понял что требуется. Надо будет поиграться с Вашим примером.

v567 19.06.2009 - 15:22

Проект можно взять по адресу: http://linuxforum.ru/index.php?showtopic=90260

 23.06.2009 - 18:21

cool smiley

v567 24.06.2009 - 12:54

В поисках решения проблемы ускорения работы ZedGraph обнаружил интересную особенность метода Invalidate(): обновление производится после окончания работы потока его вызывающего. Для учета этой особенности изменил вышеуказанный тест, введя фоновый поток. В результате обновление производится корректно (именно так как надо, т.е. с помощью Invalidate() и при этом поточечно). Лучшая скорость работы теста с фоновым потоком составила 13.6 сек
(старого - 15.4 сек).
В связи с этим напрашивается вывод о том, что это и есть потолок быстродействия и библиотеки ZedGraph и платформы .NET в целом. Что в свою очередь означает, что быстродействие .NET значительно уступает быстродействию Win32. Напоминаю, что аналогичная поточечная отрисовка с помощью компонента TChart в Delphi занимает менее 1 секунды.

Текст теста с фоновым потоком:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using ZedGraph;

namespace Test
{
    public partial class TestForm : Form
    {
        Thread FProc;
        public GraphPane myP;
        long m1, m2;
        LineItem mySerP;
        double x, y, Sg;


        public TestForm()
        {
            InitializeComponent();
            Vars.ObjTstF = this;
        }


        // Изменение ZedGraph с учетом изменения размеров формы
        private void SetSize()
        {
            zg6.Location = new Point(0, 0);
            zg6.Size = new Size(this.ClientRectangle.Width, this.ClientRectangle.Height);
            zg6.Refresh();
        }


        // Изменение размеров формы
        private void F06_Resize(object sender, EventArgs e)
        {
            SetSize();         // Изменение размеров ZedGrpah
        }


        private void Form1_Shown(object sender, EventArgs e)
        {
            SetSize();         // Изменение размеров ZedGrpah
            this.Move += new System.EventHandler(this.F06_Resize);
            this.Resize += new System.EventHandler(this.F06_Resize);
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            FProc = new Thread(FTimer.FonProc);

            SetSize();

            myP = zg6.GraphPane;

            // Убираем всякий мусор (титлы и надписи по осям)
            myP.Title.FontSpec.Size = 6;
            myP.Title.Text = " ";
            myP.XAxis.Title.Text = "";
            myP.YAxis.Title.Text = "";

            // Настройка шрифта осей
            myP.XAxis.Scale.FontSpec.Size = 9;
            myP.YAxis.Scale.FontSpec.Size = 9;
            myP.XAxis.Scale.FontSpec.IsBold = true;
            myP.YAxis.Scale.FontSpec.IsBold = true;

            // Градиентная заливка графика
            myP.Chart.Fill = new Fill(Color.White, Color.Gray, 45F);
            // Градиентная заливка коймы графика
            myP.Fill = new Fill(Color.White, Color.Gray, 45F);

            myP.XAxis.Scale.Min = 0;
            myP.XAxis.Scale.Max = 500;
            myP.YAxis.Scale.Min = 0;
            myP.YAxis.Scale.Max = 500;
            myP.AxisChange();              // перерисовка ZedGraph

            if (mySerP != null) mySerP.Clear();

            double[] XX = new double[1]; double[] YY = new double[1];
            XX[0] = 0; YY[0] = 0;
            mySerP = myP.AddCurve("", XX, YY, Color.DarkBlue);

            // Определяем параметры серии
            mySerP.Symbol.Type = SymbolType.Circle;
            mySerP.Line.IsVisible = false;
            mySerP.Line.Width = 10;
            mySerP.Symbol.Fill.Type = FillType.Solid;
            mySerP.Symbol.Size = 4;
        }


        // Процедура перерисовки графика
        public void Tm()
        {
            double r;

            if (this.InvokeRequired == false)   // наш поток ?
            {
                m2 = DateTime.Now.Ticks;
                r = 0.0000001 * (m2 - m1);
                label1.Text = "Время выполнения= " + r.ToString("0.0") + "сек";
                //zg6.Refresh();
                //label1.Refresh();
                zg6.Invalidate();
            }
            else                                // если не наш пускаем процедуру Invok'ом
            {
                DrawT FDraw = new DrawT(Tm);
                if (FProc != null) this.Invoke(FDraw);
            }
        }


        private void button1_Click(object sender, EventArgs e)
        {
            m1 = DateTime.Now.Ticks;
            Sg = 0.0; x = 0.0;

            // запускаем поток таймера
            Vars.PrTm = true;
            FProc.Start();
        }


        // Самодельный таймер вызываемый фоновым потоком
        public void timer()
        {
            Vars.S.PrRabs = true;

            if (Sg < (12.0 * Math.PI))
            {
                y = 250 + (int)(250.0 * Math.Sin(Sg));

                mySerP.AddPoint((int)(x), (int)(y));

                Sg += (0.5 * 6.0 * Math.PI) / 250.0;
                x += 0.5;

                Tm();
            }
            else
            {
                Vars.PrTm = false;
                if (FProc != null)
                {
                    Thread.Sleep(300);
                    FProc.Abort();
                }
            }

            Vars.S.PrRabs = false;
        }


        private void TestForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            Vars.PrTm = false;
            if (FProc != null)
            {
                Thread.Sleep(300);
                FProc.Abort();
            }
        }
    }


    // Делегат для решения проблем синхронизации потоков
    delegate void DrawT();


    // Класс с переменными общего доступа для всех потоков
    public class Vars
    {
        public static Vars S = new Vars();          // Собственный Class
        public static bool PrTm = false;
        public static TestForm ObjTstF = null;
        public bool PrRabs = false;
    }


    // фоновый поток таймера
    class FTimer
    {
        public static void FonProc()
        {
            while (Vars.PrTm)
            {
                Thread.Sleep(0);
                if (Vars.S.PrRabs == false)
                {
                    Vars.ObjTstF.timer();
                }
            }
        }
    }
}

v567 24.06.2009 - 13:12

Проект целиком кроме ссылки на linuxforum можно ещё взять здесь: http://www.cyberforum.ru/csharp-net/thread41029.html
В указанной ссылке тест содержит текст (без фонового потока) который приводился ранее.

А с фоновым потоком выполнимый файл сделать труда не составит.

v567 24.06.2009 - 19:24

Решение найдено. happy smiley
Как оказалось достаточно убрать в процедуре FTimer.FonProc() вызов Thread.Sleep(0). Время работы теста в этом случае составит 0.8 сек. Что более чем на порядок превосходит предыдущие результаты, но приблизительно в 4 раза хуже, чем в TChart'е. Однако это уже можно списать на медлительность .NET

Итак, итоговый вариант выглядит так happy smiley:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using ZedGraph;

namespace Test
{
    public partial class TestForm : Form
    {
        Thread FProc;
        public GraphPane myP;
        long m1, m2;
        LineItem mySerP;
        double x, y, Sg;


        public TestForm()
        {
            InitializeComponent();
            Vars.ObjTstF = this;
        }


        // Изменение ZedGraph с учетом изменения размеров формы
        private void SetSize()
        {
            zg6.Location = new Point(0, 0);
            zg6.Size = new Size(this.ClientRectangle.Width, this.ClientRectangle.Height);
            zg6.Refresh();
        }


        // Изменение размеров формы
        private void F06_Resize(object sender, EventArgs e)
        {
            SetSize();         // Изменение размеров ZedGrpah
        }


        private void Form1_Shown(object sender, EventArgs e)
        {
            SetSize();         // Изменение размеров ZedGrpah
            this.Move += new System.EventHandler(this.F06_Resize);
            this.Resize += new System.EventHandler(this.F06_Resize);
        }


        private void Form1_Load(object sender, EventArgs e)
        {
            FProc = new Thread(FTimer.FonProc);

            SetSize();

            myP = zg6.GraphPane;

            // Убираем всякий мусор (титлы и надписи по осям)
            myP.Title.FontSpec.Size = 6;
            myP.Title.Text = " ";
            myP.XAxis.Title.Text = "";
            myP.YAxis.Title.Text = "";

            // Настройка шрифта осей
            myP.XAxis.Scale.FontSpec.Size = 9;
            myP.YAxis.Scale.FontSpec.Size = 9;
            myP.XAxis.Scale.FontSpec.IsBold = true;
            myP.YAxis.Scale.FontSpec.IsBold = true;

            // Градиентная заливка графика
            myP.Chart.Fill = new Fill(Color.White, Color.Gray, 45F);
            // Градиентная заливка коймы графика
            myP.Fill = new Fill(Color.White, Color.Gray, 45F);

            myP.XAxis.Scale.Min = 0;
            myP.XAxis.Scale.Max = 500;
            myP.YAxis.Scale.Min = 0;
            myP.YAxis.Scale.Max = 500;
            myP.AxisChange();              // перерисовка ZedGraph

            if (mySerP != null) mySerP.Clear();

            double[] XX = new double[1]; double[] YY = new double[1];
            XX[0] = 0; YY[0] = 0;
            mySerP = myP.AddCurve("", XX, YY, Color.DarkBlue);

            // Определяем параметры серии
            mySerP.Symbol.Type = SymbolType.Circle;
            mySerP.Line.IsVisible = false;
            mySerP.Line.Width = 10;
            mySerP.Symbol.Fill.Type = FillType.Solid;
            mySerP.Symbol.Size = 4;
        }


        // Процедура перерисовки графика
        public void Tm()
        {
            double r;

            if (this.InvokeRequired == false)   // наш поток ?
            {
                m2 = DateTime.Now.Ticks;
                r = 0.0000001 * (m2 - m1);
                label1.Text = "Время выполнения= " + r.ToString("0.0") + "сек";
                //zg6.Refresh();
                //label1.Refresh();
                zg6.Invalidate();
            }
            else                                // если не наш пускаем процедуру Invok'ом
            {
                DrawT FDraw = new DrawT(Tm);
                if (FProc != null) this.Invoke(FDraw);
            }
        }


        private void button1_Click(object sender, EventArgs e)
        {
            m1 = DateTime.Now.Ticks;
            Sg = 0.0; x = 0.0;

            // запускаем поток таймера
            Vars.PrTm = true;
            FProc.Start();
        }


        // Самодельный таймер вызываемый фоновым потоком
        public void timer()
        {
            Vars.S.PrRabs = true;

            if (Sg < (12.0 * Math.PI))
            {
                y = 250 + (int)(250.0 * Math.Sin(Sg));

                mySerP.AddPoint((int)(x), (int)(y));

                Sg += (0.5 * 6.0 * Math.PI) / 250.0;
                x += 0.5;

                Tm();
            }
            else
            {
                Vars.PrTm = false;
                if (FProc != null)
                {
                    Thread.Sleep(300);
                    FProc.Abort();
                }
            }

            Vars.S.PrRabs = false;
        }


        private void TestForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            Vars.PrTm = false;
            if (FProc != null)
            {
                Thread.Sleep(300);
                FProc.Abort();
            }
        }
    }


    // Делегат для решения проблем синхронизации потоков
    delegate void DrawT();


    // Класс с переменными общего доступа для всех потоков
    public class Vars
    {
        public static Vars S = new Vars();          // Собственный Class
        public static bool PrTm = false;
        public static TestForm ObjTstF = null;
        public bool PrRabs = false;
    }


    // фоновый поток таймера
    class FTimer
    {
        public static void FonProc()
        {
            while (Vars.PrTm)
            {
                // Thread.Sleep(0);
                if (Vars.S.PrRabs == false)
                {
                    Vars.ObjTstF.timer();
                }
            }
        }
    }
}

hoplin 31.08.2009 - 08:45

спасибо за материалы. пользуемся )

Рутакате 09.10.2009 - 23:10

Как сдвинуть столбцы

Точнее-как сделать так,чтобы при построении Bar-а,столбцы стояли вплотную друг к другу?Оч срочно!!!))

Jenyay 09.10.2009 - 23:18

Рутакате, гляньте этот класс

graber 22.10.2009 - 19:21

преобразование координат

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

Jenyay 22.10.2009 - 21:37

@CintaNotes,

Что-то похожее в ZedGraph есть. Как будет время, покопаюсь.

graber 22.10.2009 - 22:33

Re:преобразование координат

нашел, все работает. может кому поможет, вот код:
private bool zedGraphControl1_MouseMoveEvent( ZedGraphControl sender, MouseEventArgs e )
{

   // Save the mouse location
   PointF mousePt = new PointF( e.X, e.Y );

   // Find the Chart rect that contains the current mouse location
   GraphPane pane = sender.MasterPane.FindChartRect( mousePt );

   // If pane is non-null, we have a valid location.  Otherwise, the mouse is not
   // within any chart rect.
   if ( pane != null )
   {
      double x, y;
      // Convert the mouse location to X, and Y scale values
      pane.ReverseTransform( mousePt, out x, out y );
      // Format the status label text
      toolStripStatusXY.Text = "(" + x.ToString("f2") + ", " + y.ToString("f2") + ")";
   }
   else
      // If there is no valid data, then clear the status label text
      toolStripStatusXY.Text = string.Empty;

   // Return false to indicate we have not processed the MouseMoveEvent
   // ZedGraphControl should still go ahead and handle it
   return false;

}

и ссылка на источник: http://zedgraph.org/wiki/index.php?title=Show_the__Cursor_Location_in_a_Status_bar

zaqazaqaz 16.11.2009 - 13:27

ПОМОГИТЕ ПЖЛ!!!!!!!

у меня построен график
подскажите ПЖЛ как сделать такое :
по mouseclick, получать координаты точки на которую кликаю а не координаты формы., ну или просто координаты места на графике. ПЖЛ ПЖЛ ПЖЛ ПЖЛ ПЖЛ ПЖЛ ПЖЛ ПЖЛ ПОМОГИТЕ ПОМОГИТЕ ПОМОГИТЕ ПОМОГИТЕ ПОМОГИТЕ ПОМОГИТЕ ПОМОГИТЕ ПОМОГИТЕ ПОМОГИТЕ

Jenyay 16.11.2009 - 21:30

zaqazaqaz, посмотрите комментарий выше. Попозже постараюсь сделать подобный пример.

Серж 19.12.2009 - 16:43

Была раньше. Точка пересечения двух прямых.

Только вливаюсь в ваши ряды. Вот сразу вопрос - как получить точку пересечения двух Curve?

Ффф 27.01.2010 - 00:20

Можно ли отключить контекстное меню, которое вылезает по нажатию правой кнопкой мыши на графике?

Jenyay 27.01.2010 - 09:25

Ффф, можно. Для этого надо установить свойство IsShowContextMenu в false.

Артем 03.03.2010 - 04:51

Подскажите пожалуйста, как получить доступ к параметрам уже построенной кривой. т.е один из методов в моей программе строит график какой то функции, а другой метод каким то образом этот график должен преобразовать, т.е мне необходимо получить во втором методе вектора точек по которым строился начальный график, переменную типа lineItem общую для всех методов класса вводить не хочется, так как в ней будет, последняя построенная функция, а мне надо иметь доступ к любой функции построенной на graphpane. Как мнее получать параметры любой построенной функции по индексу?

Jenyay 03.03.2010 - 17:27

У класса GraphPane есть свойство CurveList - список кривых. Если я правильно понял, то это то, что Вам нужно.

Jenyay 03.03.2010 - 19:20

Добавил новый пример про изменение кривых.

Алена 12.03.2010 - 23:35

Формат меток осей

Сначала хочу поблагодарить за то, что вы нам помогаете! С помощью вашего ресурса снимается сразу масса вопросов. Однако не нашла решения для моей проблемки: по оси Y откладываются шестизначные цифры (140233, 140234, 140234 и т.д.), но на самой оси они отражаются как "140,2" при этом название оси выглядит так "Y Axis (10^3)". Понятно, что он из лучших побуждений сокращает мои большие цифры, но они мне нужны полноценные. Подскажите, где можно выставить нормальное отображение цифр?

Jenyay 13.03.2010 - 16:53

Алена, я тоже недавно столкнулся с такой проблемой, еще не искал как ее обойти. Если найду, то обязательно напишу.

Jenyay 14.03.2010 - 19:25

Алена, добавил пример по Вашему вопросу.

Алена 14.03.2010 - 22:20

Спасибо огромное!!! Сама бы еще не скоро не догадалась)

S_H_U_R_I_K 01.04.2010 - 10:28

Как нарисовать точку

Есть необходимость нарисовать точку на панели ZedGraph. Так при наведении на эту точку выдовалось подсказка с координатами и именем это точки.
На данный момент это реализовал, посторив кривую с одной точкой. Есть другие способы?

Jenyay 01.04.2010 - 20:37

S_H_U_R_I_K, а, по-моему, это хороший способ.

Igor 02.04.2010 - 14:44

Снову real-time

Пожалуйста помогите найти следующие решение.
Надо выводить график в real-time и отображать час по оси Х в формате Ч:М(string). Незнаю как динамически ето можна сделать. Когда я создаю динамический масив с етими строковыми переменными и их отображаю, то график перемещается вправо, при етом становится больше незарисованая часть графика (фон). Как выйти с етого положения? По моему надо решыть проблему с автоматическим маштабируванием осей.

Спасиба!

Антон 04.04.2010 - 15:28

Большое спасибо) Вы сэкономили мне кучу времени, что особенно ценно перед дипломом))))) winking smiley

Аля 16.04.2010 - 22:43

Просто супер!!! Мне всё очень нравится)))
Но у меня сейчас возникла проблема, никак не получается сделать. Есть База данных, данные выводятся в dataGridView и у меня не получается передать эти значения в ZedGraph. Напиши пожалуйста маленький примерчик))))

Jenyay 17.04.2010 - 20:34

Аля, а нельзя брать данные минуя DataGrid?

known 20.04.2010 - 22:49

отображдение координат по оси OX и OY по клику.

копался с кодом Graber, ничего путного не вышло, может кто чем сможет помочь?

Задача: получить координаты по осям OX и OY положение мыши по её клику.

Jenyay 20.04.2010 - 22:53

known, как раз собирался сделать такой пример. Постараюсь сделать его побыстрее.

known 21.04.2010 - 11:33

Jenyay, спасибо большое!

typik 21.04.2010 - 21:01

события

Здравствуйте! Пожайлуста подскажите как сделать, чтобы вместо эффекта по умолчанию при нажатие мыши, был например указатель мыши и он бы двигал график. Еще как то странно иногда есть такой эффект, что оси выходят за рамку, встречалось такое?

Jenyay 21.04.2010 - 21:27

По поводу движения графика, при случае посмотрю как это проще всего сделать. Про оси ничего сказать не могу, с таким не сталкивался.

Аня 16.05.2010 - 21:53

Лучше в конце писать zedgraph.Refresh(), а не Invalidate(). Перерисовываться будет быстро, если у вас данные часто меняются. а с Invalidate все долго думает, а потом в конце отрисовывает.

Arthur 04.06.2010 - 07:31

несколько кривых в нескольких координатах Y

Здравствуйте. Большое спасибо за материал, очень помогло.
Но возникла проблема, никак не могу найти решения.
Надо нарисовать несколько кривых на одной панели. Каждая кривая имеет свою размерность (единицы измерения), соответственно надо несколько (от трех и больше) осей Y, каждая из осей должна соответствовать конкретной кривой... Как то так. Даже не могу сооброзить откуда начать копать. Заранее спасибо за помощь.

Jenyay 04.06.2010 - 12:18

Arthur, написал пример для Вашего случая.

Arthur 04.06.2010 - 14:37

Потрясающая оперативность, просто нет слов, огромное спасибо.
С уважением, Артур.

Jiri 23.06.2010 - 16:23

Проблема с двумя графиками

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

Jenyay 25.06.2010 - 20:07

Проблема с двумя графиками

Jiri, добавил новый пример по Вашему вопросу.

Anoha 29.06.2010 - 03:33

ответь пожалуйста в этой теме
http://jenyay.net/ZedGraph/Bar

Jenyay 29.06.2010 - 22:20

Anoha, как будет время, посмотрю в чем может быть дело. Это скорее всего ближе к выходным.

Алексей 09.08.2010 - 15:42

Добрый день!

Можно вопрос:
а вот такие графики возможно сделать в данном контроле?
http://s60.radikal.ru/i168/1008/fd/53c1e9c67002.jpg
Просто у меня 6 независимых функций, которые нужно отобразить на одном графике - при этом может (да и зачастую будет) происходить наложение одного графика на другой.

Jenyay 09.08.2010 - 21:34

Вообще такие графики я впервые вижу. Судя по всему, ZedGraph такие рисовать не может.

Алексей 10.08.2010 - 06:43

Спасибо большое за ответ.
Просмотрев исходник данного графика, установил, что это
TChart от Borland c++, и его свойство View3D.
Интересно, есть какие нибудь аналоги в visual studio?

Al 12.08.2010 - 22:55

Als

Thanks from Bulgaria!I was surprised to find so full info here!

Алена 16.08.2010 - 18:03

Jenyay, опять вопросик возник... Понадобилось сделать подписи к каждой точке на графике. Покопалась, поняла что отдельной такой галочки нет и надо делать через добавление текстовых объектов. Все сделала, добавила, но у моих текстовых объектов фон белый и никак не могу найти как сделать его прозрачным??

Jenyay 18.08.2010 - 19:58

Алена, добавил новый пример, касающийся фона текстовых объектов.

Алена 22.08.2010 - 00:20

Спасибо, спасибо, спасибо!happy smiley

sasha_g1981 12.09.2010 - 15:41

в реальном времени отображается серия большого размера >10000 точек, имеется ли в zedgraph возможность перерисовки не всей серии, а только нового значения как это делает MSChart, Dundas, TChart... и есть ли возможность использовать пустые точки

Newton 18.09.2010 - 10:32

Точки разрыва

доброго времени суток! столкнулся с проблемой отрисовки графика с множеством точек разрыва к примеру [x](целая часть числа), как быть? натолкните на путь истинный

Jenyay 18.09.2010 - 21:44

Точки разрыва

Первое, что приходит на ум, это для каждого отрезка создать свою кривую.

Александр 22.09.2010 - 01:58

Ограничение масштабирования

При ручном масштабировании с помощью колеса мышки, масштаб изменяется не ограниченно, как в вверх, так и вниз диапазона, каким образом можно выставить ограничение на увеличение/уменьшение масштаба ???

Jenyay 22.09.2010 - 22:39

RE: Ограничение масштабирования

Александр, добавил пример про ограничение масштаба.

Александр 24.09.2010 - 00:22

RE: Ограничение масштабирования

Спасибо!!!
ваш код прямо копия моего :)
но все равно проблема не решена, данный способ работает только при изменении масштаба, а как быть с перемещением...
не могу поверить, что в таком навороченном контроле, нет стандартной возможности ограничения масштабирования

Jenyay 24.09.2010 - 21:47

RE: Ограничение масштабирования

> не могу поверить, что в таком навороченном контроле, нет стандартной возможности ограничения масштабирования

Что-то в документации я тоже ничего подобного не нашел.

Newton 25.09.2010 - 10:12

Точки разрыва

2Jenyay
ладно так и сделаю, спасибо за совет... не оптимально, но сойдет для сельской местностиgrinning smiley

sasha_g1981 01.10.2010 - 01:55

RE: Ограничение масштабирования

стандартной возможности ограничения масштабирования как я понял нет, но можно дописать самому
в ZedGraphControl.Events.cs

protected void ZoomScale( Axis axis, double zoomFraction, double centerVal, bool isZoomOnCenter )
        {
.......................
               //axis._scale._minLinearized = centerVal - range;
                //axis._scale._maxLinearized = centerVal + range;
//**********************************************************

                double x1 = centerVal - range;
                double x2 = centerVal + range;

                if (Math.Abs(x1 - x2) > ZoomResolution)
                {
                    axis._scale._minLinearized = centerVal - range;
                    axis._scale._maxLinearized = centerVal + range;
                }
//**********************************************************
}
 private const double ZoomResolution = 1e-5; //1e-300; //

это ограничение зума, а ограничение макс./мин значений по можно как в примере сделать, по умолчанию double.Max/double.Min

Дима 05.10.2010 - 19:16

Приоритет видимости кривых

У меня на граффике есть гистограмма и линия, так вот столбцы гистограммы закрывают собой эту линию, а мне надо чтобы она была на переднем плане. Как этого добиться?

Jenyay 05.10.2010 - 22:07

RE: Приоритет видимости кривых

Попробуйте поменять очередь, в которой выводятся кривые.

Дима 06.10.2010 - 11:51

RE: Приоритет видимости кривых

Спасибо, помогло.
Кривая которая выводится на граффик первой оказывается выше, т.е. видимой по отношению к тем которые выводятся после нее.

Jiri 14.10.2010 - 16:16

Реальное время под осью Х

Приветствую. Надо динамически выводить данные, обновляемые каждую секунду. При этом надо, чтобы метки под осью Х отражали время получения данных в формате 12:03:57 и т.п. my_pane.XAxis.Type = AxisType.Date; дает время, в котором шаг аргумента х, равный 1, дает шаг в 1 день, начиная с (не соврать бы) с 1-го января 1900 года. Понятно, что можно перевети текущую дату в соответствующее число.. Формат вывода даты тоже задается. Но. Вопрос собственно в следующем. Проще можно как-нибудь?

Maks 19.10.2010 - 11:24

Здравствуйте. Пробую использовать ZedGraph под VC++.NET.
И не могу сделать отрисовку отдельных точек, как в примереhttp://jenyay.net/ZedGraph/Scatter
Собственно мой код

ZedGraph::LineItem myCurve = pane->AddCurve("Sin(x)",list,Color::Red,ZedGraph::SymbolType::Diamond);
myCurve.Line->IsVisible =false;
myCurve.Symbol->Fill->Color = Color::Red;
myCurve.Symbol->Fill->Type = ZedGraph::FillType::Solid;
myCurve.Symbol->Size = 9;

Artem 31.10.2010 - 00:27

2 Оси X

Доброго времени суток у меня такая пробдема есть 2 графика
Размерность по Y одинаковая а по X разная необходимо отображение 2 X осей.
Я написал так:
GraphPane pane = zedGraphControl1.GraphPane; pane.X2Axis.IsVisible = true;
Ось появилась но по ней графики не строятся.

Jenyay 31.10.2010 - 08:45

RE: 2 Оси X

Artem, посмотрите вот этот пример, хотя, если пользоваться X2Axis, то, по идее, можно и ее использовать, а можно оси и самому задать.

ichi 01.11.2010 - 16:27

маркировка части графика

Друзья, подскажите, пожалуйста, как лучше решить задачу выделения цветом части графика (определенного числа точек из общей совокупности) по шелчку и протаскиванию мышки?

Леонтий 20.11.2010 - 21:56

Перемещение мышкой метки (Label) у стрелки

Очень часто (причем нельзя заранее сказать) стрелка с подписью закроет линию графика.
Удобно было бы после создания, по шлечку мыши иметь возможность перемещать один из концов стрелки (из подпись конечно) по полю графика. Может кто такое далал или знает откуда рыть.

Immelstorm 29.11.2010 - 16:07

Работа.

Компилится нормально, но вот никакого графика нет frowning smiley
Что может быть не так?

Jenyay 29.11.2010 - 21:35

Re: Работа

Да что угодно, начиная от того, что неправильно заданы интервалы по осям до того, что не созданы кривые.

Владимир 08.12.2010 - 15:59

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

Jenyay, имеются до 30 графиков(graphpane) фиксированного размера и синхронизированных по оси х. Они конечно все не влезают на экран. Возможно ли как то осуществить вертикальную прокрутку графиков, при этом иметь горизонтальную прокрутку. Заранее благодарен!!!

Лулик 14.12.2010 - 16:26

Прямая через начало координат и точку

Добрый день, огромное спасибо за Вашу работу, очень помогло, единственное, не получается элементарное действие.
В цикле из ДатаГрид вывожу на график необходимые точки, всё получилось, как теперь провести прямые через начало координат и эти точки????? Спасибо

Jenyay 14.12.2010 - 22:29

Re: Прямая через начало координат и точку

Если я правильно понял, то надо просто создать кривую иоз двух точек: первая с координатами (0; 0), вторая - координата точки, которую надо соединить.

Лулик 15.12.2010 - 01:17

Прямая через начало координат и точку

Это да, но тогда эти кривые и заканчиваются на конечных точках, т.е. получаются отрезки, а мне нужны именно прямые, чтобы достигли мои точки и тянулись дальше до конца свободного места. Есть ли такая возможность???

Jenyay 15.12.2010 - 10:29

В смысле нужны не отрезки, а лучи? Похоже, что именно лучей в ZedGraph нет, но, получив по двум точкам уравнение прямой можно рассчитать точку, где она пересечет границу графика, и продлить ее до той точки пересечения.

Лулик 15.12.2010 - 14:29

Прямая через начало координат и точку

Спасибо, так и сделаю) Жаль, что ZedGraph не поддерживает лучи happy smiley

geforse 25.12.2010 - 21:30

Перерисовка графика

Как перерисовать график по нажатию кнопки ?

Jenyay 25.12.2010 - 22:40

Re: Перерисовка графика

Для перерисовки есть метод Invalidate(), или нужна какая-то особенная перерисовка?

edq 06.01.2011 - 23:59

смещение?

Если на гистограмме присутствует только один элемент, он отображается так: http://my.jetscreenshot.com/4589/20110106-8bvh-58kb
но при добавлении второго и т.д. происходит смещение/ремаштабирование гистограммы http://my.jetscreenshot.com/4589/20110106-st1k-69kb
как этого избежать?
.GraphPane.BarSettings.MinClusterGap = 0.0f;
не помогает
з.ы. большое спасибо за примеры, очень помогли

KobolD 12.01.2011 - 11:07

Стрелка на временном граффике

Как нарисовать стрелку на граффике если по оси Х идут даты т.е. myPane.XAxis.Type = AxisType.Date
Преобразовать Дату в double с помощью Convert.ToDouble не получается

KobolD 13.01.2011 - 12:32

Вобщем я сам разобрался, надо дату привести к типу XDate. тогда ее можно передавать в параметры стрелки, хотя там вроде как формат double должен быть.

Евгений 24.01.2011 - 13:42

Смотрю практически только в шпаргалку. Очень хорошо получилось.

Толик 06.02.2011 - 18:05

Скелет кривой

Здравствуйте. Подскажите пжл, у меня имеются 2 кривые, одна накладывается на другую. Нужно изменять 2-ю кривую по точкам, при этом 1-я остается на месте, как бы заблокирована от редактирования. Т.е. я хочу видеть на сколько я изменяю кривую по отношению к ее исходному варианту.
Редактирование кривой осилил, но при перетягивании точки 2й кривой, автоматически аналогично тянется и 1я. В итоге изменяются обе кривые (.

Cisse 09.02.2011 - 19:07

Скажите, пожалуйста, я добавил компонент, пытаюсь добавить на форму, пишет ошибку Не удалось создать компонент ZedGraphControl. Шрифт Arial не поддерживает стиль Regular. Как это исправить?

Jenyay 09.02.2011 - 20:49

Странная ошибка. У Вас проблем со шрифтом Arial в других местах не возникало? Попробуйте, например, у кнопки использовать этот шрифт.

Cisse 10.02.2011 - 16:42

Компонент добавить получилось, теперь другая проблема) При попытке добавить панель для рисования конструкция такая GraphPane pane = zedGraph.GraphPane; при попытке запустить ошибка
'ZedGraph.GraphPane' is a 'type', which is not valid in the given context . А как тогда правильно будет?

Cisse 10.02.2011 - 18:11

Извиняюсь, подсказали, заработало. Извиняюсь за наглость, не могли бы Вы объяснить как работает эта строчка list.Add (x, f(x)); по моим соображениям, вызываем функцию f, первый x это значение которое добавляем в лист или как-то по другому работает? Еще вопрос, возможно ли строить график по данным массива? Где можно про это прочитать, ну или намекните как)

Jenyay 10.02.2011 - 21:00

> Извиняюсь за наглость, не могли бы Вы объяснить как работает эта строчка list.Add (x, f(x)); по моим соображениям, вызываем функцию f, первый x это значение которое добавляем в лист или как-то по другому работает?

В список добавляем точку, x-координата которой x, а значение y вычисляется с помощью функции f() в той же точке x.

> Еще вопрос, возможно ли строить график по данным массива? Где можно про это прочитать, ну или намекните как)

Тут надо знать какой тип массива. Но самое простое, что можно сделать - просто в цикле вызывать list.Add() для каждого элемента массива. Хотел кинуть ссылку на документацию, но что-то она на официальном сайте сейчас недоступна.

Cisse 16.02.2011 - 15:02

Подскажите, пожалуйста, я на главной форме разместил компонент ZedGraph, создал отдельный файл для кода fsin.cs, в нем я хочу писать обработку построения графиков (классы для каждой функции), возникла проблема, как обратиться к ZedGraph на главной форме? Пытаюсь создать панель для рисования, но показывает ошибку.

Jenyay 16.02.2011 - 21:31

Cisse, лучше сделать наоборот, чтобы форма с ZedGraph'ом обращалась к fsin. Когда расчет зависит от интерфейсных элементов, это не очень хорошо.

Cisse 16.02.2011 - 22:12

Я так думал сделать: в файлах fsin.cs и остальных сделать описание классов для построения графиков и просто из главного меню при выборе определенного пункта обращаться методом к этому файлу и строить! А как сделать чтобы форма обращалась к файлам с классами (желательно примеры кода)?

Jenyay 16.02.2011 - 22:47

Cisse, или я что-то не правильно понимаю, или

using fsin;

...
// Где-то в коде
myVal = fsin.MyClass();

Cisse 17.02.2011 - 17:51

На главной форме компонент ZedGraph. В файле fsin.cs я в классах пытаюсь создать панель для рисования GraphPane pane = ZedGraph.GraphPane; , но показывает ошибку 'ZedGraph.GraphPane' is a 'type', which is not valid in the given context
Как правильно надо написать?

Jenyay 17.02.2011 - 20:30

В fsin надо обращаться не к классу ZedGraph, а к его экземпляру на форме. Что-то вроде Form1.graph. Это при условии, что graph - открытый член, чего лучше избегать и сделать для него отдельное свойство.

Cisse 18.02.2011 - 16:01

Можете показать код как это можно реализовать (и что где писать)?

Олег 21.02.2011 - 11:05

Ось времени

Можно ли, используя AxisType.Date, не отображать на оси времени определенные дни, месяца и др.(к примеру выходные дни из-за отсутствия данных) или задать свой календарь рабочих дней, чтобы график был без разрывов

Vadik 21.02.2011 - 14:54

печать/сохранить

добрый день. Возник вопрос как распечатать и сохранить полученный график? На одном форуме прочитал, что надо сохранить как рисунок и потом можно и печатать и сохранять)
Зарание спасибо!

Jenyay 21.02.2011 - 16:48

Олег, Vadik, интересные вопросы. Так сразу ответить не смогу, но я в ближайшие время покопаюсь в этом направлении.

Vadik 23.02.2011 - 21:26

ок, спасибо, тоже подумаю, если придумаю напишу)

Jenyay 23.02.2011 - 21:37

Если действовать в лоб, то можно из окна получить Graphics, скопировать контент в Image и сохранить его с помощью Image.Save. Но надо посмотреть, может быть есть более красивый способ.

Vadik 24.02.2011 - 00:37

я понял, что то такое читал, попробую так!

Vadik 25.02.2011 - 19:27

Все оказалось гораздо прощеhappy smiley
zedGraphControl1.SaveAsBitmap();//сохранить
zedGraphControl1.PrintDocument.Print();//печать

Jenyay 25.02.2011 - 19:50

Vadik,
ну и замечательно. Надо будет при случае включить это в шпаргалку.

Jenyay 25.02.2011 - 23:01

RE: Ось времени

> Можно ли, используя AxisType.Date, не отображать на оси времени определенные дни, месяца и др.(к примеру выходные дни из-за отсутствия данных) или задать свой календарь рабочих дней, чтобы график был без разрывов

Попробуйте установить pane.XAxis.Type = AxisType.DateAsOrdinal;

Олег 27.02.2011 - 01:48

RE:Попробуйте установить pane.XAxis.Type = AxisType.DateAsOrdinal

Пробавал, в принципе отображает без разрывов, но вот вместо дат времени отображает 0.00 на всех точках. Думаю как бы свой тип шкалы добавить.

Jenyay 27.02.2011 - 08:38

Можно попробовать установить вручную формат отображения меток с помощью Axis.Scale.Format.

Cisse 27.02.2011 - 18:37

Подскажите, пожалуйста, как узнать пересечение графиков? Можно ли ось y перенести по центру?

Jenyay 27.02.2011 - 19:28

По поводу обнаружения пересечений я не видел методов в самом ZedGraph (хотя можно, конечно, поискать), а вот, чтобы перенести ось, надо добавить строку

pane.YAxis.Cross = 0.0;

Это значит, что ось будет располагаться там, где находится 0 по оси X. Можно соответственно перенести ось и в другую точку.

Cisse 28.02.2011 - 18:33

Напишите, пожалуйста, номер Вашего ICQ, есть очень жизненно-важный вопрос.

Jenyay 28.02.2011 - 20:33

Cisse, 119402670

Zelen 07.03.2011 - 12:28

необходимо построить примерно вот такой график
http://s2.ipicture.ru/uploads/20110131/2qfU86F1.jpg
использую пакет - zedgraph
и возникает вот такая проблема:
1. По оси Х выставляю время
2. По оси У выставляю текстовые значения

на офф сайте zedgraph нашел такой коммент

For AxisType.Text, you can still specify numeric Y values for screen coordinates. The first text item has a value of 1.0, the second is 2.0, etc. You can use these values for a BoxItem. Note also that the current version of ZedGraph supports ZOrder, which allows you to specify whether the BoxItem gets placed under or above the grid, the curves, etc.

т.е. как я понял, каждому текстовому значению соответствует число (ну первое значение - 1, второе - 2 и тд.)
Вообщем пытаюсь нарисовать полоску получается такая фигня
http://s2.ipicture.ru/uploads/20110307/f1eTpNaU.jpg
убираю текстовые значения по оси У, выставляю числа - получается все норм
http://s2.ipicture.ru/uploads/20110307/QiYQec1z.jpg
код:

private void DrawGraph()
{
GraphPane pane = zedGraph.GraphPane;
pane.CurveList.Clear();
PointPairList list = new PointPairList();
string[] sDates = {"Obj1","Obj2","Obj3","Obj4","Obj5","Obj6","Obj7", "Obj9","Obj10","Obj11"};
/// тип значений по оси У
pane.YAxis.Type = AxisType.Text;
pane.YAxis.Scale.TextLabels = sDates;
//тип значений по оси Х
pane.XAxis.Type = AxisType.Date;
pane.XAxis.Scale.FormatAuto = true;
// границы графика
pane.XAxis.Scale.Min = new XDate(2000, 12, 4, 08, 0, 0);
pane.XAxis.Scale.Max = new XDate(2000, 12, 4, 21, 0, 0);
pane.YAxis.Scale.Min = 0;
pane.YAxis.Scale.Max = 11;
// Теперь линия по нулевому уровню должна быть перпендикулярна оси X
pane.XAxis.MajorGrid.IsZeroLine = true;
// !!!
// Задаем вид пунктирной линии для крупных рисок по оси X:
// Длина штрихов равна 10 пикселям, ...
pane.XAxis.MajorGrid.DashOn = 10;
// затем 5 пикселей - пропуск
pane.XAxis.MajorGrid.DashOff = 5;
// Включаем отображение сетки напротив крупных рисок по оси Y
pane.YAxis.MajorGrid.IsVisible = true;
// Аналогично задаем вид пунктирной линии для крупных рисок по оси Y
pane.YAxis.MajorGrid.DashOn = 10;
pane.YAxis.MajorGrid.DashOff = 5;
// Включаем отображение сетки напротив мелких рисок по оси X
pane.YAxis.MinorGrid.IsVisible = true;
// Задаем вид пунктирной линии для крупных рисок по оси Y:
// Длина штрихов равна одному пикселю, ...
pane.YAxis.MinorGrid.DashOn = 1;
// затем 2 пикселя - пропуск
pane.YAxis.MinorGrid.DashOff = 2;
// Включаем отображение сетки напротив мелких рисок по оси Y
pane.XAxis.MinorGrid.IsVisible = true;
// Аналогично задаем вид пунктирной линии для крупных рисок по оси Y
pane.XAxis.MinorGrid.DashOn = 1;
pane.XAxis.MinorGrid.DashOff = 2;
DateTime startdatemin = new DateTime(2000, 12, 4, 08, 0, 0);
double yValue=0;
// задаем точки для графика
for (int i = 0; i < 10000; i++)
{
DateTime tt = startdatemin.AddSeconds(i);
yValue = 1;
list.Add(new XDate(tt), yValue);
}
LineItem myCurve = pane.AddCurve("Object5", list, Color.Blue, SymbolType.VDash);
// Цвет заполнения отметок
myCurve.Symbol.Fill.Color = Color.Blue;
// !!!
// Тип заполнения - сплошная заливка
myCurve.Symbol.Fill.Type = FillType.Brush;
// !!!
// Размер
myCurve.Symbol.Size= 10;
zedGraph.AxisChange();
zedGraph.Invalidate();
}

Есть какие идеи в чем косяк ?

Rey 29.03.2011 - 10:45

Курсор

Не могу поменять курсор у компонента ZedGraph, курсор над ZedGraph всегда в положении Cross.
Как сменить иконку курсора на другую, например на Arrow?

Алексей 16.04.2011 - 15:51

Как узнать текущие значения крайних точек отображения при масштабировании?

Привет.
есть такая проблема - нужно динамически получать значения крайних точек оси в текущем масштабе.

Т.е. к примеру в начале по х 0..100
по y 0..200

пользователь отдалил график..
и получается по х -50..150
по у - -50..250

Как такие значения получать?

 19.04.2011 - 20:23

Здравствуйте, Нужна ваша помощь. В цикле надо рисовать график, т.е. три цикла - три графика, Но рисуется только Один график в конце всего цикла. В чем ошибка???
Вот код:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ZedGraph;
using System.IO;

namespace WindowsFormsApplication7
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        int[] output = new int[20];
        string[] outputstring = new string[20]; //массив значений S режима контроля
        int[] outputold = new int[20];
        int[] studingold = new int[20];
        int[] studingoutput = new int[20];
        string[] Training = new string[15];// массив значений S обучающего режима
        double[] sr = new double[15];
        double[] otkl = new double[15];

        double sum = 0;
        double G = 0;
        double S = 0;
        public void SetStudingState()
        {
            int sh = 0;
            string[] frequency = File.ReadAllLines(@"D:frequency.txt");
            int N = 3;
            int m = frequency.Length;
            int[,] mas = new int[N, m];


            for (int i = 0; i < N; i++)
            {


                sh++;
                textBox4.AppendText(sh.ToString());

                for (int j = 0; j < m; j++)
                {

                    textBox1.AppendText(frequency[j]);
                    textBox1.AppendText("t");
                    //textBox1.AppendText("RF" + frequency[j] + "_AT0" + "n");
                    //comport.Write("VFn");// установка режима

                    studingoutput[j] = Convert.ToInt32(frequency[j]) + 1;


                    //DisplayData(MessageType.Incoming, decAgain + "n");



                    mas[i, j] = studingoutput[j];
                }

                //System.Threading.Thread.Sleep(1000);


                /////////////////////////////////////////
                for (int a = 0; a < m; a++)
                {
                    sum = 0;
                    S = 0;
                    G = 0;
                    for (int b = 0; b < sh; b++)

                        sum += mas[b, a];

                    sum /= sh+1;
                    sum = Math.Round(sum, 2);
                    textBox2.AppendText(sum.ToString());//среднее значение--на экран
                    textBox2.AppendText("t");
                    sr[a] = sum;/////////////////////////////


                    for (int b = 0; b < sh; b++)
                        G += Math.Pow((mas[b, a] - sum), 2);
                    if (sh == 1)
                    {
                        S = 0;
                    }
                    else
                    {
                        S = Math.Sqrt(G / (sh - 1));
                    }
                    S = Math.Round(S, 2);
                    otkl[a] = S;/////////////////////////////
                    textBox3.AppendText(S.ToString());//отклонение на экран
                    textBox3.AppendText("t");


                }
                ////////////////////////////////////////
                System.Threading.Thread.Sleep(1000);
                // Получим панель для рисования
                GraphPane pane = zedGraphControl1.GraphPane;

                pane.CurveList.Clear();
                // Два списка точек для двух графиков
                PointPairList list1 = new PointPairList();
                // PointPairList list2 = new PointPairList();

                int x, y;

                for (int z = 0; z < m; z++)
                {
                    int g = Convert.ToInt32(frequency[z]);
                    int h = Convert.ToInt32(studingoutput[z]);
                    x = g;
                    y = h;

                    list1.Add(x, y);
                }

                // Добавим две кривые, но не будем сохранять указатели на них
              LineItem myCurve = pane.AddCurve("", list1, Color.Red, SymbolType.None);
                //  pane.AddCurve("", list2, Color.Red, SymbolType.None);
                // Включим сглаживание
                myCurve.Line.IsSmooth = true;


                // Обновим оси и перерисуем график
                zedGraphControl1.AxisChange();// обновление графика
                zedGraphControl1.Invalidate();

                System.Threading.Thread.Sleep(1000);

                textBox1.Clear();
                textBox2.Clear();
                textBox3.Clear();
                textBox4.Clear();
            }

        }

        private void button1_Click(object sender, EventArgs e)
        {
            SetStudingState();
        }


    }
}

Jenyay 19.04.2011 - 20:45

А Вы удаляете все предыдущие графики перед рисованием текущего с помощью строки pane.CurveList.Clear();

Этот метод надо вызывать только один раз перед тем, как рисовать первый график.

 21.04.2011 - 00:47

Я помещала этот метод в начале метода SetStudingState() - ничего не изменилось((( что это может быть???

 24.04.2011 - 19:51

Ау ау ау, помогите кто-нибудь.......

dvios 25.04.2011 - 18:06

Как изменять аргумент функции из формы?

Для изучения языка написал простую программу поиска корня нелинейного уравнения, в которой правая и левая граница отрезка х задаются из TextBox (для поиска корня на разных отрезках). Но хочется чтобы рядом выводился график функции на ЭТОМ отрезке, т.е. xmin и xmax (из Вашего первого урока) так же считывались из TextBox. Как это реализовать?

Jenyay 25.04.2011 - 21:25

dvios, А в чем именно вопрос? Как считать данные из TextBox, или Вы хотите, чтобы при изменении значений в TextBox изменялись интервалы?

Если первое, то используйте свойство Text, только не забудьте преобразовать полученную строку к double.

Если второе, то посмотрите событие OnTextChanged.

dvios 25.04.2011 - 22:02

Так вот почему-то не посылается у меня в zedgraph считанные из TextBox значения...
Сейчас одну идею проверяю, если получится напишу.

dvios 25.04.2011 - 22:34

Все, разобрался. Проблема в том, что я языком только 2 недели занимаюсь happy smiley
Спасибо за советы!

Андрей 26.04.2011 - 14:04

Здравствуйте!

У меня вопрос: нет ли в ZedGraph опции, чтобы рисовались не все точки графика? Например, нет смысла на форме шириной 1024 пиксела рисовать миллион точек, т.к. из них реально видны будут только 1024, а времени тратится много. Достаточно нарисовать 1024 точки, которые будут аппроксимировать данный график из миллиона точек.

Jenyay 27.04.2011 - 21:08

Андрей, посмотрите класс FilteredPointList, похоже, что это то, что надо.

Александр 28.04.2011 - 14:52

Добрый день.
Отличная у Вас шпаргалка получилась!
А для Visual C++ подобного нет?

Jenyay 28.04.2011 - 17:41

Спасибо, очень приятно. Сам я Managed C++ не занимался, поэтому все примеры на C#. Но мне кажется, что в данном случае использование ZedGraph из-под MC++ разница будет чисто синтаксическая.

Или Вы имеете в виду C++ не под .NET?

Александр 29.04.2011 - 08:43

Дело в том, что VC++ я начал изучать 2 недели назад, а C# для меня вообще загадка. Я в интернете нашел несколько примеров и с построением графиков разобрался, а вот как использовать SetLaout чтобы отобразить 4 графика на одном листе в VC++ понять не могу. Может сможете что-нибудь посоветовать?

Андрей 03.05.2011 - 14:37

Jenyay, спасибо большое за ответ и наглядный пример!

Николай  06.05.2011 - 14:31

логарифмические координаты

Добрый день.

Подскажите, пожалуйста, как в zedgraph построить график, чтобы одна из осей была в логарифмических координатах?

спасибо.

Jenyay 06.05.2011 - 14:46

RE: логарифмические координаты

Посмотрите свойство Type у класса Axis. Ему надо присвоить значение AxisType.Log.

Jenyay 06.05.2011 - 15:47

RE: логарифмические координаты

Добавил пример на эту тему

Jenyay 06.05.2011 - 17:53

Комментарий с просьбой сделать курсовую удалил, тем более, что Delphi здесь - оффтопик.

neD 09.05.2011 - 18:30

Спасибо за данный материал

Спасибо большое автору за данный материал. Мне он очень и очень помог. Фактически, этот сайт и zedgraph.org wiki в Архиве Интернета (http://replay.web.archive.org/20090410072128/http://zedgraph.org/wiki/index.php?title=Main_Page) - максимально полные и обширные источники документации и примеров по ZedGraph на данный момент.

Whiteblond 16.05.2011 - 13:39

Как добавить на график интерактивные точки-контроллы?

Например строю полярный график эллипса, и хочу иметь возможность изменить его ширину-высоту с помощью мыши, возможно директриссу повернуть, чтобы угол поворота сделать..Возможно такое?

Александр 18.05.2011 - 14:36

Можно ли добавить вторую ось X?

У Вас в примере "Как на одном графике нарисовать несколько кривых с разными осями Y" показано как с помощью метода AddYAxis добавить вторую ось Y.
А нет ли способа добавить вторую ось X?
Необходимо на одном графике построить сечения трехмерной функции плоскостями XOZ и YOZ.

Артемий 18.05.2011 - 18:55

координаты по осям

Здравствуйте! У меня по оси X идёт дата и время. Скажите как сделать чтоб небыло промежутка, например между 06:00 потом 5 подписанных чёрточек потом 12:00. Как их тоже заполнить значениями???

Jenyay 18.05.2011 - 20:58

RE: координаты по осям

А вот этот пример не помогает?

Артемий 19.05.2011 - 10:58

координаты по осям

неа, не помогает...

Артемий 19.05.2011 - 13:04

координаты по осям Data Time

Как сделать чтоб при любом масштабировании формат был всё равно dd-mm-yyyy и HH:mm

Iriska 19.05.2011 - 23:04

Указывая DateAsOrdinal не отображаются объекты из GraphObjList

Это как так? И как отобразить дополнительную информацию при DateAsOrdinal? Или как-то можно по-другому (не DateAsOrdinal) выкинуть ненужные промежутки времени на графике, напр. интересует только рабочее время с 8 до 17 за несколько дней? Заранее спасибки.

Iriska 20.05.2011 - 00:06

Упорство и труд все перетрут :)

Сама нашла решение - координаты у линии нужно задавать в индексах, а не в реальных значениях. Спасибо за содержательную и оооочень полезную шпаргалку winking smiley

Julia 23.05.2011 - 19:13

Странное отображение

Начала осваивать этот компонент. Делаю как в примерах. График отображается. Но с правой стороны пояляется пустой прямоугольник и стерт низ полотна.

Jenyay 23.05.2011 - 22:23

RE: Странное отображение

А покажите скриншот.

Фирсов Алексей 24.05.2011 - 01:52

Добавление подписи в pie chart

Подскажите, как добавить на круговую диаграмму подписи, отображающие процент "кусочка"? Сейчас они видны, только если навести на соответствующий сегмент. А хотелось бы видеть их прямо на графике сразу.

Julia 24.05.2011 - 16:24

Михаил 27.05.2011 - 16:48

Зарисовка области

Подскажите пожалуйста как зарисовать область которая находится здесь в вот такой функции y = 12 и надо зарисовать область вся что выше!! есть метод Fill для линии но этот метод зарисовывает от линии до оси а мне нужно чтоб просто от линии вверх?

Артемий 01.06.2011 - 13:07

Огромные размеры Off

Здравствуйте!
Когда я разворачиваю форму на весь экран, делаю и график большим, и тогда все надписи и подписи становятся просто огромными, короче все шрифты на графике увеличивают размер, как это отключить????

 01.06.2011 - 14:19

RE: Огромные размеры Off

Как с этим бороться, показывает вот этот пример.

Юлия 29.06.2011 - 15:27

Вертикальные подписи по оси х

Строю гистограмму для большого числа значений (20 и более). Подписи по оси X - текстовые (наименование оборудования, символов 6-8). Естественно, показывает подписи по оси Х только некоторые. Можно ли сделать так, чтобы подписпи по оси Х отображались все и вертикально (чтобы все вошли)? Спасибо.

Ekura 06.07.2011 - 09:49

Вертикальные подписи по оси х

Чтобы подписи по оси Х отображались все и вертикально

(GraphPane myPane = zedGraph.GraphPane)

myPane.XAxis.Scale.FontSpec.Angle = 90;

Андрей 06.07.2011 - 16:36

Как выводить график по частям

Здравствуйте! У меня возник следующий вопрос. Пусть каждый момент времени данные для отрисовки кривой приходят в виде пакетов по 100 значений. Пакеты приходят в произвольном порядке. Нужно по мере поступления пакетов рисовать кривую. Я делаю так: когда приходит первый пакет, создаю кривую. При поступлении следующих пакетов методом AddPoint() добавляю точки к уже созданной ранее кривой. Но тут возникает проблема: крайние точки нарисованных не подряд участков кривой соединяются прямой линией. После окончания визуализации (когда все пакеты пришли) получаю нарисованную кривую + набор прямых линий, которые мне, естественно, не нужны. Скажите, пожалуйста, как удалить эти прямые, или как лучше организовать визуализацию в моем случае.

Jenyay 06.07.2011 - 19:22

Можно добавлять в конце каждого пакета (или в начале) разрыв, как это дела, написано здесь.

Андрей 13.07.2011 - 10:22

Jenyay, спасибо за совет!

Рашид 17.07.2011 - 08:47

Возможности интерактива

Здравствуйте! Тут уже задавали вопрос про интерактивнность пакета. Так какие есть возможности? Наложение точки, линии, идентифицировать серию по клику мыши по ней?

Пётр 19.07.2011 - 12:05

Тема

А как сделать отображение значений точек по умолчанию? Чтоб не клацать меню и не выбирать это свойство...

Пётр 19.07.2011 - 12:22

ответ на тему

IsShowPointValues

Юлия 21.07.2011 - 14:56

Вертикальные подписи по оси х

Ekura - спасибо большое

Jenyay 22.07.2011 - 22:33

RE: Возможности интерактива

Завтра выложу примеры, которые показывают, как можно с помощью мышки выбирать кривые и перемещать отдельные точки.

Пётр 27.07.2011 - 18:44

Цвет оси Х по нулю

Здрасте, не могу найти где задать цвет линии по оси Х по 0. Я просто задал чёрный фон и тогда не видно эту линию вообще((

Евгений 28.07.2011 - 12:57

Помощь Петру

хм... Может кто нить ответит на вопрос Петра???

Jenyay 28.07.2011 - 21:25

Цвет оси X задается с помощью свойства pane.XAxis.Color, по Y, соответственно, pane.YAxis.Color. Еще может понадобиться цвет рамки вокруг графика - pane.Chart.Border.Color.

Пётр 01.08.2011 - 10:32

Цвет оси Х по нулю

paneUDP.XAxis.Color = Color.White; Это первое что я пробовал и не катит оно, как была она чёрного цвета так и остаётся...

Jenyay 01.08.2011 - 13:39

RE: Цвет оси Х по нулю

Есть у меня одно подозрение... В общем, попробуйте таким образом поменять цвет оси Y. Дело в том, что линия Y = 0 относится к оси Y, а линия X = 0 - к оси X.

Пётр 01.08.2011 - 14:37

RE: Цвет оси Х по нулю

Jenyay, прям в точку!

Пётр 01.08.2011 - 18:41

Вопрос по поводу масштабирования

На одном контроле с помощью MasterPane я рисую несколько графиков. Когда я начинаю масштабировать скролингом или мышкой то масштабирует все из нескольких графиков... Можно сделать так чтоб менял масштаб только тот на котором я кручу скролинг???

Руслан 03.08.2011 - 09:20

scroll event

Здравствуйте. Хочу, чтобы текстовый объект всегда оставался в поле зрения, при прокрутке и масштабировании диаграммы. С масштабированием разобрался благодаря шпаргалке об ограничении масштабирования, спасибо. Не могли бы показать пример какого то использования обработки скролла графика?

Пётр 03.08.2011 - 12:15

Ответ на вопрос по масщтабированию....

Со своим вопрос пришлось разобраться самому, во общем вот код, думаю тут всё понятно: 6 вариантов построения и шесть параметров.

switch (pane_time)
{
    case 1:
        masterPaneSelected.SetLayout(g, true, new int[] { 1 }, new float[] { 1.0F });
        break;
    case 2:
        masterPaneSelected.SetLayout(g, true, new int[] { 1, 1 }, new float[] { 1.0F, 1.06F });
        break;
    case 3:
        masterPaneSelected.SetLayout(g, true, new int[] { 1, 1, 1 }, new float[] { 1.0F, 1.0F, 1.075F });
        break;
    case 4:
        masterPaneSelected.SetLayout(g, true, new int[] { 1, 1, 1, 1 }, new float[] { 1.0F, 1.0F, 1.0F, 1.09F });
        break;
    case 5:
        masterPaneSelected.SetLayout(g, true, new int[] { 1, 1, 1, 1, 1 }, new float[] { 1.0F, 1.0F, 1.0F, 1.0F, 1.15F });
        break;
    case 6:
        masterPaneSelected.SetLayout(g, true, new int[] { 1, 1, 1, 1, 1, 1 }, new float[] { 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.165F });
        break;
}

Jenyay 03.08.2011 - 13:18

По поводу масштабирования и MasterPane, гляньте свойства IsSynchronizeXAxes / IsSynchronizeYAxes, может поможет.

По поводу скролла. Я тут на несколько дней буду в оффлайне, на следующей неделе гляну.

Пётр 03.08.2011 - 15:01

То что нужно по масштабированию в MasterPane

IsSynchronizeXAxes / IsSynchronizeYAxes это как раз то что я и имел в виду. СПС

Пётр 08.08.2011 - 15:16

Гистограммы с несколькими значениями в каждом столбце ZedGraph

как сделать график чтоб выглядел, типа как здесь
http://technet.microsoft.com/ru-ru/library/ee633676.aspx
второй рисунок

Jenyay 09.08.2011 - 10:54

RE: scroll event

> Хочу, чтобы текстовый объект всегда оставался в поле зрения, при прокрутке и масштабировании диаграммы.

Используйте конструктор TextObj с 4-мя параметрами:

public TextObj(
        string text,
        double x,
        double y,
        CoordType coordType
)

Если последний параметр будет равен CoordType.ChartFraction, то координаты будут задаваться относительно прямоугольника графика независимо от координат на нем. Скоро выложу пример на эту тему.

Jenyay 09.08.2011 - 15:02

Добавил примеры про использование CoordType и рисование перекрывающихся гистограмм.

Руслан 10.08.2011 - 05:19

Спасибо!

Руслан 10.08.2011 - 05:49

RE:scroll event

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

Jenyay 10.08.2011 - 09:12

Сам не пробовал, но по идее можно, посмотрите другие значения из CoordType, там для разных осей можно задавать разные настройки.

Пётр 11.08.2011 - 16:09

А вот ещё вопрос! Можно задавать ширину легенды? Я сделал так чтоб она отображалась внутри графика и хочу чтоб значения были в одну строчку, а он переносит на 2.((

Jenyay 11.08.2011 - 20:00

> Я сделал так чтоб она отображалась внутри графика и хочу чтоб значения были в одну строчку, а он переносит на 2.((

Для этого у легенды есть свойство IsHStack. Его надо установить в true.

Андрей 12.08.2011 - 06:12

Роза ветров

Здравствуйте.
Можно ли средствами ZedGraph нарисовать что-то вроде ?

Если можно, то как?
Спасибо.

Jenyay 12.08.2011 - 08:25

Насколько я знаю, ZedGraph не может рисовать графики в полярной системе координат. Можно только вручную рисовать все эти окружности и самому пересчитывать координаты из полярной системы в декартову. Хотя надо поподробнее посмотреть.

Пётр 12.08.2011 - 11:07

> Я сделал так чтоб она отображалась внутри графика и хочу чтоб значения были в одну строчку, а он переносит на 2.((

> Для этого у легенды есть свойство IsHStack. Его надо установить в true.

Я юзал это свойство, когда ставлю false он каждую надпись в новую строчку, как полагается, ставлю true всё равно переносит последние надписи. А ещё прикол в том что когда ставлю свойство pane.Legend.Position = ZedGraph.LegendPos.Top; то всё норм, без всяких переносов.

Пётр 12.08.2011 - 12:35

Ну и ещё вопрос, можно как нить добавить дополнительно отделенную легенду в один GraphPane?

Руслан 13.08.2011 - 08:16

RE:scroll event

Все как вы сказали))а есть ли возможность так же выдавать координаты стандартным элементам вроде checkbox'ов? По аналогии не выходит, говорит что ему не подходят координаты zedgraph'a. В этом контроле реализовано что-то свое вместо чекбоксов?

Петр 15.08.2011 - 11:06

русификация

как перевести на русский интерфейс сабжа ?

Jenyay 15.08.2011 - 15:45

> как перевести на русский интерфейс сабжа ?

Интересный вопрос. Наверняка что-то должно быть, надо будет покопаться.

> есть ли возможность так же выдавать координаты стандартным элементам вроде checkbox'ов?

Хотите положить компонент поверх ZedGraph в точку с нужными координатами?

> можно как нить добавить дополнительно отделенную легенду в один GraphPane?

Судя по тому, что свойство Legend только для чтения и это не список, а один экземпляр, то мне кажется, что нет. С другой стороны можно создать вручную экземпляр Legend, но как его связать с определенным GraphPane, да еще чтобы он показывал что-то свое - хз.

Руслан 16.08.2011 - 05:41

RE:scroll event

>Хотите положить компонент поверх ZedGraph в точку с нужными координатами?
Да, причем желательно задать их как и textobj'экту, по горизонтали относительно видимой части и вертикально относительно координат.

Jenyay 16.08.2011 - 21:44

Тогда гляньте методы GeneralTransform/ReverseTransform из GraphPane.

Jenyay 17.08.2011 - 10:45

Добавил пример про пересчет координат.

Оля 23.08.2011 - 11:04

язык

когда пользователи кликают мышкой на графике то видят команды на англ языке- и пугаются

Jenyay 23.08.2011 - 11:10

RE: язык

> когда пользователи кликают мышкой на графике то видят команды на англ языке- и пугаются

Успокойте их, погладьте, скажите, что все будет хорошо. :)

А если серьезно, то все никак не дойдут руки посмотреть, как русифицировать ZedGraph.

Jenyay 26.08.2011 - 18:13

Добавил пример, как можно изменять контекстное меню, в том числе и переводить пункты меню.

 29.08.2011 - 15:11

Уже в оф.версии есть поддержка многих языков в контекстном меню. У меня стоит 5.1.5, с ней в комплекте идут библиотеки локализации.

Rey 02.09.2011 - 13:21

Курсор

Здравствуйте.
Не могу поменять курсор у компонента ZedGraph, курсор над ZedGraph всегда в положении Cross.
Как сменить иконку курсора на другую, например на Arrow?

Jenyay 02.09.2011 - 21:31

Rey 07.09.2011 - 06:38

Курсор

Jenyay, спасибо!

Roman 13.09.2011 - 14:34

Гистограмма с накапливанием

Как сделать такую гистограмму которая будет отображать вклад каждой категории в общую сумму. Вот как в MS Excel.
Пробовал закрасить столбик гистограммы разными цветами. До определенной позиции - один а после нее другой, но не получалось ничего.

Roman 13.09.2011 - 14:50

Гистограмма с накапливанием

Пардон разобрался, в документации описан тип гистограммы Stack. Вот только одно не устраивает, то что там при наведении мышки на элемент который находится над другим, то его значение отображается как общая сумма, хотелось бы чтоб отображалось только его значение не суммарное. Как бы это провернуть?

Stack 13.09.2011 - 15:20

странное поведение компонента

Собственно суть проблемы:

На грифике есть 9 (может чуть больше) рисок которых не должно быть, они отчетливо видны на вертикальной прямой. Координаты рисок:

14:35:51.57 12.09.2011 138.00
14:35:51.68 12.09.2011 143.90
14:35:51.79 12.09.2011 143.90
14:35:51.89 12.09.2011 143.90
14:35:52.00 12.09.2011 143.90
14:35:52.11 12.09.2011 143.90
14:35:52.22 12.09.2011 143.90
14:35:52.33 12.09.2011 143.90
14:35:52.44 12.09.2011 143.90
14:35:52.55 12.09.2011 143.90
14:35:52.66 12.09.2011 146.80

По идее там должны быть не риски и прямая линия которая уходит вверх, а там должна была быть прямая линия с 1 только скачком (но без этих зазубрин, судя по логу)

Как был реализован вывод графика:
1) считывание данных из файла в массив
2) формирование листа с точками (для даты происходил парсинг)
3) настройка чтоб у графика по оси Х была дата
4) собственно вывод самого графика.

Вот в чем может быть причина такого поведения?

Stack 15.09.2011 - 10:04

Все разобрался, претензий к компоненту нет..не правильно парсил дату (перепутал местами секунды и миллисекунды ) :)

Руслан 21.09.2011 - 06:51

Большой объем данных

Пишу осциллограф и столкнулся с тем, что при больших объемах данных(>10 графиков с >2000 точек) контрол начинает тормозить: при захвате поля перемещает его рывками и еще некоторые незначительные задержки, при этом, если увеличить масштаб то задержки заметно снижаются. Подскажите, можно ли с этим что-то сделать?

Jenyay 21.09.2011 - 08:43

RE: Большой объем данных

А вот этот пример не поможет?

Руслан 22.09.2011 - 17:30

RE: Большой объем данных

Спасибо,постараюсь применить, но, боюсь дискретизация точек настроена хорошо, есть ли еще какие-нибудь варианты, например, возможность выделения большего количества ресурсов под компонент?(сам никогда с таким не сталкивался)

 22.09.2011 - 20:09

Руслан

Еще вопрос(: Можно ли все значения, например по Х для PointPairList умножить на какое-то число?

Алексей 27.09.2011 - 17:43

изменение положения заголовка оси Y

Здравствуйте!
У меня строится множество графиков, у каждого из которых своя ось Y. Вертикальные заголовки осей занимают много места в этом случае.
Не подскажите, как можно заголовок ОСИ Y разместить над осью?

Jenyay 28.09.2011 - 09:05

изменение положения заголовка оси Y

Можно попробовать использовать pane.YAxis.IsTitleAtCross = true;

Но вообще хотелось бы найти более гибкий способ перемещения этой надписи.

Алексей 28.09.2011 - 15:35

изменение положения заголовка оси Y

Огромное спасибо, попробую.

Еще один вопрос тревожит:
Строятся множество графиков(дискретно, по получению новой точки), и по истечению какого-то времени счета, большая часть первых точек каждого графика пропадает ( около 70 %). Остаются последние точки + новые, которые продолжают появляться.
Это происходит только при очень малом шаге счета, при его увеличении, все графики строятся прекрасно.
Может есть какие-то ограничения по объему отображения точек?
Заранее спасибо!

Артём 29.09.2011 - 18:06

Размер графика...

Я рисую с помощью МастерПайн несколько графиков. Все получается но есть один глюк. Сначала я устанавливаю порядок расположения:

using (Graphics g = CreateGraphics())
{
masterPane.SetLayout(g, true, new int[] { 4, 4, 2 },
new float[] { 0.5F, 0.5F, 1.5F });
}

После этого графики которые в 3 ряду я меняю им размеры:

RectangleF SmallRect = new Rectangle();
SmallRect = masterPane[8].Rect;
SmallRect.Width = SmallRect.Width + (SmallRect.Width * (float)0.936);

RectangleF SmallRect2 = new Rectangle();
SmallRect2 = masterPane[9].Rect;
SmallRect2.Width = SmallRect2.Width - (SmallRect2.Width * (float)0.91);
SmallRect2.X = SmallRect2.X + (SmallRect2.X * (float)0.92);

masterPane[8].ReSize(CreateGraphics(), SmallRect);
masterPane[9].ReSize(CreateGraphics(), SmallRect2);

И вроде всё хорошо работает, но когда я сворачиваю программу в трей а потом разворачиваю, то 3 ряд с большим уже и маленьким графиком становятся одинакового размера, пока я их заново не перерисую, точнее не выполню этот код... Как тут быть?

Zelen 24.10.2011 - 11:33

поточечный вывод графика

Вообщем у меня график содержит большое количество точек, которые надо выводить поточечно: т. е. каждый раз добавлять новую точку на графике, при этом старые точки не должны стираться. К сожалению Invalidate() затирает предыдущие точки и построить график невозможно. Есть ли какие нибудь способы обновления zedgraph без стирания старых графиков ?

Сергей 24.10.2011 - 15:37

Отмена осей

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

Сергей 24.10.2011 - 16:21

GraphPane

Еще вопрос, как убрать в GraphPane , обрамляющую рамку?
Еще вопрос, как сделать, чтобы при отображении пэйнов один за другим, убрать разделяющую между пэйнами черточку и ,соответсвенно, промежуток. за ранее спасибо

Андрей 02.11.2011 - 15:01

Не показывать отрицательную часть графика

Здравствуйте!

Скажите, пожалуйста, как при зумировании с использованием функции ZoomPane не показывать часть графика, лежащую левее нуля. Для зумирования колесиком нашел совет №29 "Как ограничить масштабирование графика", но, как я понимаю, он в моем случае не подходит.

CyMpaK 03.11.2011 - 15:45

Надпись (10^3) на осях

Здравствуйте. Мне не нравится данная надпись на осях. Можно ли её как-нибудь удалить или сделать другого формата? Например (x1000).
Заранее спасибо.

Jenyay 03.11.2011 - 17:59

Надпись (10^3) на осях

CyMpaK 03.11.2011 - 19:08

Надпись (10^3) на осях

Спасибо большое за совет.

m4a 04.11.2011 - 11:16

ответы

to Сергей
Здравствуйте. Вопрос такой: можно ли отменить показ осей в графике, и отменить выделение мышью участка на графике?
1) pane.YAxisList[axisindex].IsVisible = axisprop.visible;
2) в настройках контрола перебирай. в VS много свойств ищи что тебе надо.

Еще вопрос, как убрать в GraphPane , обрамляющую рамку?
Еще вопрос, как сделать, чтобы при отображении пэйнов один за другим, убрать разделяющую между пэйнами черточку и ,соответсвенно, промежуток. за ранее спасибо
1)ZGrConrtol.MasterPane.PaneList[0].Chart.Border.IsVisible = false;
2) не ясно что необходимо
может быть из этого что-то подойдет
ZGrConrtol.MasterPane.PaneList[1].Border.IsVisible = false;
ZGrConrtol.MasterPane.PaneList[1].Margin.All = 0;
ZGrConrtol.MasterPane.Margin.All = 0;

CyMpaK 07.11.2011 - 11:46

Проблема

Здравствуте ещё раз.
Jenyay вы мне посоветовали посмотреть пример. Но у меня появилась другая проблема. Есть код, который рисует график с помощью
библиотеки ZedGraph. График выводит на осях злополучные (10^3). Команда pane.XAxis.Title.IsOmitMag = true; работает и (10^3) не появляется, но команда
ChartPane.YAxis.Scale.Mag = 0; не изменяет формат. Все так же выводит 10, 20, 30 вместо 10000 и тд. Причем, если график не достигает 10000, то
все цифры полностью рисуются, а вот если график будет содержать точку 10000, то там уже рисуются 5,10 ... 30 c (10^3).
И ещё вопрос, все-таки есть ли способ вместо (10^3) вставить другой текст? если да, то это бы разрешило бы предыдущий вопрос ;)

Andrey 25.12.2011 - 11:19

Здравствуйте. Подскажите пожалуйста можно ли с помощью zedgraph нарисовать 3-х мерный график?если нельзя то подскажите компонент для рисования?

Jenyay 25.12.2011 - 15:16

Нет, трехмерные графики ZedGraph строить не умеет. А вот кто умеет - не подскажу, программно их строил только в Python.

Tsvetik 12.01.2012 - 12:37

Ползовательские символы точек графика

Здравствуйте. Не подскжете ли как сделать собственный значок для рисования точки графика?
Я копал в сторону

Symbol mysymbol = new Symbol();
Graphics g = graphControl.CreateGraphics();
var path = mysymbol.MakePath(g, 1.0F);
path.AddLine(0, 0, 2, 2);
path.AddEllipse(10, 10, 10, 10);
LineItem l = new LineItem ("ABCD",Items,Color.Red,SymbolType.UserDefined);
l.Symbol = mysymbol;

Однако качтомный символ не рисуется.

Roman 18.01.2012 - 11:33

Печать

Необходимо подготовить отчет на страничку A4 на котором нужно разместить скажем 5 разных графиков и возможно чего то еще там написать помимо этих графиков, т.е. тупо напечатать один график не подходит. Как это осуществить ?

alex 23.01.2012 - 15:27

Узнать координаты новой свечки

Помогите узнать координаты новой свечки (переменная myCurve)

пробовал myCurve.getCoords(), но он выдает какие то левые значения.

код:

StockPt pt = new StockPt(

                    new XDate(Util.ToDateTime(idate, itime)),
                    (double)high,
                    (double)low,
                    (double)open,
                    (double)close,
                    (double)vol);
            l1.Add(pt);

JapaneseCandleStickItem myCurve = mypane.AddJapaneseCandleStick("test", l1);

Milax 25.01.2012 - 10:30

When YAxis type is Logarithmic and chart type is stacked bar bar item drawed incorrect

When YAxis type is Logarithmic and chart type is stacked bar bar item drawed incorrect.
We see bar items for one axis only. Other bar items no displayed.

Why?

Milax 25.01.2012 - 10:34

3D Graph

Andrey 25.12.2011 - 11:19
"Здравствуйте. Подскажите пожалуйста можно ли с помощью zedgraph нарисовать 3-х мерный график?если нельзя то подскажите компонент для рисования? "

http://www.steema.com/teechart/net

Genry 31.01.2012 - 16:26

Скроллбар

Большое спасибо за примеры, очень полезно.
Подскажите, а как можно настроить отображение только части графика, а для просмотра того, что не помещается на экране, использовать скроллбары: например, есть значения по оси Х от 0 до 100, отображается только диапазон в 20 точек (пусть 40-60), остальное - скроллбаром, при этом прокрутить область меньше 0 или больше 100 нельзя?

Eugene 01.02.2012 - 14:05

Как узнать размеры текста на графике?

Здравствуйте.
Сейчас борюсь с такой задачей: на asp.net страничке показываю точечный график с названиями точек. По требованиям лейблы не должны накладываться.
Для этого я сам алгоритмом их расставляю (как TextObj). Есть заминка в том, что я не могу понять как узнать длину/высоту текста лейблы в координатах графика или в пикселах что б хоть как-то привязаться к самому графику. Вводил попраочные коэффициенты, но они перестают быть актуальными как только начинаю пользоваться масштабом.

Длину текста в пикселях могу узнать так: TextRenderer.MeasureText("MyText", new Font("Tahoma", 6)).Width
Будут ли это значение в той же системе координат что и
var pointF = myPane.GeneralTransform(new PointF((float)pointPair.X, (float)pointPair.Y), CoordType.AxisXYScale);
pointPair.X, pointPair.Y ?


Подписаться на комментарии
Автор:
Тема:
 Ваш комментарий
 
 
Введите код 370
 
Править - История - Печать - Последние изменения - Поиск
Последняя редакция от 31.01.2012 08:25