164 lines
6.6 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|