§ 15. Пабудова графікаў функцый і дыяграм

15.2. Пабудова дыяграм

Разгледзім асноўныя прынцыпы пабудовы гістаграм на прыкладах пабудовы гістаграмы і кругавой дыяграмы. Інтэрактыўнасць у дадзеным выпадку забяспечваецца данымі ў файле.

Прыклад 15.3. Стварыць праект, у якім неабходна пабудаваць гістаграму па даных з масіва з n элементаў. Значэнні элементаў масіва лічыць з тэкставага файла. Тэкставы файл змясціць у папку Win32\Debug. У гэтым выпадку для доступу да файла досыць прапісаць імя файла. Калі файл захоўваецца ў іншым месцы, то для доступу да файла неабходна прапісаць поўны шлях.

Этапы выканання задання

  1. Змясціць на форму кампаненты: малюнак (Image) і кнопка (Button).
  2. Змяніць уласцівасці Caption у кампанента Button1 на «Построить».
  3. Устанавіць памеры Image — 600 × 400.
  4. Напісаць апрацоўшчык падзеі OnClick для кампанента Button1, у якім дыяграма будуецца з дапамогай прамавугольнікаў.

4.1. Лічыць даныя з файла ў масівы: масіў d — захоўвае колькасці, па якіх будуецца дыяграма; масіў s — подпісы элементаў. Для працы з файламі падключыць бібліятэку <fstream>. Для чытання радкоў з файла падключыць бібліятэку <string>, для працы з масівамі — бібліятэку <vector>. Прапісаць дырэктыву Using NameSpace std для звароту да каманд стандартных бібліятэк.
4.2. Знайсці максімальны элемент у масіве — элемент n_max, які стаіць на месцы.
4.3. Разлічыць маштабны каэфіцыент: . Для таго каб пакінуць месца для вываду надпісаў, ад вышыні формы адымаем 40.
4.4. У цыкле будаваць n прамавугольнікаў аднолькавай шырыні. Шырыня прамавугольніка —  .Вышыня прамавугольніка вызначаецца значэннем , пераўтвораным да цэлага тыпу. Колер прамавугольнікаў задаваць выпадкова — кожны складальнік колеру змяняецца ў дыяпазоне ад 1 да 245 (выключаем чорны колер і колеры блізкія да белага).
4.5. Вывесці надпісы над прамавугольнікамі. Для вываду радкоў, лічаных з файла, іх трэба пераўтварыць так, каб можна было вывесці на канву. Для гэтага можна скарыстацца функцыяй c_str().

Прыклад 15.4. Стварыць праект, у якім трэба пабудаваць кругавую дыяграму па даным з масіва. Значэнні элементаў масіва лічыць з тэкставага файла. Тэкставы файл змясціць у папку Win32\Debug.

  1. Змясціць на форму кампаненты: малюнак (Image) і кнопка (Button).
  2. Змяніць уласцівасці Caption у кампанента Button1 на «Построить».
  3. Устанавіць памеры Image — 500 × 500.
  4. Для працы з файламі падключыць бібліятэку <fstream>. Для чытання радкоў з файла падключыць бібліятэку <string>, для працы з масівамі — бібліятэку <vector>. Для вылічэнняў спатрэбяцца трыганаметрычныя функцыі, таму неабходна падключыць бібліятэку <cmath>.  Прапісаць дырэктыву using namespace std для звароту да каманд стандартных бібліятэк.
  5. Напісаць апрацоўшчык падзеі OnClick для кампанента Button1, у якім дыяграма будуецца з дапамогай сектараў.

5.1. Лічыць даныя з файла ў масіў.
5.2. Знайсці суму элементаў масіва — sum.
5.3. Разлічыць маштабны каэфіцыент: .
5.4. У цыкле будаваць n сектараў. Колер сектара задаваць выпадкова — кожны складальнік колеру змяняецца ў дыяпазоне ад 1 да 245 (выключаем чорны колер і колеры блізкія да белага).
5.5. Сектары вызначаюцца кругам радыуса R, упісаным у квадрат з каардынатамі дыяганалі (x1; y1) — (x2; y2). Значэнні x1 = 50, y1 = 50, x2 = x1 + 2R, y2 = y1 + 2R, R = 200.
5.6. Разлік ключавых пунктаў для пабудовы сектара (гл. малюнак).
5.7. Для пабудовы сектара каардынаты пунктаў (x3; y3) і (x4; y4) трэба пераўтварыць у экранныя: павялічыць гарызантальныя на , а ў вертыкальных памяняць знак і павялічыць на  
5.8. Вывесці надпісы ўверсе кампанента Image. Для вываду радкоў, лічаных з файла, іх трэба пераўтварыць так, каб можна было вывесці на канву. Для гэтага можна скарыстацца функцыяй c_str (). Месцазнаходжанне надпісу разлічваецца так жа, як і для гістаграмы.

Прыклад 15.3. Форма на этапе канструявання:

Тэкставы файл з данымі:

Падключэнне бібліятэк:

Апрацоўшчык падзеі OnClick для кампанента Button1.

void __fastcall TForm1::Button1Click(TObject *Sender)

{

  //чытанне даных з файла

  ifstream fin("date.txt");

  int n;

  fin >> n;

  vector <int> d(n);

  vector <string> s(n);

  for(int i = 0; i < n; i++)

    fin >> s[i] >> d[i];

  //пошук максімальнага

  int n_max = 0;

  for (int i = 0; i < n; i++)

    if (d[i] > d[n_max])

      n_max = i;

  //каэфіцыент маштабавання

  int  h = Image1 -> Height - 40;

  double k = 1. * h / d[n_max];

  //шырыня слупка

  int w = Image1 -> Width/(2 * n + 1);

  int x = w;

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

    //колер

    int cr = rand()245 + 1;

    int cg = rand()245 + 1;

    int cb = rand()245 + 1;

    TColor c = TColor (RGB(cr, cg, cb));

    Image1 -> Canvas -> Brush -> Color = c;

    Image1 -> Canvas -> Rectangle

    (x, h + 40, x + w, h - (int)(k * d[i]) + 30);

    //надпіс

    Image1 -> Canvas -> Brush -> Color = clWhite;

    Image1 -> Canvas -> Font -> Color = c;

    Image1 -> Canvas -> TextOut

      (x + 33, s[i].c_str());

    //пераход да наступнага слупка

    x += 2 * w;

  }

}

Дадатак у час працы:

Прыклад 15.4. Форма на этапе канструявання:

Разлік ключавых пунктаў для пабудовы сектара:

Велічыня вугла u2 адпавядае бягучаму значэнню даных з масіва і роўная . Велічыня вугла u1 — сумарнае значэнне вуглоў для ўжо пабудаваных сектараў. Спачатку u1 = 0.

Значэнні x3 і y3 — катэты прамавугольнага трохвугольніка з вуглом u1 і гіпатэнузай роўнай радыусу круга, таму x3 = cos u1, y3 = sin u1.

Аналагічна вызначаем x4 і y4:  y4 = cos (u1 + u2), y4 = sin (u1 + u2).

Апрацоўшчык падзеі OnClick для кампанента Button1.

void __fastcall TForm1::Button1Click
               (TObject *Sender)

{

  //чытанне даных з файла

  ifstream fin("date.txt");

  int n;

  fin >> n;

  vector <int> d(n);

  vector <string> s(n);

  for(int i = 0; i < n; i++)

    fin >> s[i] >> d[i];

  //пошук сумы

  int sum = 0;

  for (int i = 0; i < n; i++)

    sum += d[i];

  //каэфіцыент маштабавання

  double pi = acos(-1.);

  double k = 2 * pi / sum;

  //вызначэнне круга

  double u1 = 0;

  int w = Image1 -> Width/(2 * n + 1);

  int x = w ;

  int R = 200;

  int x1 = 50, y1 = 50;

  int x2 = x1 + 2 * R, y2 = y1 + 2 * R;

  //цэнтр вобласці пабудовы

  int c_X = Image1 -> Width / 2;

  int c_Y = Image1 -> Height / 2;

  for (int i = 0; i < n - 1; i++){

    double u2 = k * d[i];

    int x3 = int (R * cos(u1)) + c_X;

    int y3 = c_Y - int (R * sin(u1));

    int x4 = int (R * cos(u1 + u2)) + c_X;

    int y4 = c_Y - int (R * sin(u1 + u2));

    //колер

    int cr = rand()255 + 1;

    int cg = rand()255 + 1;

    int cb = rand()255 + 1;

    TColor c = TColor (RGB(cr, cg, cb));

    Image1 -> Canvas -> Brush -> Color = c;

    //сектар

    Image1 -> Canvas -> Pie

    (x1, y1, x2, y2, x3, y3, x4, y4);

    //пераход да наступнага сектару

    u1 += u2;

    //надпіс

    Image1 -> Canvas -> Brush -> Color = clWhite;

    Image1 -> Canvas -> Font -> Color = c;

    Image1 -> Canvas -> 

    TextOut(x + 33, s[i].c_str());

    //пераход да наступнага надпісу

    x += 2 * w;

 Дадатак у час працы: