⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 teecirculargauge.pas

📁 BCB第三方组件
💻 PAS
📖 第 1 页 / 共 2 页
字号:
          tmp2 := TeePiStep * (tmpAngle - (Ticks.HorizSize * 0.1));
          P3Minus := CalcPoint(tmp2, ICenter, tmpXRad, tmpYRad);

          tmp2 := TeePiStep * (tmpAngle + (Ticks.HorizSize * 0.2));
          P4Plus := CalcPoint(tmp2, ICenter, tmpXRadius, tmpYRadius);
          tmp2 := TeePiStep * (tmpAngle - (Ticks.HorizSize * 0.2));
          P4Minus := CalcPoint(tmp2, ICenter, tmpXRadius, tmpYRadius);

          DrawAxisTick(P3, P3Plus, P3Minus, P4, P4Plus, P4Minus);

          if Axis.Labels then
          begin
            tmpS := FormatFloat(ValueFormat, tmpValue);
            tmpWidth := ParentChart.Canvas.TextWidth(tmpS);

            ParentChart.Canvas.BackMode:=cbmTransparent;

            if RotateLabels then
            begin
              tmpAngle2 := CalcAngleFromLength(P4, tmpWidth) * 0.5;

              if LabelsInside then
                 P3 := CalcPoint(tmp - tmpAngle2, ICenter,
                        tmpXRad - (tmpFontH * 0.25), tmpYRad - (tmpFontH * 0.25))
              else
                 P3 := CalcPoint(tmp - tmpAngle2, ICenter,
                        tmpXRadius + tmpFontH, tmpYRadius + tmpFontH);

              ParentChart.Canvas.RotateLabel(P3.X, P3.Y, tmpS, 90 - tmpAngle);
            end
            else
            begin
              if LabelsInside then
              begin
                P3 := CalcPoint(tmp, ICenter, tmpXRad - (tmpFontH * 0.5),
                                tmpYRad - (tmpFontH * 0.5));

                tmpAngle2 := tmpAngle - 90;

                if tmpAngle2 < 0 then
                   tmpAngle2 := tmpAngle2 * -1;

                Dec(P3.Y, Round(tmpFontH * ((1.0 / 180.0) * tmpAngle2)));
              end
              else
                P3 := CalcPoint(tmp, ICenter, tmpXRadius + tmpFontH, tmpYRadius + tmpFontH);

              tmpAngle2 := tmpAngle;

              if (tmpAngle2 > 180) then
                 tmpAngle2 := 180 - (tmpAngle2 - 180);

              if (tmpAngle2 < 0) then
                 tmpAngle2 := -tmpAngle2;

              Dec(P3.X, Round(tmpWidth * ((1.0 / 180.0) * tmpAngle2)));

              ParentChart.Canvas.TextOut(P3.X, P3.Y, tmpS);
            end
          end;

          tmpValue:=tmpValue + tmpStep;

        until tmpValue>Maximum;
      end;
    end;

    if (IRange<>0) and Axis.MinorTicks.Visible and (Axis.MinorTickCount>0) then
    begin
      Axis.MinorTickLength:=MinorTicks.VertSize;
      Axis.MinorTicks.Assign(MinorTicks.Pen);
      ParentChart.Canvas.AssignVisiblePen(MinorTicks.Pen);

      tmpXRad:= tmpXRadius - Axis.MinorTickLength - MinorTickDistance;
      tmpYRad:= tmpYRadius - Axis.MinorTickLength - MinorTickDistance;

      if tmpStep<>0 then
      begin
        tmpStep2 := tmpStep / (Axis.MinorTickCount + 1);
        tmpValue := Minimum;

        repeat
          for t:=1 to Axis.MinorTickCount do
          begin
            tmpAngle := (IStartAngle - 90) + ((tmpValue + t * tmpStep2) * TotalAngle / IRange);
            tmp := TeePiStep * tmpAngle;

            DrawAxisMinorTick(CalcPoint(tmp, ICenter, tmpXRad, tmpYRad),
                 CalcPoint(tmp, ICenter, tmpXRadius - MinorTickDistance, tmpYRadius - MinorTickDistance));
          end;

          tmpValue := tmpValue + tmpStep;

        until tmpValue > (Maximum - tmpStep);
      end;
    end;
  end;
