View Issue Details

IDProjectCategoryView StatusLast Update
0035010LazarusTAChartpublic2019-02-05 17:18
ReporterMarcin WiazowskiAssigned Towp 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version2.1 (SVN)Product Build60335 
Target Version2.0.2Fixed in Version 
Summary0035010: TAChart: tiny visual improvement
DescriptionIt's not a big thing, just a small improvement. Especially when chart is not the only form's component (so it's relatively small), resizing the form may make the chart so small, that its clipping rect becomes inverted, i.e. (Top > Bottom) and/or (Left > Right). This causes ugly visual effects - please take a look at the attached animation.


Changes in the attached patch are not very complicated:

- in TChart.PrepareAxis() the clipping rect is set - so it should be finally corrected if needed; thanks to that, the back wall drawing machinery doesn't receive an invalid rect,

- in TChartAxisList.Prepare(), an empty/invalid clipping rect should be detected, so axes should be initialized with empty rects (without this, some calculations are performed on this empty/invalid clipping rect, so axes' titles are either repositioned strangely, or some of them are still drawn),

- TChartAxis.Draw() and TChartAxis.DrawTitle() should detect empty/invalid rect and just exit.


Regards
TagsNo tags attached.
Fixed in Revision60336
LazTarget2.0.2
WidgetsetWin32/Win64
Attached Files
  • Animation.gif (133,103 bytes)
    Animation.gif (133,103 bytes)
  • Reproduce.zip (3,457 bytes)
  • patch.diff (2,852 bytes)
    Index: components/tachart/tachartaxis.pas
    ===================================================================
    --- components/tachart/tachartaxis.pas	(revision 60335)
    +++ components/tachart/tachartaxis.pas	(working copy)
    @@ -502,6 +502,7 @@
       t: TChartValueText;
     begin
       if not Visible then exit;
    +  if (FAxisRect.Left >= FAxisRect.Right) or (FAxisRect.Top >= FAxisRect.Bottom) then exit;
       FHelper.FDrawer.SetTransparency(0);
       if Marks.Visible then
         FHelper.FDrawer.Font := Marks.LabelFont;
    @@ -525,6 +526,7 @@
       d: Integer;
     begin
       if not Visible or (ASize = 0) or (FTitlePos = MaxInt) then exit;
    +  if (FTitleRect.Left >= FTitleRect.Right) or (FTitleRect.Top >= FTitleRect.Bottom) then exit;
       if Title.DistanceToCenter then
         d := Title.Distance
       else
    @@ -1147,20 +1149,32 @@
       axisRect, titleRect: TRect;
     begin
       ai := 0;
    -  for g in FGroups do begin
    -    axisRect := ARect;
    -    axis := TChartAxis(FGroupOrder[ai]);
    -    TChartAxisMargins(axisRect)[axis.Alignment] := axis.PositionToCoord(ARect);
    -    titleRect := axisRect;
    -    SideByAlignment(titleRect, axis.Alignment, g.FSize);
    -    for i := 0 to g.FCount - 1 do begin
    +  if (ARect.Left < ARect.Right) and (ARect.Top < ARect.Bottom) then begin
    +    // when ARect is valid
    +    for g in FGroups do begin
    +      axisRect := ARect;
           axis := TChartAxis(FGroupOrder[ai]);
    -      axis.FAxisRect := axisRect;
    -      axis.FTitleRect := titleRect;
    -      ai += 1;
    +      TChartAxisMargins(axisRect)[axis.Alignment] := axis.PositionToCoord(ARect);
    +      titleRect := axisRect;
    +      SideByAlignment(titleRect, axis.Alignment, g.FSize);
    +      for i := 0 to g.FCount - 1 do begin
    +        axis := TChartAxis(FGroupOrder[ai]);
    +        axis.FAxisRect := axisRect;
    +        axis.FTitleRect := titleRect;
    +        ai += 1;
    +      end;
    +      if axis.IsDefaultPosition then
    +        SideByAlignment(ARect, axis.Alignment, g.FSize + g.FTitleSize + g.FMargin);
         end;
    -    if axis.IsDefaultPosition then
    -      SideByAlignment(ARect, axis.Alignment, g.FSize + g.FTitleSize + g.FMargin);
    +  end else begin
    +    // when ARect is empty or inverted - disable drawing
    +    for g in FGroups do
    +      for i := 0 to g.FCount - 1 do begin
    +        axis := TChartAxis(FGroupOrder[ai]);
    +        axis.FAxisRect := ZeroRect;
    +        axis.FTitleRect := ZeroRect;
    +        ai += 1;
    +      end;
       end;
       InitAndSort(FZOrder, @AxisZCompare);
     end;
    Index: components/tachart/tagraph.pas
    ===================================================================
    --- components/tachart/tagraph.pas	(revision 60335)
    +++ components/tachart/tagraph.pas	(working copy)
    @@ -1505,6 +1505,9 @@
         prevExt := FCurrentExtent;
       end;
     
    +  if (FClipRect.Top >= FClipRect.Bottom) or (FClipRect.Left >= FClipRect.Right) then
    +    FClipRect := ZeroRect;
    +
       AxisList.Prepare(FClipRect);
     end;
     
    
    patch.diff (2,852 bytes)

Activities

Marcin Wiazowski

2019-02-04 23:46

reporter  

Animation.gif (133,103 bytes)
Animation.gif (133,103 bytes)

Marcin Wiazowski

2019-02-04 23:46

reporter  

Reproduce.zip (3,457 bytes)

Marcin Wiazowski

2019-02-04 23:47

reporter  

patch.diff (2,852 bytes)
Index: components/tachart/tachartaxis.pas
===================================================================
--- components/tachart/tachartaxis.pas	(revision 60335)
+++ components/tachart/tachartaxis.pas	(working copy)
@@ -502,6 +502,7 @@
   t: TChartValueText;
 begin
   if not Visible then exit;
+  if (FAxisRect.Left >= FAxisRect.Right) or (FAxisRect.Top >= FAxisRect.Bottom) then exit;
   FHelper.FDrawer.SetTransparency(0);
   if Marks.Visible then
     FHelper.FDrawer.Font := Marks.LabelFont;
@@ -525,6 +526,7 @@
   d: Integer;
 begin
   if not Visible or (ASize = 0) or (FTitlePos = MaxInt) then exit;
+  if (FTitleRect.Left >= FTitleRect.Right) or (FTitleRect.Top >= FTitleRect.Bottom) then exit;
   if Title.DistanceToCenter then
     d := Title.Distance
   else
@@ -1147,20 +1149,32 @@
   axisRect, titleRect: TRect;
 begin
   ai := 0;
-  for g in FGroups do begin
-    axisRect := ARect;
-    axis := TChartAxis(FGroupOrder[ai]);
-    TChartAxisMargins(axisRect)[axis.Alignment] := axis.PositionToCoord(ARect);
-    titleRect := axisRect;
-    SideByAlignment(titleRect, axis.Alignment, g.FSize);
-    for i := 0 to g.FCount - 1 do begin
+  if (ARect.Left < ARect.Right) and (ARect.Top < ARect.Bottom) then begin
+    // when ARect is valid
+    for g in FGroups do begin
+      axisRect := ARect;
       axis := TChartAxis(FGroupOrder[ai]);
-      axis.FAxisRect := axisRect;
-      axis.FTitleRect := titleRect;
-      ai += 1;
+      TChartAxisMargins(axisRect)[axis.Alignment] := axis.PositionToCoord(ARect);
+      titleRect := axisRect;
+      SideByAlignment(titleRect, axis.Alignment, g.FSize);
+      for i := 0 to g.FCount - 1 do begin
+        axis := TChartAxis(FGroupOrder[ai]);
+        axis.FAxisRect := axisRect;
+        axis.FTitleRect := titleRect;
+        ai += 1;
+      end;
+      if axis.IsDefaultPosition then
+        SideByAlignment(ARect, axis.Alignment, g.FSize + g.FTitleSize + g.FMargin);
     end;
-    if axis.IsDefaultPosition then
-      SideByAlignment(ARect, axis.Alignment, g.FSize + g.FTitleSize + g.FMargin);
+  end else begin
+    // when ARect is empty or inverted - disable drawing
+    for g in FGroups do
+      for i := 0 to g.FCount - 1 do begin
+        axis := TChartAxis(FGroupOrder[ai]);
+        axis.FAxisRect := ZeroRect;
+        axis.FTitleRect := ZeroRect;
+        ai += 1;
+      end;
   end;
   InitAndSort(FZOrder, @AxisZCompare);
 end;
Index: components/tachart/tagraph.pas
===================================================================
--- components/tachart/tagraph.pas	(revision 60335)
+++ components/tachart/tagraph.pas	(working copy)
@@ -1505,6 +1505,9 @@
     prevExt := FCurrentExtent;
   end;
 
+  if (FClipRect.Top >= FClipRect.Bottom) or (FClipRect.Left >= FClipRect.Right) then
+    FClipRect := ZeroRect;
+
   AxisList.Prepare(FClipRect);
 end;
 
patch.diff (2,852 bytes)

wp

2019-02-05 09:41

developer   ~0113858

I think this is not a good a idea. Having too little space for the chart is certainly a layout issue; simply hiding the chart (or parts of it) makes it less obvious that something is wrong and less probable that the issue is detected and fixed.

Instead of this patch, I published the standard property Constraints which seems to have been forgotten; it can be used to avoid reducing the chart's size below a specified limit.

Marcin Wiazowski

2019-02-05 17:18

reporter   ~0113869

Thanks.

Issue History

Date Modified Username Field Change
2019-02-04 23:46 Marcin Wiazowski New Issue
2019-02-04 23:46 Marcin Wiazowski File Added: Animation.gif
2019-02-04 23:46 Marcin Wiazowski File Added: Reproduce.zip
2019-02-04 23:47 Marcin Wiazowski File Added: patch.diff
2019-02-05 09:28 wp Assigned To => wp
2019-02-05 09:28 wp Status new => assigned
2019-02-05 09:41 wp Note Added: 0113858
2019-02-05 09:42 wp Fixed in Revision => 60336
2019-02-05 09:42 wp LazTarget => 2.0.2
2019-02-05 09:42 wp Status assigned => resolved
2019-02-05 09:42 wp Resolution open => fixed
2019-02-05 09:42 wp Target Version => 2.0.2
2019-02-05 17:18 Marcin Wiazowski Note Added: 0113869
2019-02-05 17:18 Marcin Wiazowski Status resolved => closed