Files

164 lines
6.6 KiB
C#

using UnityEngine;
using UnityEngine.UIElements;
namespace EasyChart.Layers
{
public class GridLayer : VisualElement
{
public int HorizontalGridCount { get; set; } = 5;
public int VerticalGridCount { get; set; } = 5;
public bool VerticalPreload { get; set; } = false;
public bool HorizontalPreload { get; set; } = false;
public Color XGridColor { get; set; } = new Color(0.5f, 0.5f, 0.5f, 0.2f);
public float XGridLineWidth { get; set; } = 1.0f;
public bool XGridDashed { get; set; } = false;
public float XGridDashLength { get; set; } = 4f;
public float XGridDashGap { get; set; } = 2f;
public float XGridDashOffset { get; set; } = 0f;
public Color YGridColor { get; set; } = new Color(0.5f, 0.5f, 0.5f, 0.2f);
public float YGridLineWidth { get; set; } = 1.0f;
public bool YGridDashed { get; set; } = false;
public float YGridDashLength { get; set; } = 4f;
public float YGridDashGap { get; set; } = 2f;
public float YGridDashOffset { get; set; } = 0f;
public GridLayer()
{
// Make it fill the parent
this.StretchToParentSize();
pickingMode = PickingMode.Ignore; // Background doesn't need to block clicks
style.overflow = Overflow.Visible; // Allow drawing outside contentRect for preload
generateVisualContent += OnGenerateVisualContent;
}
private void OnGenerateVisualContent(MeshGenerationContext context)
{
var width = contentRect.width;
var height = contentRect.height;
if (width <= 0 || height <= 0) return;
var painter = context.painter2D;
// Calculate extended width/height for preload
float extendedWidth = width;
float extendedHeight = height;
if (VerticalPreload && VerticalGridCount > 0)
{
float vStep = width / VerticalGridCount;
extendedWidth = width + vStep;
}
if (HorizontalPreload && HorizontalGridCount > 0)
{
float hStep = height / HorizontalGridCount;
extendedHeight = height + hStep;
}
// Draw Horizontal Lines (Y Axis steps)
// Usually split into N parts means N+1 lines? Or N lines?
// For Y axis, usually 0..Count means Count+1 lines including 0 and Max.
if (HorizontalGridCount > 0)
{
painter.lineWidth = YGridLineWidth;
painter.strokeColor = YGridColor;
float hStep = height / HorizontalGridCount;
// When preload is enabled, draw one extra line outside the visible area
int lineCount = HorizontalGridCount + (HorizontalPreload ? 1 : 0);
for (int i = 0; i <= lineCount; i++)
{
float y = i * hStep;
// Use extendedWidth so horizontal lines cover the preload area
var a = new Vector2(0, y);
var b = new Vector2(extendedWidth, y);
if (YGridDashed)
{
DashedLineUtils.DrawDashedLine(painter, a, b, YGridDashLength, YGridDashGap, YGridDashOffset);
}
else
{
painter.BeginPath();
painter.MoveTo(a);
painter.LineTo(b);
painter.Stroke();
}
}
}
// Draw Vertical Lines (X Axis steps)
// For Category Axis, we want lines exactly at 0, 1, 2... (LabelCount - 1)
// So VerticalGridCount should be set to (LabelCount > 1 ? LabelCount - 1 : 1)
// to match the logic: width / Count * i
// BUT wait: if we have 5 labels (0,1,2,3,4), we want 5 lines at 0%, 25%, 50%, 75%, 100%.
// This corresponds to dividing width by 4 (Count-1).
if (VerticalGridCount > 0)
{
painter.lineWidth = XGridLineWidth;
painter.strokeColor = XGridColor;
// If VerticalGridCount means "Number of segments", step = width / Count.
// If VerticalGridCount means "Number of labels/lines - 1", step = width / Count.
// Let's standardize: VerticalGridCount passed in will be (LabelCount - 1).
// If LabelCount=1, GridCount=0 (avoid div by zero).
float vStep = width / VerticalGridCount;
// When preload is enabled, draw one extra line outside the visible area
int lineCount = VerticalGridCount + (VerticalPreload ? 1 : 0);
for (int i = 0; i <= lineCount; i++)
{
float x = i * vStep;
// Use extendedHeight so vertical lines cover the preload area
var a = new Vector2(x, 0);
var b = new Vector2(x, extendedHeight);
if (XGridDashed)
{
DashedLineUtils.DrawDashedLine(painter, a, b, XGridDashLength, XGridDashGap, XGridDashOffset);
}
else
{
painter.BeginPath();
painter.MoveTo(a);
painter.LineTo(b);
painter.Stroke();
}
}
}
else if (VerticalGridCount == 0) // Special case: Single line or just edges?
{
painter.lineWidth = XGridLineWidth;
painter.strokeColor = XGridColor;
// Maybe just draw left and right edge?
// For now do nothing or draw at 0.
var a = new Vector2(0, 0);
var b = new Vector2(0, height);
if (XGridDashed)
{
DashedLineUtils.DrawDashedLine(painter, a, b, XGridDashLength, XGridDashGap, XGridDashOffset);
}
else
{
painter.BeginPath();
painter.MoveTo(a);
painter.LineTo(b);
painter.Stroke();
}
}
}
public void Redraw()
{
MarkDirtyRepaint();
}
public void SetScrollOffset(float xPx, float yPx)
{
style.translate = new Translate(xPx, yPx, 0);
}
}
}