end;

function TCircularGauge.CalcSweepAngle:Double;
begin
  result:=TotalAngle;
end;

function TCircularGauge.CalcStartAngle:Double;
begin
  result:=((360-TotalAngle)*0.5)+RotationAngle;
end;

function TCircularGauge.CalcValue(const AValue:Double):Double;
begin
  result:=((AValue*IAngleInc)+IStartAngle);
end;

function TCircularGauge.CalcDistance(Distance:Integer):Integer;
var tmp : Integer;
begin
  if Distance > 0 then
  begin
    tmp:=Min(XRadius, YRadius);

    if Axis.Visible then
       Dec(tmp,Axis.TickLength);

    result:=Round(Distance * tmp* 0.01 );
  end
  else
     result:=0;
end;

procedure TCircularGauge.DrawHand;
var tmpAngle : Double;
begin
  tmpAngle:=CalcValue(Value);

  if Hand.Visible then
  begin
    Hand.VertSize:=Max(1,CalcDistance(100-Hand.Distance));
    Hand.Draw(tmpAngle,ICenter,CalcDistance(Hand.Offset));
  end;

  DrawEnd(tmpAngle);
  DrawCenter;
end;

procedure TCircularGauge.DrawCenter;
begin
  if Center.Visible then
  begin
    Center.PrepareCanvas(ParentChart.Canvas,Center.Color);

    Center.Gradient.Angle:=90+Round(CalcValue(Value));
    Center.Draw(CircleXCenter,CircleYCenter);
  end;
end;

procedure TCircularGauge.DrawEnd(Angle:Double);

    Function RotatePoint(const AX,AY:Integer):TPoint;
    var tmpSin : Extended;
        tmpCos : Extended;
    begin
      SinCos(angle*TeePiStep,tmpSin,tmpCos);
      result.X:=ICenter.X-Round( AX*tmpCos + AY*tmpSin);
      result.Y:=ICenter.Y+Round(-AX*tmpSin + AY*tmpCos);
    end;

var tmp : TPoint;
begin
  if EndPoint.Visible then
  begin
    tmp:=RotatePoint(0,CalcDistance(95));
    EndPoint.PrepareCanvas(ParentChart.Canvas,EndPoint.Color);
    EndPoint.Draw(tmp.X,tmp.Y,EndPoint.Color, EndPoint.Style);
  end;
end;

procedure TCircularGauge.Assign(Source: TPersistent);
begin
  if Source is TCircularGauge then
  with TCircularGauge(Source) do
  begin
    Self.Center:=Center;
    Self.FCircled:=FCircled;
    Self.EndPoint:=EndPoint;
    Self.Hand:=Hand;
    Self.FLabelsInside:=FLabelsInside;
    Self.FRotateLabels:=FRotateLabels;
    Self.FRotAngle:=FRotAngle;
    Self.FTotalAngle:=FTotalAngle;
  end;

  inherited;
end;

class function TCircularGauge.GetEditorClass: String;
begin
  result:='TCircularGaugeEditor';
end;

Procedure TCircularGauge.DoBeforeDrawValues;
begin
  inherited;
  CalcRadius;
end;

Procedure TCircularGauge.CalcRadius;
begin
  with INewRect do
  begin
    FXRadius:=(Right-Left) div 2;
    FYRadius:=(Bottom-Top) div 2;

    ICenter.X := (Right+Left) div 2;
    ICenter.Y := (Top+Bottom) div 2;
  end;
end;

procedure TCircularGauge.SetCenter(const Value: TGaugeSeriesPointer);
begin
  FCenter.Assign(Value);
