// Fill out your copyright notice in the Description page of Project Settings.
#include "PieChartWidget.h"
int32 UPieChartWidget::NativePaint(const FPaintArgs& Args,
const FGeometry& Geometry,
const FSlateRect& Rect,
FSlateWindowElementList& DrawElements,
int32 LayerId,
const FWidgetStyle& Style,
bool ParentEnable) const
{
DrawPart(DrawElements, Geometry, LayerId, OuterR, StartAngle, EndAngle, CircleColor);
return LayerId++;
}
void UPieChartWidget::DrawPart(FSlateWindowElementList& OutDrawElement,
const FGeometry& AllottedGeometry,
int LayerId, float R,
int32 InBeginAngle, int32 InEndAngle,
const FColor& InColor) const
{
if(InBeginAngle >= InEndAngle) return ;
TArray<FSlateVertex> VertexArray;
TArray<SlateIndex> VertexIndex;
FSlateVertex BeginVertex;
FSlateVertex EndVertex;
FSlateVertex CenterVertex;
BeginVertex.Color = InColor;
EndVertex.Color = InColor;
CenterVertex.Color = InColor;
FVector2D BeginPosition;
FVector2D EndPosition;
for(int32 Angle = InBeginAngle; Angle < InEndAngle; Angle++)
{
FVector2D CenterPosition = FVector2D(R, R);
BeginPosition = FVector2D(
CenterPosition.X + R * FMath::Cos(FMath::DegreesToRadians(Angle)),
CenterPosition.Y - R * FMath::Sin(FMath::DegreesToRadians(Angle))
);
EndPosition = FVector2D(
CenterPosition.X + R * FMath::Cos(FMath::DegreesToRadians(Angle + 1)),
CenterPosition.Y - R * FMath::Sin(FMath::DegreesToRadians(Angle + 1))
);
const FSlateRenderTransform &SlateRenderTransform = AllottedGeometry.ToPaintGeometry().GetAccumulatedRenderTransform();
BeginPosition = SlateRenderTransform.TransformPoint(BeginPosition);
EndPosition = SlateRenderTransform.TransformPoint(EndPosition);
CenterPosition = SlateRenderTransform.TransformPoint(CenterPosition);
BeginVertex.Position = BeginPosition;
EndVertex.Position = EndPosition;
CenterVertex.Position = CenterPosition;
int32 BeginVertexIndex = VertexArray.Add(BeginVertex);
int32 EndVertexIndex = VertexArray.Add(EndVertex);
int32 CenterVertexIndex = VertexArray.Add(CenterVertex);
VertexIndex.Add(BeginVertexIndex);
VertexIndex.Add(EndVertexIndex);
VertexIndex.Add(CenterVertexIndex);
}
for(FSlateVertex &SlateVertex : VertexArray)
{
SlateVertex.TexCoords[0] = 0.f;
SlateVertex.TexCoords[1] = 0.f;
}
const FSlateBrush* Brush = FCoreStyle::Get().GetBrush(TEXT("PIECHART"));
const FSlateResourceHandle Handle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(*Brush);
FSlateDrawElement::MakeCustomVerts(OutDrawElement, LayerId, Handle, VertexArray, VertexIndex, nullptr, 0, 0);
}
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "PieChartWidget.generated.h"
/**
*
*/
UCLASS()
class MYPROJECT_API UPieChartWidget : public UUserWidget
{
GENERATED_BODY()
protected:
virtual int32 NativePaint(const FPaintArgs& Args, const FGeometry& Geometry, const FSlateRect& Rect, FSlateWindowElementList& DrawElements,
int32 LayerId, const FWidgetStyle& Style, bool ParentEnable) const override;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ClampMin = 0, ClampMax = 960))
float OuterR;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ClampMin = 0, ClampMax = 360))
float EndAngle;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ClampMin = 0, ClampMax = 360))
float StartAngle;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FColor CircleColor;
private:
void DrawPart(FSlateWindowElementList& OutDrawElement,
const FGeometry& AllottedGeometry,
int LayerId, float R,
int32 InBeginAngle, int32 InEndAngle,
const FColor& InColor) const;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "PieChartWidget.h"
int32 UPieChartWidget::NativePaint(const FPaintArgs& Args,
const FGeometry& Geometry,
const FSlateRect& Rect,
FSlateWindowElementList& DrawElements,
int32 LayerId,
const FWidgetStyle& Style,
bool ParentEnable) const
{
float TotalValue = 0.f;
for(int32 Index = 0; Index < Angles.Num(); Index++) TotalValue += Angles[Index];
TArray<float> CircleAngles;
for(int32 Index = 0; Index < Angles.Num(); Index++)
{
float Angle = (Angles[Index] / TotalValue) * 360;
CircleAngles.Add(Angle);
}
float AddAngle = 0;
int LoopSize = FMath::Min(Angles.Num(), CircleColor.Num());
for(int32 Index = 0; Index < LoopSize; Index++)
{
DrawPart(
DrawElements,
Geometry,
LayerId,
OuterR,
AddAngle,
AddAngle + CircleAngles[Index],
CircleColor[Index]
);
AddAngle += CircleAngles[Index];
}
return LayerId++;
}
void UPieChartWidget::DrawPart(FSlateWindowElementList& OutDrawElement,
const FGeometry& AllottedGeometry,
int LayerId, float R,
int32 InBeginAngle, int32 InEndAngle,
const FColor& InColor) const
{
if(InBeginAngle >= InEndAngle) return ;
TArray<FSlateVertex> VertexArray;
TArray<SlateIndex> VertexIndex;
FSlateVertex BeginVertex;
FSlateVertex EndVertex;
FSlateVertex CenterVertex;
BeginVertex.Color = InColor;
EndVertex.Color = InColor;
CenterVertex.Color = InColor;
FVector2D BeginPosition;
FVector2D EndPosition;
for(int32 Angle = InBeginAngle; Angle < InEndAngle; Angle++)
{
FVector2D CenterPosition = FVector2D(R, R);
BeginPosition = FVector2D(
CenterPosition.X + R * FMath::Cos(FMath::DegreesToRadians(Angle)),
CenterPosition.Y - R * FMath::Sin(FMath::DegreesToRadians(Angle))
);
EndPosition = FVector2D(
CenterPosition.X + R * FMath::Cos(FMath::DegreesToRadians(Angle + 1)),
CenterPosition.Y - R * FMath::Sin(FMath::DegreesToRadians(Angle + 1))
);
const FSlateRenderTransform &SlateRenderTransform = AllottedGeometry.ToPaintGeometry().GetAccumulatedRenderTransform();
BeginPosition = SlateRenderTransform.TransformPoint(BeginPosition);
EndPosition = SlateRenderTransform.TransformPoint(EndPosition);
CenterPosition = SlateRenderTransform.TransformPoint(CenterPosition);
BeginVertex.Position = BeginPosition;
EndVertex.Position = EndPosition;
CenterVertex.Position = CenterPosition;
int32 BeginVertexIndex = VertexArray.Add(BeginVertex);
int32 EndVertexIndex = VertexArray.Add(EndVertex);
int32 CenterVertexIndex = VertexArray.Add(CenterVertex);
VertexIndex.Add(BeginVertexIndex);
VertexIndex.Add(EndVertexIndex);
VertexIndex.Add(CenterVertexIndex);
}
for(FSlateVertex &SlateVertex : VertexArray)
{
SlateVertex.TexCoords[0] = 0.f;
SlateVertex.TexCoords[1] = 0.f;
}
const FSlateBrush* Brush = FCoreStyle::Get().GetBrush(TEXT("PIECHART"));
const FSlateResourceHandle Handle = FSlateApplication::Get().GetRenderer()->GetResourceHandle(*Brush);
FSlateDrawElement::MakeCustomVerts(OutDrawElement, LayerId, Handle, VertexArray, VertexIndex, nullptr, 0, 0);
}
void UPieChartWidget::SetValues(TArray<float> InValues, TArray<FColor> Colors)
{
if(InValues.Num() < 1) return ;
Angles.Empty();
CircleColor = Colors;
float Total = 0;
for(int32 Index = 0; Index < InValues.Num(); Index++)
{
Total += InValues[Index];
}
float CurrentTotal = 0;
for(int32 Index = 0; Index < InValues.Num(); Index++)
{
CurrentTotal = InValues[Index];
float Angle = (CurrentTotal / Total) * 360;
Angles.Add(Angle);
}
}
int UPieChartWidget::GetArrayUsefulSize()
{
return FMath::Min(CircleColor.Num(), Angles.Num());
}
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "PieChartWidget.generated.h"
/**
*
*/
UCLASS()
class MYPROJECT_API UPieChartWidget : public UUserWidget
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void SetValues(TArray<float> InValues, TArray<FColor> Colors);
UFUNCTION(BlueprintCallable)
int32 GetArrayUsefulSize();
protected:
virtual int32 NativePaint(const FPaintArgs& Args, const FGeometry& Geometry, const FSlateRect& Rect, FSlateWindowElementList& DrawElements,
int32 LayerId, const FWidgetStyle& Style, bool ParentEnable) const override;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ClampMin = 0, ClampMax = 960))
float OuterR;
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (ClampMin = 0, ClampMax = 360))
TArray<float> Angles;
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TArray<FColor> CircleColor;
private:
void DrawPart(FSlateWindowElementList& OutDrawElement,
const FGeometry& AllottedGeometry,
int LayerId, float R,
int32 InBeginAngle, int32 InEndAngle,
const FColor& InColor) const;
};