Сохранение целого TAChart в графический файл [Решено]

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
mig-31
постоялец
Сообщения: 224
Зарегистрирован: 14.07.2011 13:46:48

Сохранение целого TAChart в графический файл [Решено]

Сообщение mig-31 »

На форме лежит TAChart с TChartNavScrollBar. Как сохранить целый TAChart в графический файл при его увеличении?
Стандартно после увеличения сохраняеться только его видимая часть (увеличенная) а надо целый увеличенный.

Спасибо за ответыю
Последний раз редактировалось mig-31 11.01.2013 17:57:21, всего редактировалось 1 раз.
Ask
постоялец
Сообщения: 163
Зарегистрирован: 25.12.2008 02:51:37

Re: Сохранение целого TAChart в графический файл

Сообщение Ask »

Я уже отвечал на этот вопрос здесь.
Что не так в моём ответе?

Edit: а, кажется понял.
Хочется сохранить картинку большого размера, так чтобы масштаб сохранился?
Тут есть два момента:
1) Нужно аккуратно проверить масштаб, при сильном увеличении картинка будет очень большая, может запросто переполнить память.
2) Во втором методе (с клонированием) перед выполнением ZoomFull увеличить ширину и высоту клона пропорционально коэффициенту масштабирования.
mig-31
постоялец
Сообщения: 224
Зарегистрирован: 14.07.2011 13:46:48

Re: Сохранение целого TAChart в графический файл

Сообщение mig-31 »

Хочется сохранить картинку большого размера, так чтобы масштаб сохранился?

Да. Чтобы увеличение осталось, а в файл бы сохранился целый увеличенный график, а не только видимая увеличенная часть.
Ask
постоялец
Сообщения: 163
Зарегистрирован: 25.12.2008 02:51:37

Re: Сохранение целого TAChart в графический файл

Сообщение Ask »

Ок, значит последний рецепт должен помочь
mig-31
постоялец
Сообщения: 224
Зарегистрирован: 14.07.2011 13:46:48

Re: Сохранение целого TAChart в графический файл

Сообщение mig-31 »

Спасибо за подсказку.
Если я правильно понимаю так для после вызова Clone его не надо записывать в переменную типа TChart.
Как получить реальные размеры целого графика после увеличения? Свойства Chart1.Width and Chart1.Height возвращают размер видимой области увеличения.
Ask
постоялец
Сообщения: 163
Зарегистрирован: 25.12.2008 02:51:37

Re: Сохранение целого TAChart в графический файл

Сообщение Ask »

после вызова Clone его не надо записывать в переменную типа TChart

это уж по желанию, вопрос стиля

Свойства Chart1.Width and Chart1.Height возвращают размер видимой области увеличения.

Вот, их надо умножить на коэффициент масштабирования.
Его можно получить, например, поделив FullExtent на CurrentExtent.
mig-31
постоялец
Сообщения: 224
Зарегистрирован: 14.07.2011 13:46:48

Re: Сохранение целого TAChart в графический файл

Сообщение mig-31 »

Так же Chart1.Clone уже инициализированная переменная типа TChart.
mig-31
постоялец
Сообщения: 224
Зарегистрирован: 14.07.2011 13:46:48

Re: Сохранение целого TAChart в графический файл

Сообщение mig-31 »

При использовании Clone создаеться пустой график. Не копируться свойства и линии, столбцы.
Пробовал в WinXP32 bit Lazarus 1.1 39507.

Clone работает только если график создан в Design режиме. Если график создан в рантайме, так создаеться пустой клон без серий.
Баг ли это?

Как создать идентичную копию в рантайме.
Ask
постоялец
Сообщения: 163
Зарегистрирован: 25.12.2008 02:51:37

Re: Сохранение целого TAChart в графический файл

Сообщение Ask »

Clone работает только если график создан в Design режиме.

О как! А Я только что ответил в английском форуме, что всё вроде как должно работать.

Баг ли это?

Баг, конечно, но шансы на исправление невелики, там клонирование через сериализацию,
так что баг вполне может оказаться в глубине FPC.
При желании можно занести в багтрекер.

Для решения исходной задачи предлагаю тогда такой вариант:
использовать первый метод (через сохранение RenderingParams),
но вместо SaveToFile создать bitmap самому и использовать PaintOnCanvas
(см. собственно код SaveToFile/SaveToImage для примера).
mig-31
постоялец
Сообщения: 224
Зарегистрирован: 14.07.2011 13:46:48

Re: Сохранение целого TAChart в графический файл

Сообщение mig-31 »

Ask писал(а):При желании можно занести в багтрекер.

Проверю, если в Линухе тоже самое и занесу в багтрекер.

Ask писал(а):(см. собственно код SaveToFile/SaveToImage для примера).

Спасибо за подсказку.
Но как мне кажеться будет проблема с размерами Canvas. Размер Canvas = размеру TChart, а в случае использования TChartNavScrollBar для прокрутки TChart, Размер Canvas = размеру видимой областиTChart.
Ask
постоялец
Сообщения: 163
Зарегистрирован: 25.12.2008 02:51:37

Re: Сохранение целого TAChart в графический файл

Сообщение Ask »

Вот так, например :

Код: Выделить всё

uses TAChartUtils, TAGeometry;

procedure TForm1.tbSaveAsJPEGClick(Sender: TObject);
var
  rp: TChartRenderingParams;
  fn: String;
  img: TJPEGImage;
  scale: TDoublePoint;
begin
  fn := GetFileName('jpg');
  with Chart1.GetFullExtent do
    scale := b - a;
  with  Chart1.LogicalExtent do
    scale /= b - a;
  rp := Chart1.RenderingParams;
  img := TJPEGImage.Create;
  try
    img.Width := Round(Chart1.Width * scale.X);
    img.Height := Round(Chart1.Height * scale.Y);
    Chart1.ZoomFull;
    Chart1.PaintOnCanvas(img.Canvas, Rect(0, 0, img.Width, img.Height));
    img.SaveToFile(fn);
  finally
    img.Free;
    Chart1.RenderingParams := rp;
  end;
end;
mig-31
постоялец
Сообщения: 224
Зарегистрирован: 14.07.2011 13:46:48

Re: Сохранение целого TAChart в графический файл

Сообщение mig-31 »

Спасибо Ask.
Работает, как вы и говорили.

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

Код: Выделить всё

procedure TMainForm.SaveChartToJpgFile(Sender: TObject);
var
  rp:TChartRenderingParams;
  ChartPicture:TJPEGImage;
  scale: TDoublePoint;
begin
  SaveDialog.DefaultExt:='.jpg';
  if SaveDialog.Execute then
  with QueryChart do begin
   scale.X:=GetFullExtent.b.X/CurrentExtent.b.x;
   scale.Y:=GetFullExtent.b.Y/CurrentExtent.b.Y;
   rp:=RenderingParams;
   ChartPicture:=TJPEGImage.Create;
   ChartPicture.CompressionQuality:=100;
   try
     ChartPicture.Width:=round(Width*scale.X);
     ChartPicture.Height:=round(Height*scale.Y);
     QueryChart.ZoomFull;
     QueryChart.PaintOnCanvas(ChartPicture.Canvas, Rect(0,0,ChartPicture.Width,ChartPicture.Height));
     ChartPicture.SaveToFile(SaveDialog.FileName);
   finally
     ChartPicture.Free;
     RenderingParams:=rp;
   end;
  end;
end;   

Ответить