end;

procedure TCircularGauge.SetCircled(const Value:Boolean);
begin
  SetBooleanProperty(FCircled,Value);
end;

procedure TCircularGauge.SetEndPoint(const Value: TSeriesPointer);
begin
  FEndPoint.Assign(Value);
end;

function TCircularGauge.Axis:TChartAxis;
begin
  result:=GetHorizAxis;
end;

procedure TCircularGauge.SetHand(const Value: TGaugeHand);
begin
  FHand.Assign(Value);
end;

procedure TCircularGauge.SetLabelsInside(const Value: Boolean);
begin
  SetBooleanProperty(FLabelsInside,Value);
end;

procedure TCircularGauge.SetRotateLabels(const Value: Boolean);
begin
  SetBooleanProperty(FRotateLabels,Value);
end;

procedure TCircularGauge.SetRotAngle(const Value: Double);
begin
  SetDoubleProperty(FRotAngle,Value);
end;

procedure TCircularGauge.SetTotalAngle(const Value: Double);
begin
  SetDoubleProperty(FTotalAngle,Value);
end;

procedure TCircularGauge.SetParentChart(const Value: TCustomAxisPanel);
begin
  inherited;

  if not (csDestroying in ComponentState) then
  begin
    Hand.ParentChart:=ParentChart;
    Center.ParentChart:=ParentChart;
    EndPoint.ParentChart:=ParentChart;

    if Assigned(ParentChart) then
    begin
      Axis.Title.Caption:='';
      Axis.Increment:=10;
    end;
  end;
end;

function TCircularGauge.UseAxis: Boolean;
begin
  result:=False;
end;

{ TGaugeHand }

Constructor TGaugeHand.Create(AOwner: TChartSeries);
begin
  inherited;

  FDistance:=30;
  FOffset:=80;

  GaugeStyle:=gpHand;
  HorizSize:=5;
  VertSize:=FDistance;
  Brush.Style:=bsSolid;
  Brush.Color := clBlack;
  Pen.Color:=TCustomGauge(AOwner).GetPaletteColor(12);
  Pen.Visible := False;
  Pen.Width:= 1;

  Gradient.Visible:=True;
  Gradient.EndColor:=TCustomGauge(AOwner).GetPaletteColor(13);
  Gradient.MidColor:=TCustomGauge(AOwner).GetPaletteColor(14);
  Gradient.StartColor:=TCustomGauge(AOwner).GetPaletteColor(15);
  Gradient.Direction:=gdLeftRight;

  Shadow.Color:=clBlack;
  Shadow.Size:=5;
  Shadow.Visible:=True;
end;

procedure TGaugeHand.Draw(const Angle:Double; Center:TPoint; Off:Integer);
var
  tmpSin : Extended;
  tmpCos : Extended;

  Function CalcPoint(const AX,AY:Integer):TPoint;
  begin
    result.X:=Center.X-Round( AX*tmpCos + AY*tmpSin);
    result.Y:=Center.Y+Round(-AX*tmpSin + AY*tmpCos);
  end;

var
  tmpP : TPointArray;

  procedure CalcPoints(xOff,yOff:Integer);
  begin
    tmpP[0]:=CalcPoint(xOff-HorizSize,  yOff-Off);
    tmpP[1]:=CalcPoint(xOff+HorizSize,  yOff-Off);
    tmpP[2]:=CalcPoint(xOff+HorizSize-2,yOff+VertSize-2);
    tmpP[3]:=CalcPoint(xOff,            yOff+VertSize);
    tmpP[4]:=CalcPoint(xOff-HorizSize+2,yOff+VertSize-2);
  end;

begin
  SinCos(angle*TeePiStep,tmpSin,tmpCos);

  SetLength(tmpP,5);

  if Shadow.Visible then
  begin
    CalcPoints(Shadow.HorizSize,Shadow.VertSize);
    Shadow.Draw(ParentChart.Canvas,tmpP);
  end;

  PrepareCanvas(ParentChart.Canvas,Color);
  CalcPoints(0,0);

  if Gradient.Visible then
  begin
    Gradient.Draw(ParentChart.Canvas,tmpP,0,False);
    ParentChart.Canvas.Brush.Style:=bsClear;
  end;

  ParentChart.Canvas.Polygon(tmpP);

  tmpP:=nil;
end;

procedure TGaugeHand.SetDistance(const Value: Integer);
begin
  if FDistance<>Value then
  begin
    FDistance:=Value;
    Repaint;
  end;
end;

procedure TGaugeHand.SetOffset(const Value: Integer);
begin
  if FOffset<>Value then
  begin
    FOffset:=Value;
    Repaint;
  end;
end;

procedure TCircularGaugeEditor.FormShow(Sender: TObject);
begin
  inherited;

  if Gauge is TCircularGauge then
  with TCircularGauge(Gauge) do
  begin
    UDTotalAngle.Position:=Round(TotalAngle);
    UDRotAngle.Position:=Round(RotationAngle);
    UDHandDist.Position:=Hand.Distance;
    UDHandOff.Position:=Hand.Offset;
    CBLabelsInside.Checked:=LabelsInside;
    CBRotateLabels.Checked:=RotateLabels;
    CBCircled.Checked:=Circled;
  end;

  Timer1.Enabled:=True;
end;

procedure TCircularGaugeEditor.BHandClick(Sender: TObject);
begin
  EditSeriesPointer(Self,(Gauge as TCircularGauge).Hand);
end;

procedure TCircularGaugeEditor.BCenterClick(Sender: TObject);
begin
  EditSeriesPointer(Self,(Gauge as TCircularGauge).Center);
end;

procedure TCircularGaugeEditor.Button3Click(Sender: TObject);
begin
  EditSeriesPointer(Self,(Gauge as TCircularGauge).EndPoint);
end;

procedure TCircularGaugeEditor.CBLabelsInsideClick(Sender: TObject);
begin
  (Gauge as TCircularGauge).LabelsInside:=CBLabelsInside.Checked;
end;

procedure TCircularGaugeEditor.CBRotateLabelsClick(Sender: TObject);
begin
  (Gauge as TCircularGauge).RotateLabels:=CBRotateLabels.Checked;
end;

procedure TCircularGaugeEditor.Edit1Change(Sender: TObject);
begin
  if Showing then
     (Gauge as TCircularGauge).Hand.Distance:=UDHandDist.Position;
end;

procedure TCircularGaugeEditor.Edit3Change(Sender: TObject);
begin
  if Showing then
     (Gauge as TCircularGauge).Hand.Offset:=UDHandOff.Position;
end;

procedure TCircularGaugeEditor.ETotalAngleChange(Sender: TObject);
begin
  if Showing then
     (Gauge as TCircularGauge).TotalAngle:=UDTotalAngle.Position;
end;

procedure TCircularGaugeEditor.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled:=False;

  BLinearHand.Visible:=False;
  BValueArea.Visible:=False;
  BMaxIndicator.Visible:=False;
end;

procedure TCircularGaugeEditor.CBCircledClick(Sender: TObject);
begin
  (Gauge as TCircularGauge).Circled:=CBCircled.Checked;
end;

procedure TCircularGaugeEditor.Edit4Change(Sender: TObject);
begin
  if Showing then
     (Gauge as TCircularGauge).RotationAngle:=UDRotAngle.Position;
end;

initialization
  RegisterClass(TCircularGaugeEditor);
  RegisterTeeSeries(TCircularGauge, {$IFNDEF CLR}@{$ENDIF}TeeMsg_CircularGauge,
                                    {$IFNDEF CLR}@{$ENDIF}TeeMsg_GalleryGauges,1);
finalization
  UnRegisterTeeSeries([TCircularGauge]);
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -