Forum > TAChart
[SOLVED] Combined pointer style
CM630:
I need to combine two pointer styles in a single point of the line series - I need to have a psCross combined with another pointer (an inbuilt or a BMP one).
I suppose this is not possible.
So I decided I shall draw two points at the same coordinates and the two points should belong to a single lineseries.
But it occurs that the .pointer.style property is one for the entire series, I cannot set different pointer style to different point of the same series.
In the example image, I have overlapped two line series, each one containing a single item (point).
The pointer style of one of them is psDiamond, and the pointer style of the other is psCross.
But maybe there is a better way?
Also: The pen style for the pointers is psDashDot, but as seen from the screenshot, the lines are solid.
wp:
Two possibilities:
/1/ The line series has an event OnGetPointerStyle in which you can can change the pointer of individual data points. You can used it to draw the pointer of that particular data point as a cross for the first series, and as the other pointer for the second series (the second series should have Pointer.Style = psNone to avoid having two pointers of the other data points as well).
/2/ In this method you do not need a clone of the series. Because there is another event OnCustomDrawPointer which allows you to draw the pointer in an arbitrary way. It's a bit tricky, though, to draw the built-in pointers without repeating their drawing code: simply create a SeriesPointer, adjust its properties and call its Draw or DrawSize methods to paint it. Maybe like this:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.Chart1LineSeries1CustomDrawPointer(ASender: TChartSeries; ADrawer: IChartDrawer; AIndex: Integer; ACenter: TPoint);var p: TSeriesPointer; ps: TSeriesPointerStyle; clr: TColor; sz: Integer;begin if AIndex = 3 then begin ADrawer.SetPenParams(psSolid, clBlue, 3); ADrawer.Line(ACenter.X-10, ACenter.Y-10, ACenter.X+10, ACenter.Y+10); ADrawer.Line(ACenter.X-10, ACenter.Y+10, ACenter.X+10, ACenter.Y-10); clr := clBlue; sz := 8; ps := psCircle; end else begin clr := clRed; ps := psTriangle; sz := 5; end; p := TSeriesPointer.Create(nil); try p.Style := ps; p.HorizSize := sz; p.VertSize := sz; p.Draw(ADrawer, ACenter, clr); finally p.Free; end;end;
CM630:
--- Quote from: wp on March 18, 2024, 01:08:04 pm ---
.../2/ In this method you do not need a clone of the series. Because there is another event OnCustomDrawPointer which allows you to draw the pointer in an arbitrary way. It's a bit tricky, though, to draw the built-in pointers without repeating their drawing code: simply create a SeriesPointer, adjust its properties and call its Draw or DrawSize methods to paint it...
--- End quote ---
Draw and DrawSize require and IChartDrawer, and there seem to be multiple kinds of drawers. I do not know which of them I shall use.
Without calling Draw the OnCustomDrawPointer event does not fire.
wp:
--- Quote from: CM630 on March 18, 2024, 03:04:17 pm ---
--- Quote from: wp on March 18, 2024, 01:08:04 pm ---.../2/ In this method you do not need a clone of the series. Because there is another event OnCustomDrawPointer which allows you to draw the pointer in an arbitrary way. It's a bit tricky, though, to draw the built-in pointers without repeating their drawing code: simply create a SeriesPointer, adjust its properties and call its Draw or DrawSize methods to paint it...
--- End quote ---
Draw and DrawSize require and IChartDrawer, and there seem to be multiple kinds of drawers. I do not know which of them I shall use.
--- End quote ---
The currently active drawer comes as a parameter of the event handler.
--- Quote from: CM630 on March 18, 2024, 03:04:17 pm ---Without calling Draw the OnCustomDrawPointer event does not fire.
--- End quote ---
OnCustomdrawPointer fires during the Paint cycle whenever a pointer must be drawn. When you need the pointer at a specific occasion call Chart.Invalidate or Chart.Repaint.
Note also that the property LineSeries.Pointer.Visible (or LineSeries.ShowPoints) must be set to true, otherwise the pointer drawing procedure is not called.
I am attaching to little project which I wrote and tested before answering you post.
CM630:
Thanks, this exceeds my expectations indeed!!!
I have simplified the code because I have a separate TLineSeries for each cursor.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TWaveformGraph.CursorOnCustomDrawPointer(ASender: TChartSeries; ADrawer: IChartDrawer; AIndex: Integer; ACenter: TPoint);const CrsH= 10; CrsV= 10;begin //Draw cross ADrawer.SetPenParams(psSolid, clRed, 1); ADrawer.Line(ACenter.X, ACenter.Y-CrsV, ACenter.X, ACenter.Y+CrsV); //Vertical bar ADrawer.Line(ACenter.X-CrsH, ACenter.Y, ACenter.X+CrsH, ACenter.Y); //Horizontal bar try TLineSeries(ASender).Pointer.Draw(ADrawer,ACenter,TLineSeries(ASender).Pointer.Pen.Color); except end;end; There is some more work to do, in order to apply the proper bars length, but for now it looks close to what it shall be.
But, since I have come across it, is this a bug:
--- Quote ---...The pen style for the pointers is psDashDot, but as seen from the screenshot, the lines are solid...
--- End quote ---
Navigation
[0] Message Index
[#] Next page