Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: TBitMap question


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Mar 27, 2017 7:56 AM Last Post By: Alan Jordan Threads: [ Previous | Next ]
Alan Jordan

Posts: 222
Registered: 3/2/01
TBitMap question  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 23, 2017 2:05 PM
I have a component that draws a graph from a table similar to a spreadsheet. In the graph component, I have a TRect that describes the viewport of the graph. I want to draw a vertical line on the graph when a user clicks on a cell of the table. I am able to draw the graph and the associated line, but when I click on another cell the first line is still there after the second line is drawn. I have tried all of the Canvas.Pen.Mode choices and each has something left. I think I want to make a copy of the original graph before any lines are drawn and copy this image back and then draw the line. How can I do that? I have looked at TBitMap, but am not clear how to use this.
Remy Lebeau (Te...


Posts: 8,716
Registered: 12/23/01
Re: TBitMap question  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 23, 2017 2:48 PM   in response to: Alan Jordan in response to: Alan Jordan
Alan wrote::

I want to draw a vertical line on the graph when a user clicks on a
cell of the table. I am able to draw the graph and the associated
line, but when I click on another cell the first line is still there after
the second line is drawn.

That implies that you are maintaining a persistent drawing of the graph and
you are drawing the lines on that image. Don't do that. Since the lines
are dynamic, draw them dynamically only when they are actually needed.

I think I want to make a copy of the original graph before any lines
are drawn and copy this image back and then draw the line. How
can I do that?

That is overkill, you don't need to do it that way. Simply keep track of
which cell was last clicked on, and make sure each click calls the the component's
Invalidate() method after updating that tracking info. Then, whenever the
component is painted, first draw the main graph onto the component, then
draw the current line on top of that drawing if a cell has been clicked.

If you need help with that, please show your current component code, and
someone can show you how to insert the extra logic.

I have looked at TBitMap, but am not clear how to use this.

Then how are you drawing the graph to begin with?

--
Remy Lebeau (TeamB)
Alan Jordan

Posts: 222
Registered: 3/2/01
Re: TBitMap question  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 27, 2017 7:56 AM   in response to: Alan Jordan in response to: Alan Jordan
Here is the code that works: Data1 is the spreadsheet component, and of course DeltaGraph1 is the graph.
In the table cell click: Notice that I turn off the old line, then redraw the graph and finally draw the new line.
procedure TForm1.Data1Click(Sender: TObject);
begin
if TurnOnOffGrp.ItemIndex=0 then
begin
if (OldCl>=0) and (OldRw>=0) then
begin
with DeltaGraph1 do
DeltaGraph1.TurnOffLastLine(OldCol, OldRow); // if I only turn off the line and don’t redraw the graph, there is a gap where the line was taken out.
end;
DeltaGraph1.DrawGraph; // have to redraw the graph to eliminate the gap.
DeltaGraph1.DrawVertLine(Data1.Col,Data1.Row);
OldCl:=Data1.Col;
OldRw:=Data1.Row;
end;
end;

Here is the code for turning off the line:

procedure TDeltaGraph.TurnOffLastLine( Cl, Rw : Integer );
var
Xd1 : Double;
XAxis : TAxis;
YAxis : TAxis;
Pt1, Pt2 : TPoint;
Color : TColor;
OldColor : TColor;
begin
XAxis:=FAxes.Items[0].Axis; // horiz axis
YAxis:=FAxes.Items[Cl].Axis; // This gets the axis for
Xd1:=Data.PlotCells[0, Rw]; // gets the data point on Horiz axis in Col 0
Pt1.X:=XAxis.GetUToSX(Xd1); // convert to an integer for plotting
Pt2.X:=Pt1.X; // End point of the axis I am moving is vertically above first point
Pt1.Y:=YAxis.StartAxis.Y; // YAxis start point
Pt2.Y:=YAxis.EndAxis.Y; // YAxis End point
OldColor:=Canvas.Pen.Color;
Canvas.Pen.Color:=clBtnFace; // Canvas.Brush.Color;
Canvas.MoveTo(Pt1.X,Pt1.Y);
Canvas.LineTo(Pt2.X,Pt2.Y);
Canvas.Pen.Color:=OldColor;
end;

And finally to draw the new line:

procedure TDeltaGraph.DrawVertLine(Cl, Rw : Integer);
var
Xd1 : Double;
XAxis : TAxis;
YAxis : TAxis;
Pt1, Pt2 : TPoint;
OldColor : TColor;
Rect : TRect;
begin
XAxis:=FAxes.Items[0].Axis; // horiz axis
YAxis:=FAxes.Items[Cl].Axis; // This gets the axis for
Xd1:=Data.PlotCells[0,Rw]; // gets the data point on Horiz axis in Col 0
Pt1.X:=XAxis.GetUToSX(Xd1); // convert to an integer for plotting
Pt2.X:=Pt1.X; // End point of the axis I am moving is vertically above first point
Pt1.Y:=YAxis.StartAxis.Y; // YAxis start point
Pt2.Y:=YAxis.EndAxis.Y; // YAxis End point
{ Rect.Left:=Pt1.X-2; Setting up a rectangle to copy did not use This is what I was trying to copy for one line
Rect.Right:=Pt1.X+2;
Rect.Bottom:=Pt1.Y+1;
Rect.Top:=Pt2.Y+1;
FCopyRect:=Rect; // Rectangle to copy did not use }
OldColor:=Canvas.Pen.Color;
Canvas.Pen.Color:=YAxis.AxisColor;
Canvas.Pen.Mode:=pmCopy;
Canvas.MoveTo(Pt1.X,Pt1.Y);
Canvas.LineTo(Pt2.X,Pt2.Y);
Canvas.Pen.Color:=OldColor;
FOldPt1:=Pt1;
FOldPt2:=Pt2;
FOldCl:=Cl;
FOldRw:=Rw;
end;

My question is: Would it be faster to use a TBitMap to copy all, or part of the graph and restore, instead of redrawing the graph?
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02