0 / 0 / 1
Регистрация: 25.08.2015
Сообщений: 6
1

Стрелки на графике

25.08.2015, 17:56. Показов 2650. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет. Делаю программу, рисующую диаграмму Ганта с помощью встроенного элемента Chart.
Очень нужно придумать, как сделать стрелки между рядами как на примере. Ну или что-то похожее, чтобы отобразить связи.
Стрелки на графике


На всякий случай код моей программы. Вызывается из другого приложения с параметрами "Название1, дата начала1, дата окончания1, Название2, дата начала2, дата окончания2, ..."
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
54
55
56
57
58
59
namespace GanttChart
{
    public partial class Form1 : Form
    {
        Random RandomValue = new Random();
        public Form1()
        {
            InitializeComponent();
        }
        public Color BarColor()
        {
            return Color.FromArgb(255, RandomValue.Next(220), RandomValue.Next(220), RandomValue.Next(220));
        }
        public string NoSpace(string Name)
        {
            StringBuilder s = new StringBuilder(Name);
            for (int i=0; i<s.Length; i++)
                if (s[i] == '_')
                { s[i] = ' '; }
            return s.ToString();
        }
        public void AddBar(string Name, string StartDate, string EndDate)
        {
            chart.Series[0].Points.AddXY(Name, StartDate, EndDate);
            chart.Series[0].Points[chart.Series[0].Points.Count - 1].XValue = chart.Series[0].Points.Count - 1;
            chart.Series[0].Points[chart.Series[0].Points.Count - 1].Color = BarColor();
            chart.Series[0].Points[chart.Series[0].Points.Count - 1].Name = "name1";
        }
        public string[,] SourceData(string[] args)
        {
            string[,] Data = new string[(args.Length-1)/3, 3];
            int cnt = 1;
            for (int i = 0; i < (args.Length-1)/3; i++)
                for (int j = 0; j < 3; j++ )
                {
                    Data[i, j] = args[cnt];
                    cnt++;
                }
 
                    return Data;
        }
        
        private void Form1_Load(object sender, EventArgs e)
        {
            chart.Series.Add("Gantt");
            chart.Series[0].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.RangeBar;
            chart.Series[0].YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Date;
            chart.Series[0].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.String;
            
            chart.Series[0].IsVisibleInLegend = false;
            string[] args = Environment.GetCommandLineArgs();
            string[,] Data = SourceData(args);
            for (int i = 0; i<(args.Length-1)/3; i++)
            {
                AddBar(NoSpace(Data[i,0]), Data[i,1], Data[i,2]);
            }
        }
    }
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.08.2015, 17:56
Ответы с готовыми решениями:

Стрелки на графике
Здравствуйте, уважаемые участники форума. У меня такой вопрос, я построил график в маткаде, с...

Во сколько раз угловая скорость минутной стрелки часов больше угловой скорости часовой стрелки
Во сколько раз угловая скорость минутной стрелки часов больше угловой скорости часовой стрелки?

Стрелки подождите, стрелки не бегите! (RTC спешат)
Есть RTC VS1307N (аналог DS1307). Кварц дешевый, от производителя nonami. Корпус кварца...

QCustomPlot. Позиция точки на нарисованном графике, выделение областей на графике
Доброго времени суток! Необходима помощь сообщества. Для ведущейся работы назрела необходимость...

6
0 / 0 / 1
Регистрация: 25.08.2015
Сообщений: 6
26.08.2015, 13:47  [ТС] 2
Подскажите хотя бы, пожалуйста, может какими-то другими средствами это можно реализовать? У кого есть идеи?
0
193 / 100 / 131
Регистрация: 23.06.2015
Сообщений: 249
26.08.2015, 18:43 3
Цитата Сообщение от rapt0r Посмотреть сообщение
Подскажите хотя бы, пожалуйста, может какими-то другими средствами это можно реализовать? У кого есть идеи?
Я бы отрисовывал вручную.
0
0 / 0 / 1
Регистрация: 25.08.2015
Сообщений: 6
27.08.2015, 07:28  [ТС] 4
Я бы отрисовывал вручную.
Я думал об этом, но я не могу получить координаты точек нужных.
0
193 / 100 / 131
Регистрация: 23.06.2015
Сообщений: 249
27.08.2015, 10:39 5
Лучший ответ Сообщение было отмечено Ev_Hyper как решение

Решение

Цитата Сообщение от rapt0r Посмотреть сообщение
Я думал об этом, но я не могу получить координаты точек нужных.
Можно написать свой контрол для отображения диаграммы(я бы так делал)

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Windows.Forms;
 
namespace Gantt
{
    public class GanttDiagramm : Control
    {
        public int TitleHeight { get; set; }
        public int TasksWidth { get; set; }
        public int TaskHeight { get; set; }
        public List<GanttTask> Tasks { get; set; }
 
        static readonly Random Rand = new Random();
        public static Color GetRandomColor()
        {
            return Color.FromArgb(255, Rand.Next(220), Rand.Next(220), Rand.Next(220));
        }
 
        public GanttDiagramm()
        {
            TitleHeight = 40;
            TaskHeight = 30;
            TasksWidth = 100;
            Tasks = new List<GanttTask>();
        }
 
        public int GetRequiredHeight()
        {
            return TitleHeight + Tasks.Count * TaskHeight + 1;
        }
 
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Draw(e.Graphics);
        }
 
        public void Draw(Graphics g)
        {
            var blackPen = new Pen(Color.Black);
            var arrowPen = new Pen(Color.Sienna, 2);
            var blackPenDot = new Pen(Color.Black) { DashStyle = DashStyle.Dot };
            var blackBrush = Brushes.Black;
            g.Clear(Color.White);
            g.DrawRectangle(blackPen, 0, 0, Width - 1, TitleHeight);
            g.DrawLine(blackPen, TasksWidth, 0, TasksWidth, TitleHeight);
            g.DrawLine(blackPen, TasksWidth, TitleHeight >> 1, Width - 1, TitleHeight >> 1);
 
            g.DrawString(Text, DefaultFont, blackBrush,
                new RectangleF(TasksWidth, 0, Width - TasksWidth - 1, TitleHeight >> 1),
                new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
 
            const int dw = 17;
            for (int w = TasksWidth, j = 1; w < Width; w += dw, j++)
            {
                string s = j.ToString(CultureInfo.InvariantCulture);
                g.DrawString(s, DefaultFont, blackBrush,
                    new RectangleF(w, TitleHeight >> 1, dw, TitleHeight >> 1),
                    new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
                g.DrawLine(blackPenDot, w + dw, TitleHeight >> 1, w + dw, TitleHeight);
            }
 
            for (int i = 0, h = TitleHeight; i < Tasks.Count; i++, h += TaskHeight)
            {
                var t = Tasks[i];
                g.DrawRectangle(blackPen, 0, h, Width - 1, TaskHeight);
                g.DrawLine(blackPen, TasksWidth, h, TasksWidth, h + TaskHeight);
                g.DrawString(t.Title, DefaultFont, blackBrush,
                    new RectangleF(0, h, TasksWidth, TaskHeight),
                    new StringFormat
                    {
                        Alignment = StringAlignment.Far,
                        LineAlignment = StringAlignment.Center
                    });
 
                for (int w = TasksWidth; w < Width; w += dw)
                    g.DrawLine(blackPenDot, w + dw, h, w + dw, h + TaskHeight);
                var rect = new RectangleF((t.BeginDate - 1) * dw + (dw / 2.0f) + TasksWidth,
                    h + 6.0f, (t.EndDate - t.BeginDate) * dw, TaskHeight - 11.0f);
 
                var color = GetRandomColor();
                var colorBlend = new ColorBlend { Colors = new[] { color, color, Color.White, color }, 
                    Positions = new[] { 0f, 0.43f, 0.67f, 1.0f } };
                var lgb = new LinearGradientBrush(new RectangleF(rect.X, rect.Y + 0.8f * rect.Height,
                    rect.Width, 1.8f * rect.Height), 
                    GetRandomColor(), GetRandomColor(), LinearGradientMode.Vertical)
                {
                    InterpolationColors = colorBlend
                };
                g.FillRectangle(lgb, rect);
                DrawArrow(i, g, h, dw, arrowPen);
            }
        }
 
        protected void DrawArrow(int i, Graphics g, int h, int dw, Pen arrowPen)
        {
            if(i == 0) return;
            var x = dw * (Tasks[i - 1].EndDate - 0.5f) + TasksWidth;
            h -= TaskHeight;
            var y = h + 0.5f * TaskHeight;
            g.DrawLine(arrowPen, x, y, x + 0.5f * dw, y);
            g.DrawLine(arrowPen, x + 0.5f * dw, y, x + 0.5f * dw, h + TaskHeight);
            g.DrawLine(arrowPen, x - 0.5f * dw, h + TaskHeight, x + 0.5f * dw, h + TaskHeight);
            g.DrawLine(arrowPen, x - 0.5f * dw + 1, y + TaskHeight, x - 0.5f * dw + 1, h + TaskHeight);
            h += TaskHeight;
            y = h + 0.5f * TaskHeight;
            g.DrawLine(arrowPen, (Tasks[i].BeginDate - 1) * dw + (dw / 2.0f) + TasksWidth, y, x - 0.5f * dw, y);
            g.DrawLine(arrowPen, (Tasks[i].BeginDate - 1) * dw + (dw / 2.0f) + TasksWidth, y,
                (Tasks[i].BeginDate - 1) * dw + (dw / 2.0f) + TasksWidth - 3.0f, y + 3.0f);
            g.DrawLine(arrowPen, (Tasks[i].BeginDate - 1) * dw + (dw / 2.0f) + TasksWidth, y - 1.0f,
                (Tasks[i].BeginDate - 1) * dw + (dw / 2.0f) + TasksWidth - 3.0f, y - 4.0f);
        }
    }
 
    public class GanttTask
    {
        public int BeginDate;
        public int EndDate;
        public string Title;
 
        public GanttTask(int begin, int end, string title)
        {
            Title = title;
            BeginDate = begin;
            EndDate = end;
        }
    }
}
Использование:
C#
1
2
3
4
5
6
7
8
9
10
public Form1()
{
  InitializeComponent();
 
  ganttDiagramm1.Tasks.Add(new GanttTask(2, 10, "Построить дом"));
  ganttDiagramm1.Tasks.Add(new GanttTask(11, 13, "Посадить дерево"));
  ganttDiagramm1.Tasks.Add(new GanttTask(13, 16, "Бросить курить"));
  ganttDiagramm1.Tasks.Add(new GanttTask(16, 26, "Вырастить сына"));
  ganttDiagramm1.Height = ganttDiagramm1.GetRequiredHeight();
}
Как это выглядит:
Миниатюры
Стрелки на графике  
2
0 / 0 / 1
Регистрация: 25.08.2015
Сообщений: 6
27.08.2015, 13:04  [ТС] 6
Cuellius, здесь, как я понял график просто рисуется на форме. И, как мне кажется, для графиков с большим разбросом дат возникнут проблемы) Мне бы способ находить в компоненте Chart координаты колонок, чтобы прямо на нем стрелки нарисовать.
0
193 / 100 / 131
Регистрация: 23.06.2015
Сообщений: 249
28.08.2015, 17:45 7
Цитата Сообщение от rapt0r Посмотреть сообщение
Cuellius, здесь, как я понял график просто рисуется на форме.
Нет, на собственном контроле GanttDiagramm.
0
28.08.2015, 17:45
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.08.2015, 17:45
Помогаю со студенческими работами здесь

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

Определить по значению угла часовой стрелки значение угла для минутной стрелки
Часовая стрелка образует угол с лучом проходящим через центр и через точку соответствующую 12 часам...

Стрелки
Стрелки поражают мишень с вероятностями 0.9 и 0.7 . Они произвели залп по мишени и она была...

Стрелки
вот мое решение, этой задачи : Задана последовательность, состоящая только из символов ‘&gt;’, ‘&lt;’...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru