![]() | Steema Issues DatabaseNote: This database is for bugs and wishes only. For technical support help, if you are a customer please visit our online forums;otherwise you can use StackOverflow. Before using this bug-tracker we recommend a look at this document, Steema Bug Fixing Policy. |
| Summary: | Matching values on pie chart can swap colors on refresh | ||
|---|---|---|---|
| Product: | VCL TeeChart | Reporter: | swensonk |
| Component: | Chart | Assignee: | Steema Issue Manager <issuemanager> |
| Status: | RESOLVED FIXED | ||
| Severity: | normal | CC: | david |
| Priority: | --- | ||
| Version: | unspecified | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows | ||
| Chart Series: | --- | Delphi / C++ Builder RAD IDE Version: | |
| Attachments: | Example of the original followed by the refresh | ||
This problem is caused because there are duplicated Pie series values, and PieValues.Order := loAscending. The internal sorting algorithm to order pie slices is a QuickSort, which is an "unstable" algorithm (it will swap duplicate values each run). Code below reproduces the problem, clicking Button1: procedure TForm1.Button1Click(Sender: TObject); begin Series1.Repaint; end; procedure TForm1.FormCreate(Sender: TObject); begin Series1.Clear; Series1.Add(887,'a'); Series1.Add(514,'b'); Series1.Add(565,'c'); Series1.Add(109,'d'); Series1.Add(116,'e'); Series1.Add(116,'f'); Series1.Add(985,'g'); Series1.Add(898,'h'); Series1.PieValues.Order:=loAscending; end; We'll try to modify QuickSort to make it "stable", to avoid reordering. Fixed. Changed source code below (TeEngine.pas unit, TChartSeries.CompareValueIndex method)
Function TChartValueList.CompareValueIndex(a,b:Integer):Integer;
var tmpA : TChartValue;
tmpB : TChartValue;
begin
tmpA:=Value[a];
tmpB:=Value[b];
if tmpA<tmpB then result:=-1
else
if tmpA>tmpB then result:=1
else
begin
// Use "a" and "b" indexes to avoid "unstable" results:
if a<b then
result:=-1 // -1 always, for both cases FOrder ascending or descending
else
result:=0;
Exit;
end;
if FOrder=loDescending then
result:=-result;
end;
|
Created attachment 63 [details] Example of the original followed by the refresh We are using a chart with a gradient and marks. But when we print these we disable the gradient and marks, and refresh the chart. If you have two matching values, these can items can swap colors in the legend. The following is the code we are using that is during the swap in colors. procedure TfrmPieChart.tbPrintClick(Sender: TObject); var OldOrient : TPrinterOrientation; begin PieChart.PrintMargins.Left := 3; PieChart.PrintMargins.Top := 3; PieChart.PrintMargins.Right := 3; PieChart.PrintMargins.Bottom := 3; PieChart.Gradient.Visible := False; PieChart.Border.Visible := False; PieChart.Shadow.Visible := False; PieChart.BevelOuter := bvNone; Series1.Marks.Visible := False; Series2.Marks.Visible := False; Series3.Marks.Visible := False; Series4.Marks.Visible := False; Printer.PrinterIndex := Printer.Printers.IndexOf(SysObject.ReportPrinter); if (Printer.PrinterIndex > -1) and (SysObject.ReportPrinterTray <> '') then begin SelectPrinterBin(PrinterBinGetIndex(SysObject.ReportPrinter, SysObject.ReportPrinterTray)); end; OldOrient := Printer.Orientation; Printer.Orientation := poLandscape; if printdialog1.Execute then begin Printer.BeginDoc; try PieChart.Canvas := TTeeCanvas3D.Create; PieChart.PrintPartial(PieChart.ChartPrintRect); finally Printer.EndDoc end; end; Printer.Orientation := OldOrient; PieChart.Canvas:=TGDIPlusCanvas.Create; PieChart.Gradient.Visible := True; Series1.Marks.Visible := True; Series2.Marks.Visible := True; Series3.Marks.Visible := True; Series4.Marks.Visible := True; PieChart.Refresh; //Reset chart to original settings end;