UE4 Slate饼状图

// 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;
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值