mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-17 14:00:12 +00:00
增加HeatmapChart热力图
This commit is contained in:
@@ -167,7 +167,7 @@ namespace XCharts
|
||||
/// Category data, available in type: 'Category' axis.
|
||||
/// 类目数据,在类目轴(type: 'category')中有效。
|
||||
/// </summary>
|
||||
public List<string> data { get { return m_Data; } }
|
||||
public List<string> data { get { return m_Data; } set { if (value != null) m_Data = value; } }
|
||||
/// <summary>
|
||||
/// axis Line.
|
||||
/// 坐标轴轴线。
|
||||
|
||||
@@ -197,11 +197,6 @@ namespace XCharts
|
||||
/// </summary>
|
||||
public FontStyle fontStyle { get { return m_FontStyle; } set { m_FontStyle = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// DataZoom is in draging.
|
||||
/// 正在拖拽组件。
|
||||
/// </summary>
|
||||
public bool isDraging { get; set; }
|
||||
/// <summary>
|
||||
/// The start label.
|
||||
/// 组件的开始信息文本。
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace XCharts
|
||||
{
|
||||
var coordinate = new Grid
|
||||
{
|
||||
m_Show = false,
|
||||
m_Show = true,
|
||||
m_Left = 50,
|
||||
m_Right = 30,
|
||||
m_Top = 50,
|
||||
|
||||
@@ -36,7 +36,11 @@ namespace XCharts
|
||||
/// <summary>
|
||||
/// 带有涟漪特效动画的散点图。利用动画特效可以将某些想要突出的数据进行视觉突出。
|
||||
/// </summary>
|
||||
EffectScatter
|
||||
EffectScatter,
|
||||
/// <summary>
|
||||
/// 热力图。主要通过颜色去表现数值的大小,必须要配合 visualMap 组件使用。
|
||||
/// </summary>
|
||||
Heatmap,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -177,9 +181,10 @@ namespace XCharts
|
||||
[SerializeField] private float[] m_Radius = new float[2] { 0, 80 };
|
||||
#endregion
|
||||
[SerializeField] private SerieLabel m_Label = new SerieLabel();
|
||||
[SerializeField] private SerieLabel m_HighlightLabel = new SerieLabel();
|
||||
[SerializeField] private Animation m_Animation = new Animation();
|
||||
[SerializeField] private LineArrow m_LineArrow = new LineArrow();
|
||||
[SerializeField] private ItemStyle m_ItemStyle = new ItemStyle();
|
||||
[SerializeField] private Emphasis m_Emphasis = new Emphasis();
|
||||
[SerializeField] [Range(1, 10)] private int m_ShowDataDimension;
|
||||
[SerializeField] private bool m_ShowDataName;
|
||||
[SerializeField] private bool m_ShowDataIcon;
|
||||
@@ -355,11 +360,6 @@ namespace XCharts
|
||||
/// </summary>
|
||||
public SerieLabel label { get { return m_Label; } set { m_Label = value; } }
|
||||
/// <summary>
|
||||
/// Text label of highlight graphic element.
|
||||
/// 高亮时的文本标签配置。
|
||||
/// </summary>
|
||||
public SerieLabel highlightLabel { get { return m_HighlightLabel; } set { m_HighlightLabel = value; } }
|
||||
/// <summary>
|
||||
/// The start animation.
|
||||
/// 起始动画。
|
||||
/// </summary>
|
||||
@@ -367,9 +367,19 @@ namespace XCharts
|
||||
public Animation animation { get { return m_Animation; } set { m_Animation = value; } }
|
||||
/// <summary>
|
||||
/// The arrow of line.
|
||||
/// 折线图的箭头
|
||||
/// 折线图的箭头。
|
||||
/// </summary>
|
||||
public LineArrow lineArrow { get { return m_LineArrow; } set { m_LineArrow = value; } }
|
||||
/// <summary>
|
||||
/// The style of data item.
|
||||
/// 图形样式。
|
||||
/// </summary>
|
||||
public ItemStyle itemStyle { get { return m_ItemStyle; } set { m_ItemStyle = value; } }
|
||||
/// <summary>
|
||||
/// 高亮的图形样式和文本标签样式。
|
||||
/// </summary>
|
||||
public Emphasis emphasis { get { return m_Emphasis; } set { m_Emphasis = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// 系列中的数据内容数组。SerieData可以设置1到n维数据。
|
||||
/// </summary>
|
||||
@@ -738,7 +748,7 @@ namespace XCharts
|
||||
/// </summary>
|
||||
/// <param name="dataZoom"></param>
|
||||
/// <returns></returns>
|
||||
public List<SerieData> GetDataList(DataZoom dataZoom)
|
||||
public List<SerieData> GetDataList(DataZoom dataZoom = null)
|
||||
{
|
||||
if (dataZoom != null && dataZoom.enable)
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace XCharts
|
||||
[SerializeField] [Range(1f, 20)] protected float m_LineSmoothness = 2f;
|
||||
[SerializeField] [Range(1f, 20)] protected float m_LineSegmentDistance = 3f;
|
||||
[SerializeField] [Range(1, 10)] protected float m_CicleSmoothness = 2f;
|
||||
[SerializeField] [Range(10, 50)] protected float m_VisualMapTriangeLen = 20f;
|
||||
|
||||
/// <summary>
|
||||
/// Curve smoothing factor. By adjusting the smoothing coefficient, the curvature of the curve can be changed,
|
||||
@@ -41,6 +42,11 @@ namespace XCharts
|
||||
/// 圆形的平滑度。数越小圆越平滑,但顶点数也会随之增加。
|
||||
/// </summary>
|
||||
public float cicleSmoothness { get { return m_CicleSmoothness; } set { m_CicleSmoothness = value <= 0 ? 1f : value; } }
|
||||
/// <summary>
|
||||
/// 可视化组件的调节三角形变长。
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public float visualMapTriangeLen { get { return m_VisualMapTriangeLen; } set { m_VisualMapTriangeLen = value <= 0 ? 1f : value; } }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -50,6 +50,8 @@ namespace XCharts
|
||||
[SerializeField] private Color32 m_DataZoomTextColor;
|
||||
[SerializeField] private Color32 m_DataZoomLineColor;
|
||||
[SerializeField] private Color32 m_DataZoomSelectedColor;
|
||||
[SerializeField] private Color32 m_VisualMapBackgroundColor;
|
||||
[SerializeField] private Color32 m_VisualMapBorderColor;
|
||||
[SerializeField] private Color32[] m_ColorPalette;
|
||||
|
||||
[SerializeField] private Font m_CustomFont;
|
||||
@@ -70,6 +72,8 @@ namespace XCharts
|
||||
[SerializeField] private Color32 m_CustomDataZoomTextColor;
|
||||
[SerializeField] private Color32 m_CustomDataZoomLineColor;
|
||||
[SerializeField] private Color32 m_CustomDataZoomSelectedColor;
|
||||
[SerializeField] private Color32 m_CustomVisualMapBackgroundColor;
|
||||
[SerializeField] private Color32 m_CustomVisualMapBorderColor;
|
||||
[SerializeField] private List<Color32> m_CustomColorPalette = new List<Color32>(13);
|
||||
/// <summary>
|
||||
/// the theme of chart.
|
||||
@@ -229,6 +233,25 @@ namespace XCharts
|
||||
get { return m_CustomDataZoomSelectedColor != Color.clear ? m_CustomDataZoomSelectedColor : m_DataZoomSelectedColor; }
|
||||
set { m_CustomDataZoomSelectedColor = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 视觉映射组件的背景色。
|
||||
/// </summary>
|
||||
public Color32 visualMapBackgroundColor
|
||||
{
|
||||
get { return m_CustomVisualMapBackgroundColor != Color.clear ? m_CustomVisualMapBackgroundColor : m_VisualMapBackgroundColor; }
|
||||
set { m_CustomVisualMapBackgroundColor = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 视觉映射的边框色。
|
||||
/// </summary>
|
||||
public Color32 visualMapBorderColor
|
||||
{
|
||||
get { return m_CustomVisualMapBorderColor != Color.clear ? m_CustomVisualMapBorderColor : m_VisualMapBorderColor; }
|
||||
set { m_CustomVisualMapBorderColor = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The color list of palette. If no color is set in series, the colors would be adopted sequentially and circularly from this list as the colors of series.
|
||||
/// 调色盘颜色列表。如果系列没有设置颜色,则会依次循环从该列表中取颜色作为系列颜色。
|
||||
@@ -304,6 +327,8 @@ namespace XCharts
|
||||
m_DataZoomLineColor = theme.m_DataZoomLineColor;
|
||||
m_DataZoomSelectedColor = theme.m_DataZoomSelectedColor;
|
||||
m_DataZoomTextColor = theme.m_DataZoomTextColor;
|
||||
m_VisualMapBackgroundColor = theme.m_VisualMapBackgroundColor;
|
||||
m_VisualMapBorderColor = theme.m_VisualMapBorderColor;
|
||||
m_ColorPalette = new Color32[theme.m_ColorPalette.Length];
|
||||
for (int i = 0; i < theme.m_ColorPalette.Length; i++)
|
||||
{
|
||||
@@ -334,6 +359,8 @@ namespace XCharts
|
||||
m_DataZoomLineColor = Color.clear;
|
||||
m_DataZoomSelectedColor = Color.clear;
|
||||
m_DataZoomTextColor = Color.clear;
|
||||
m_VisualMapBackgroundColor = Color.clear;
|
||||
m_VisualMapBorderColor = Color.clear;
|
||||
for (int i = 0; i < m_CustomColorPalette.Count; i++)
|
||||
{
|
||||
m_CustomColorPalette[i] = Color.clear;
|
||||
@@ -369,6 +396,8 @@ namespace XCharts
|
||||
m_DataZoomLineColor = GetColor("#51515120"),
|
||||
m_DataZoomSelectedColor = GetColor("#51515120"),
|
||||
m_DataZoomTextColor = GetColor("#514D4D"),
|
||||
m_VisualMapBackgroundColor = GetColor("#51515120"),
|
||||
m_VisualMapBorderColor = GetColor("#cccccc"),
|
||||
m_ColorPalette = new Color32[]
|
||||
{
|
||||
new Color32(194, 53, 49, 255),
|
||||
@@ -429,6 +458,8 @@ namespace XCharts
|
||||
m_DataZoomLineColor = GetColor("#51515120"),
|
||||
m_DataZoomSelectedColor = GetColor("#51515120"),
|
||||
m_DataZoomTextColor = GetColor("#514D4D"),
|
||||
m_VisualMapBackgroundColor = GetColor("#51515120"),
|
||||
m_VisualMapBorderColor = GetColor("#cccccc"),
|
||||
m_ColorPalette = new Color32[]
|
||||
{
|
||||
new Color32(55, 162, 218, 255),
|
||||
@@ -493,6 +524,8 @@ namespace XCharts
|
||||
m_DataZoomLineColor = GetColor("#FFFFFF45"),
|
||||
m_DataZoomSelectedColor = GetColor("#D0D0D03D"),
|
||||
m_DataZoomTextColor = GetColor("#FFFFFFFF"),
|
||||
m_VisualMapBackgroundColor = GetColor("#aaa"),
|
||||
m_VisualMapBorderColor = GetColor("#cccccc"),
|
||||
m_ColorPalette = new Color32[]
|
||||
{
|
||||
new Color32(221, 107, 102, 255),
|
||||
|
||||
@@ -157,8 +157,8 @@ namespace XCharts
|
||||
var tooltip = new Tooltip
|
||||
{
|
||||
m_Show = true,
|
||||
xValues = new float[2],
|
||||
yValues = new float[2],
|
||||
xValues = new float[2]{-1,-1},
|
||||
yValues = new float[2]{-1,-1},
|
||||
dataIndex = new List<int>() { -1, -1 },
|
||||
lastDataIndex = new List<int>() { -1, -1 }
|
||||
};
|
||||
|
||||
389
Scripts/UI/Component/VisualMap.cs
Normal file
389
Scripts/UI/Component/VisualMap.cs
Normal file
@@ -0,0 +1,389 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// VisualMap component.
|
||||
/// 视觉映射组件。用于进行『视觉编码』,也就是将数据映射到视觉元素(视觉通道)。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class VisualMap
|
||||
{
|
||||
/// <summary>
|
||||
/// 类型。分为连续型和分段型。
|
||||
/// </summary>
|
||||
public enum Type
|
||||
{
|
||||
/// <summary>
|
||||
/// 连续型。
|
||||
/// </summary>
|
||||
Continuous,
|
||||
/// <summary>
|
||||
/// 分段型。
|
||||
/// </summary>
|
||||
Piecewise
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 选择模式
|
||||
/// </summary>
|
||||
public enum SelectedMode
|
||||
{
|
||||
/// <summary>
|
||||
/// 多选。
|
||||
/// </summary>
|
||||
Multiple,
|
||||
/// <summary>
|
||||
/// 单选。
|
||||
/// </summary>
|
||||
Single
|
||||
}
|
||||
|
||||
[SerializeField] private bool m_Enable = false;
|
||||
[SerializeField] private bool m_Show = true;
|
||||
[SerializeField] private Type m_Type = Type.Continuous;
|
||||
[SerializeField] private SelectedMode m_SelectedMode = SelectedMode.Multiple;
|
||||
[SerializeField] private float m_Min = 0;
|
||||
[SerializeField] private float m_Max = 100f;
|
||||
|
||||
[SerializeField] private float[] m_Range = new float[2] { 0, 100f };
|
||||
[SerializeField] private string[] m_Text = new string[2] { "", "" };
|
||||
[SerializeField] private float[] m_TextGap = new float[2] { 10f, 10f };
|
||||
[SerializeField] private int m_SplitNumber = 5;
|
||||
[SerializeField] private bool m_Calculable = false;
|
||||
[SerializeField] private bool m_Realtime = true;
|
||||
[SerializeField] private float m_ItemWidth = 20f;
|
||||
[SerializeField] private float m_ItemHeight = 140f;
|
||||
[SerializeField] private float m_BorderWidth = 0;
|
||||
[SerializeField] private int m_Dimension = 0;
|
||||
[SerializeField] private bool m_HoverLink = true;
|
||||
[SerializeField] private Orient m_Orient = Orient.Horizonal;
|
||||
[SerializeField] private Location m_Location = Location.defaultLeft;
|
||||
[SerializeField] private List<Color> m_InRange = new List<Color>();
|
||||
[SerializeField] private List<Color> m_OutOfRange = new List<Color>();
|
||||
|
||||
/// <summary>
|
||||
/// 是否开启组件功能。
|
||||
/// </summary>
|
||||
public bool enable { get { return m_Enable; } set { m_Enable = value; } }
|
||||
/// <summary>
|
||||
/// 是否显示组件。如果设置为 false,不会显示,但是数据映射的功能还存在。
|
||||
/// </summary>
|
||||
public bool show { get { return m_Show; } set { m_Show = value; } }
|
||||
/// <summary>
|
||||
/// 组件类型。
|
||||
/// </summary>
|
||||
public Type type { get { return m_Type; } set { m_Type = value; } }
|
||||
/// <summary>
|
||||
/// 选择模式。
|
||||
/// </summary>
|
||||
public SelectedMode selectedMode { get { return m_SelectedMode; } set { m_SelectedMode = value; } }
|
||||
/// <summary>
|
||||
/// 允许的最小值。'min' 必须用户指定。[visualMap.min, visualMap.max] 形成了视觉映射的『定义域』。
|
||||
/// </summary>
|
||||
public float min { get { return m_Min; } set { m_Min = value; } }
|
||||
/// <summary>
|
||||
/// 允许的最大值。'max' 必须用户指定。[visualMap.min, visualMax.max] 形成了视觉映射的『定义域』。
|
||||
/// </summary>
|
||||
public float max { get { return m_Max; } set { m_Max = value < min ? min + 1 : value; } }
|
||||
/// <summary>
|
||||
/// 指定手柄对应数值的位置。range 应在 min max 范围内。
|
||||
/// </summary>
|
||||
public float[] range { get { return m_Range; } }
|
||||
/// <summary>
|
||||
/// 两端的文本,如 ['High', 'Low']。
|
||||
/// </summary>
|
||||
public string[] text { get { return m_Text; } }
|
||||
/// <summary>
|
||||
/// 两端文字主体之间的距离,单位为px。
|
||||
/// </summary>
|
||||
public float[] textGap { get { return m_TextGap; } }
|
||||
/// <summary>
|
||||
/// 对于连续型数据,自动平均切分成几段,默认为0时自动匹配inRange颜色列表大小。
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public int splitNumber { get { return m_SplitNumber; } set { m_SplitNumber = value; } }
|
||||
/// <summary>
|
||||
/// 是否显示拖拽用的手柄(手柄能拖拽调整选中范围)。
|
||||
/// </summary>
|
||||
public bool calculable { get { return m_Calculable; } set { m_Calculable = value; } }
|
||||
/// <summary>
|
||||
/// 拖拽时,是否实时更新。
|
||||
/// </summary>
|
||||
public bool realtime { get { return m_Realtime; } set { m_Realtime = value; } }
|
||||
/// <summary>
|
||||
/// 图形的宽度,即颜色条的宽度。
|
||||
/// </summary>
|
||||
public float itemWidth { get { return m_ItemWidth; } set { m_ItemWidth = value; } }
|
||||
/// <summary>
|
||||
/// 图形的高度,即颜色条的高度。
|
||||
/// </summary>
|
||||
public float itemHeight { get { return m_ItemHeight; } set { m_ItemHeight = value; } }
|
||||
/// <summary>
|
||||
/// 边框线宽,单位px。
|
||||
/// </summary>
|
||||
public float borderWidth { get { return m_BorderWidth; } set { m_BorderWidth = value; } }
|
||||
/// <summary>
|
||||
/// 指定用数据的『哪个维度』,映射到视觉元素上。『数据』即 series.data。从1开始,默认为0取 data 中最后一个维度。
|
||||
/// </summary>
|
||||
public int dimension { get { return m_Dimension; } set { m_Dimension = value; } }
|
||||
/// <summary>
|
||||
/// 打开 hoverLink 功能时,鼠标悬浮到 visualMap 组件上时,鼠标位置对应的数值 在 图表中对应的图形元素,会高亮。
|
||||
/// 反之,鼠标悬浮到图表中的图形元素上时,在 visualMap 组件的相应位置会有三角提示其所对应的数值。
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public bool hoverLink { get { return m_HoverLink; } set { m_HoverLink = value; } }
|
||||
/// <summary>
|
||||
/// Specify whether the layout of component is horizontal or vertical.
|
||||
/// 布局方式是横还是竖。
|
||||
/// </summary>
|
||||
public Orient orient { get { return m_Orient; } set { m_Orient = value; } }
|
||||
/// <summary>
|
||||
/// The location of component.
|
||||
/// 组件显示的位置。
|
||||
/// </summary>
|
||||
public Location location { get { return m_Location; } set { m_Location = value; } }
|
||||
/// <summary>
|
||||
/// 定义 在选中范围中 的视觉颜色。
|
||||
/// </summary>
|
||||
public List<Color> inRange { get { return m_InRange; } set { if (value != null) m_InRange = value; } }
|
||||
/// <summary>
|
||||
/// 定义 在选中范围外 的视觉颜色。
|
||||
/// </summary>
|
||||
public List<Color> outOfRange { get { return m_OutOfRange; } set { if (value != null) m_OutOfRange = value; } }
|
||||
|
||||
/// <summary>
|
||||
/// 鼠标悬停选中的index
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public int rtSelectedIndex { get; set; }
|
||||
public float rtSelectedValue { get; set; }
|
||||
/// <summary>
|
||||
/// the current pointer position.
|
||||
/// 当前鼠标位置。
|
||||
/// </summary>
|
||||
public Vector2 pointerPos { get; set; }
|
||||
public bool isVertical { get { return orient == Orient.Vertical; } }
|
||||
public float rangeMin
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Range[0] < min || m_Range[0] > max) return min;
|
||||
else return m_Range[0];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value >= min && value <= m_Range[1]) m_Range[0] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public float rangeMax
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Range[1] >= m_Range[0] && m_Range[1] < max) return m_Range[1];
|
||||
else return max;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value >= m_Range[0] && value <= max) m_Range[1] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int rtSplitNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
if (splitNumber > 0 && splitNumber <= m_InRange.Count) return splitNumber;
|
||||
else return inRange.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public float rangeMinHeight { get { return (rangeMin - min) / (max - min) * itemHeight; } }
|
||||
public float rangeMaxHeight { get { return (rangeMax - min) / (max - min) * itemHeight; } }
|
||||
|
||||
private List<Color> m_RtInRange = new List<Color>();
|
||||
public List<Color> rtInRange
|
||||
{
|
||||
get
|
||||
{
|
||||
if (splitNumber == 0 || m_InRange.Count >= splitNumber || m_InRange.Count < 1) return m_InRange;
|
||||
else
|
||||
{
|
||||
if (m_RtInRange.Count != rtSplitNumber)
|
||||
{
|
||||
m_RtInRange.Clear();
|
||||
var total = max - min;
|
||||
var diff1 = total / (m_InRange.Count - 1);
|
||||
var diff2 = total / splitNumber;
|
||||
|
||||
var inCount = 0;
|
||||
var inValue = min;
|
||||
var rtValue = min;
|
||||
|
||||
|
||||
for (int i = 0; i < splitNumber; i++)
|
||||
{
|
||||
rtValue += diff2;
|
||||
if (rtValue > inValue + diff1)
|
||||
{
|
||||
inValue += diff1;
|
||||
inCount++;
|
||||
}
|
||||
if (i == splitNumber - 1)
|
||||
{
|
||||
m_RtInRange.Add(m_InRange[m_InRange.Count - 1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
var rate = (rtValue - inValue) / diff1;
|
||||
m_RtInRange.Add(Color.Lerp(m_InRange[inCount], m_InRange[inCount + 1], rate));
|
||||
}
|
||||
}
|
||||
}
|
||||
return m_RtInRange;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Color GetColor(float value)
|
||||
{
|
||||
int splitNumber = rtInRange.Count;
|
||||
if (splitNumber <= 0) return Color.clear;
|
||||
value = Mathf.Clamp(value, min, max);
|
||||
|
||||
var diff = (max - min) / (splitNumber - 1);
|
||||
var index = GetIndex(value);
|
||||
var nowMin = min + index * diff;
|
||||
var rate = (value - nowMin) / diff;
|
||||
if (index == splitNumber - 1) return rtInRange[index];
|
||||
else return Color.Lerp(rtInRange[index], rtInRange[index + 1], rate);
|
||||
}
|
||||
|
||||
public int GetIndex(float value)
|
||||
{
|
||||
int splitNumber = rtInRange.Count;
|
||||
if (splitNumber <= 0) return -1;
|
||||
value = Mathf.Clamp(value, min, max);
|
||||
|
||||
var diff = (max - min) / (splitNumber - 1);
|
||||
var index = -1;
|
||||
for (int i = 0; i < splitNumber; i++)
|
||||
{
|
||||
if (value <= min + (i + 1) * diff)
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
public bool IsInSelectedValue(float value)
|
||||
{
|
||||
if (rtSelectedIndex < 0) return true;
|
||||
else
|
||||
{
|
||||
return rtSelectedIndex == GetIndex(value);
|
||||
}
|
||||
}
|
||||
|
||||
public float GetValue(Vector3 pos, float chartWidth, float chartHeight)
|
||||
{
|
||||
var centerPos = location.GetPosition(chartWidth, chartHeight);
|
||||
var pos1 = centerPos + (isVertical ? Vector3.down : Vector3.left) * itemHeight / 2;
|
||||
var pos2 = centerPos + (isVertical ? Vector3.up : Vector3.right) * itemHeight / 2;
|
||||
if (isVertical)
|
||||
{
|
||||
if (pos.y < pos1.y) return min;
|
||||
else if (pos.y > pos2.y) return max;
|
||||
else return min + (pos.y - pos1.y) / (pos2.y - pos1.y) * (max - min);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pos.x < pos1.x) return min;
|
||||
else if (pos.x > pos2.x) return max;
|
||||
else return min + (pos.x - pos1.x) / (pos2.x - pos1.x) * (max - min);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsInRect(Vector3 local, float chartWidth, float chartHeight, float triangleLen = 20)
|
||||
{
|
||||
var centerPos = location.GetPosition(chartWidth, chartHeight);
|
||||
var diff = calculable ? triangleLen : 0;
|
||||
if (local.x >= centerPos.x - itemWidth / 2 - diff && local.x <= centerPos.x + itemWidth / 2 + diff &&
|
||||
local.y >= centerPos.y - itemHeight / 2 - diff && local.y <= centerPos.y + itemHeight / 2 + diff)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsInRangeRect(Vector3 local, float chartWidth, float chartHeight)
|
||||
{
|
||||
var centerPos = location.GetPosition(chartWidth, chartHeight);
|
||||
if (orient == Orient.Vertical)
|
||||
{
|
||||
var pos1 = centerPos + Vector3.down * itemHeight / 2;
|
||||
return local.x >= centerPos.x - itemWidth / 2 && local.x <= centerPos.x + itemWidth / 2 &&
|
||||
local.y >= pos1.y + rangeMinHeight && local.y <= pos1.y + rangeMaxHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
var pos1 = centerPos + Vector3.left * itemHeight / 2;
|
||||
return local.x >= pos1.x + rangeMinHeight && local.x <= pos1.x + rangeMaxHeight &&
|
||||
local.y >= centerPos.y - itemWidth / 2 && local.y <= centerPos.y + itemWidth / 2;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsInRangeMinRect(Vector3 local, float chartWidth, float chartHeight, float triangleLen)
|
||||
{
|
||||
var centerPos = location.GetPosition(chartWidth, chartHeight);
|
||||
if (orient == Orient.Vertical)
|
||||
{
|
||||
var radius = triangleLen / 2;
|
||||
var pos1 = centerPos + Vector3.down * itemHeight / 2;
|
||||
var cpos = new Vector3(pos1.x + itemWidth / 2 + radius, pos1.y + rangeMinHeight - radius);
|
||||
|
||||
return local.x >= cpos.x - radius && local.x <= cpos.x + radius &&
|
||||
local.y >= cpos.y - radius && local.y <= cpos.y + radius;
|
||||
}
|
||||
else
|
||||
{
|
||||
var radius = triangleLen / 2;
|
||||
var pos1 = centerPos + Vector3.left * itemHeight / 2;
|
||||
var cpos = new Vector3(pos1.x + rangeMinHeight - radius, pos1.y + itemWidth / 2 + radius);
|
||||
return local.x >= cpos.x - radius && local.x <= cpos.x + radius &&
|
||||
local.y >= cpos.y - radius && local.y <= cpos.y + radius;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsInRangeMaxRect(Vector3 local, float chartWidth, float chartHeight, float triangleLen)
|
||||
{
|
||||
var centerPos = location.GetPosition(chartWidth, chartHeight);
|
||||
if (orient == Orient.Vertical)
|
||||
{
|
||||
var radius = triangleLen / 2;
|
||||
var pos1 = centerPos + Vector3.down * itemHeight / 2;
|
||||
var cpos = new Vector3(pos1.x + itemWidth / 2 + radius, pos1.y + rangeMaxHeight + radius);
|
||||
|
||||
return local.x >= cpos.x - radius && local.x <= cpos.x + radius &&
|
||||
local.y >= cpos.y - radius && local.y <= cpos.y + radius;
|
||||
}
|
||||
else
|
||||
{
|
||||
var radius = triangleLen / 2;
|
||||
var pos1 = centerPos + Vector3.left * itemHeight / 2;
|
||||
var cpos = new Vector3(pos1.x + rangeMaxHeight + radius, pos1.y + itemWidth / 2 + radius);
|
||||
return local.x >= cpos.x - radius && local.x <= cpos.x + radius &&
|
||||
local.y >= cpos.y - radius && local.y <= cpos.y + radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Scripts/UI/Component/VisualMap.cs.meta
Normal file
11
Scripts/UI/Component/VisualMap.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 066b3522287d94c9388681683567fad6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
135
Scripts/UI/HeatmapChart.cs
Normal file
135
Scripts/UI/HeatmapChart.cs
Normal file
@@ -0,0 +1,135 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
[AddComponentMenu("XCharts/HeatmapChart", 18)]
|
||||
[ExecuteInEditMode]
|
||||
[RequireComponent(typeof(RectTransform))]
|
||||
[DisallowMultipleComponent]
|
||||
public class HeatmapChart : CoordinateChart
|
||||
{
|
||||
|
||||
#if UNITY_EDITOR
|
||||
protected override void Reset()
|
||||
{
|
||||
base.Reset();
|
||||
m_Title.text = "HeatmapChart";
|
||||
m_Tooltip.type = Tooltip.Type.None;
|
||||
m_Grid.left = 100;
|
||||
m_Grid.right = 60;
|
||||
m_Grid.bottom = 60;
|
||||
|
||||
m_XAxises[0].type = Axis.AxisType.Category;
|
||||
m_XAxises[0].boundaryGap = false;
|
||||
m_YAxises[0].type = Axis.AxisType.Category;
|
||||
m_YAxises[0].boundaryGap = false;
|
||||
m_XAxises[0].splitNumber = 10;
|
||||
m_YAxises[0].splitNumber = 10;
|
||||
RemoveData();
|
||||
var serie = AddSerie(SerieType.Heatmap, "serie1");
|
||||
var heatmapGridWid = 10f;
|
||||
int xSplitNumber = (int)(coordinateWid / heatmapGridWid);
|
||||
int ySplitNumber = (int)(coordinateHig / heatmapGridWid);
|
||||
serie.itemStyle.show = true;
|
||||
serie.itemStyle.borderWidth = 1;
|
||||
serie.itemStyle.borderColor = Color.clear;
|
||||
serie.emphasis.show = true;
|
||||
serie.emphasis.itemStyle.show = true;
|
||||
serie.emphasis.itemStyle.borderWidth = 1;
|
||||
serie.emphasis.itemStyle.borderColor = Color.black;
|
||||
|
||||
m_VisualMap.enable = true;
|
||||
m_VisualMap.max = 10;
|
||||
m_VisualMap.range[0] = 0f;
|
||||
m_VisualMap.range[1] = 10f;
|
||||
m_VisualMap.orient = Orient.Vertical;
|
||||
m_VisualMap.calculable = true;
|
||||
m_VisualMap.location.align = Location.Align.BottomLeft;
|
||||
m_VisualMap.location.bottom = 100;
|
||||
m_VisualMap.location.left = 30;
|
||||
var colors = new List<string>{"#313695", "#4575b4", "#74add1", "#abd9e9", "#e0f3f8", "#ffffbf",
|
||||
"#fee090", "#fdae61", "#f46d43", "#d73027", "#a50026"};
|
||||
m_VisualMap.inRange.Clear();
|
||||
foreach (var str in colors)
|
||||
{
|
||||
m_VisualMap.inRange.Add(ThemeInfo.GetColor(str));
|
||||
}
|
||||
for (int i = 0; i < xSplitNumber; i++)
|
||||
{
|
||||
m_XAxises[0].data.Add((i + 1).ToString());
|
||||
}
|
||||
for (int i = 0; i < ySplitNumber; i++)
|
||||
{
|
||||
m_YAxises[0].data.Add((i + 1).ToString());
|
||||
}
|
||||
for (int i = 0; i < xSplitNumber; i++)
|
||||
{
|
||||
for (int j = 0; j < ySplitNumber; j++)
|
||||
{
|
||||
var value = 0f;
|
||||
var rate = Random.Range(0, 101);
|
||||
if (rate > 70) value = Random.Range(8f, 10f);
|
||||
else value = Random.Range(1f, 8f);
|
||||
var list = new List<float> { i, j, value };
|
||||
AddData(0, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
protected override void RefreshTooltip()
|
||||
{
|
||||
var xData = m_Tooltip.xValues[0];
|
||||
var yData = m_Tooltip.yValues[0];
|
||||
if (IsCategory() && (xData < 0 || yData < 0)) return;
|
||||
sb.Length = 0;
|
||||
for (int i = 0; i < m_Series.Count; i++)
|
||||
{
|
||||
var serie = m_Series.GetSerie(i);
|
||||
var xAxis = m_XAxises[serie.axisIndex];
|
||||
var yAxis = m_YAxises[serie.axisIndex];
|
||||
var xCount = xAxis.data.Count;
|
||||
var yCount = yAxis.data.Count;
|
||||
if (serie.show && serie.type == SerieType.Heatmap)
|
||||
{
|
||||
if (IsCategory())
|
||||
{
|
||||
string key = serie.name;
|
||||
var serieData = serie.data[(int)xData * yCount + (int)yData];
|
||||
var value = serieData.data[2];
|
||||
var color = m_VisualMap.enable ? m_VisualMap.GetColor(value) :
|
||||
(Color)m_ThemeInfo.GetColor(serie.index);
|
||||
sb.Append("\n")
|
||||
.Append(key).Append(!string.IsNullOrEmpty(key) ? "\n" : "")
|
||||
.Append("<color=#").Append(ChartCached.ColorToStr(color)).Append(">● </color>")
|
||||
.Append(xAxis.data[(int)xData]).Append(": ")
|
||||
.Append(ChartCached.FloatToStr(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
m_Tooltip.UpdateContentText(sb.ToString().Trim());
|
||||
var pos = m_Tooltip.GetContentPos();
|
||||
if (pos.x + m_Tooltip.width > chartWidth)
|
||||
{
|
||||
pos.x = chartWidth - m_Tooltip.width;
|
||||
}
|
||||
if (pos.y - m_Tooltip.height < 0)
|
||||
{
|
||||
pos.y = m_Tooltip.height;
|
||||
}
|
||||
m_Tooltip.UpdateContentPos(pos);
|
||||
m_Tooltip.SetActive(true);
|
||||
|
||||
for (int i = 0; i < m_XAxises.Count; i++)
|
||||
{
|
||||
UpdateAxisTooltipLabel(i, m_XAxises[i]);
|
||||
}
|
||||
for (int i = 0; i < m_YAxises.Count; i++)
|
||||
{
|
||||
UpdateAxisTooltipLabel(i, m_YAxises[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Scripts/UI/HeatmapChart.cs.meta
Normal file
11
Scripts/UI/HeatmapChart.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 31aa03cd4ce594c239ae746791b3b59f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Scripts/UI/Helper.meta
Normal file
8
Scripts/UI/Helper.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 58d150a402b5e4bfcbec6a28cba7ed44
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
15
Scripts/UI/Helper/VisualMapHelper.cs
Normal file
15
Scripts/UI/Helper/VisualMapHelper.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System.Text;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public static class VisualMapHelper
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
11
Scripts/UI/Helper/VisualMapHelper.cs.meta
Normal file
11
Scripts/UI/Helper/VisualMapHelper.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 947fc87a63dec45f8b27ade5f0d050c4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -16,6 +16,7 @@ namespace XCharts
|
||||
[SerializeField] protected List<XAxis> m_XAxises = new List<XAxis>();
|
||||
[SerializeField] protected List<YAxis> m_YAxises = new List<YAxis>();
|
||||
[SerializeField] protected DataZoom m_DataZoom = DataZoom.defaultDataZoom;
|
||||
[SerializeField] protected VisualMap m_VisualMap = new VisualMap();
|
||||
|
||||
private bool m_DataZoomDrag;
|
||||
private bool m_DataZoomCoordinateDrag;
|
||||
@@ -52,7 +53,9 @@ namespace XCharts
|
||||
CheckXAxis();
|
||||
CheckMinMaxValue();
|
||||
CheckCoordinate();
|
||||
CheckRaycastTarget();
|
||||
CheckDataZoom();
|
||||
CheckVisualMap();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
@@ -72,6 +75,7 @@ namespace XCharts
|
||||
DrawCoordinate(vh);
|
||||
DrawSerie(vh);
|
||||
DrawDataZoomSlider(vh);
|
||||
DrawVisualMap(vh);
|
||||
}
|
||||
|
||||
|
||||
@@ -112,6 +116,9 @@ namespace XCharts
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case SerieType.Heatmap:
|
||||
DrawHeatmapSerie(vh, colorIndex, serie);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -170,6 +177,33 @@ namespace XCharts
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (IsCategory())
|
||||
{
|
||||
|
||||
for (int j = 0; j < xAxis.GetDataNumber(m_DataZoom); j++)
|
||||
{
|
||||
float splitWid = xAxis.GetDataWidth(coordinateWid, m_DataZoom);
|
||||
float pX = coordinateX + j * splitWid;
|
||||
if ((xAxis.boundaryGap && (local.x > pX && local.x <= pX + splitWid)) ||
|
||||
(!xAxis.boundaryGap && (local.x > pX - splitWid / 2 && local.x <= pX + splitWid / 2)))
|
||||
{
|
||||
m_Tooltip.xValues[i] = j;
|
||||
m_Tooltip.dataIndex[i] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < yAxis.GetDataNumber(m_DataZoom); j++)
|
||||
{
|
||||
float splitWid = yAxis.GetDataWidth(coordinateHig, m_DataZoom);
|
||||
float pY = coordinateY + j * splitWid;
|
||||
if ((yAxis.boundaryGap && (local.y > pY && local.y <= pY + splitWid)) ||
|
||||
(!yAxis.boundaryGap && (local.y > pY - splitWid / 2 && local.y <= pY + splitWid / 2)))
|
||||
{
|
||||
m_Tooltip.yValues[i] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (xAxis.IsCategory())
|
||||
{
|
||||
var value = (yAxis.maxValue - yAxis.minValue) * (local.y - coordinateY - yAxis.zeroYOffset) / coordinateHig;
|
||||
@@ -225,7 +259,7 @@ namespace XCharts
|
||||
}
|
||||
}
|
||||
|
||||
private StringBuilder sb = new StringBuilder(100);
|
||||
protected StringBuilder sb = new StringBuilder(100);
|
||||
protected override void RefreshTooltip()
|
||||
{
|
||||
base.RefreshTooltip();
|
||||
@@ -320,7 +354,7 @@ namespace XCharts
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateAxisTooltipLabel(int axisIndex, Axis axis)
|
||||
protected void UpdateAxisTooltipLabel(int axisIndex, Axis axis)
|
||||
{
|
||||
var showTooltipLabel = axis.show && m_Tooltip.type == Tooltip.Type.Corss;
|
||||
axis.SetTooltipLabelActive(showTooltipLabel);
|
||||
@@ -611,7 +645,7 @@ namespace XCharts
|
||||
dataZoomObject.transform, m_ThemeInfo.font, m_ThemeInfo.dataZoomTextColor, TextAnchor.MiddleLeft,
|
||||
Vector2.zero, Vector2.zero, new Vector2(0, 0.5f), new Vector2(200, 20), m_DataZoom.fontSize, 0, m_DataZoom.fontStyle);
|
||||
m_DataZoom.SetLabelActive(false);
|
||||
raycastTarget = m_DataZoom.enable;
|
||||
CheckRaycastTarget();
|
||||
var xAxis = m_XAxises[m_DataZoom.xAxisIndex];
|
||||
if (xAxis != null)
|
||||
{
|
||||
@@ -705,6 +739,11 @@ namespace XCharts
|
||||
private void CheckMinMaxValue()
|
||||
{
|
||||
if (m_XAxises == null || m_YAxises == null) return;
|
||||
if (IsCategory())
|
||||
{
|
||||
m_CheckMinMaxValue = true;
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < m_XAxises.Count; i++)
|
||||
{
|
||||
UpdateAxisMinMaxValue(i, m_XAxises[i]);
|
||||
@@ -1145,12 +1184,17 @@ namespace XCharts
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckRaycastTarget()
|
||||
{
|
||||
var ray = m_DataZoom.enable || (m_VisualMap.enable && m_VisualMap.show && m_VisualMap.calculable);
|
||||
if (raycastTarget != ray)
|
||||
{
|
||||
raycastTarget = ray;
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckDataZoom()
|
||||
{
|
||||
if (raycastTarget != m_DataZoom.enable)
|
||||
{
|
||||
raycastTarget = m_DataZoom.enable;
|
||||
}
|
||||
if (!m_DataZoom.enable) return;
|
||||
CheckDataZoomScale();
|
||||
CheckDataZoomLabel();
|
||||
@@ -1314,11 +1358,18 @@ namespace XCharts
|
||||
var pos = serie.dataPoints[j];
|
||||
serieData.SetGameObjectPosition(serieData.labelPosition);
|
||||
serieData.UpdateIcon();
|
||||
if (serie.show && serie.label.show)
|
||||
if (serie.show && serie.label.show && serieData.canShowLabel)
|
||||
{
|
||||
var value = serieData.data[1];
|
||||
float value = 0f;
|
||||
var dimension = 1;
|
||||
if (serie.type == SerieType.Heatmap)
|
||||
{
|
||||
dimension = m_VisualMap.enable && m_VisualMap.dimension > 0 ? m_VisualMap.dimension - 1 :
|
||||
serieData.data.Count - 1;
|
||||
}
|
||||
value = serieData.data[dimension];
|
||||
var content = serie.label.GetFormatterContent(serie.name, serieData.name, value, total);
|
||||
serieData.SetLabelActive(true);
|
||||
serieData.SetLabelActive(value != 0);
|
||||
serieData.SetLabelPosition(serie.label.offset);
|
||||
if (serieData.SetLabelText(content)) RefreshChart();
|
||||
}
|
||||
@@ -1343,7 +1394,6 @@ namespace XCharts
|
||||
{
|
||||
if (IsInCooridate(pos))
|
||||
{
|
||||
m_DataZoom.isDraging = true;
|
||||
m_DataZoomCoordinateDrag = true;
|
||||
}
|
||||
}
|
||||
@@ -1351,20 +1401,18 @@ namespace XCharts
|
||||
{
|
||||
if (m_DataZoom.IsInStartZoom(pos, coordinateX, coordinateWid))
|
||||
{
|
||||
m_DataZoom.isDraging = true;
|
||||
m_DataZoomStartDrag = true;
|
||||
}
|
||||
else if (m_DataZoom.IsInEndZoom(pos, coordinateX, coordinateWid))
|
||||
{
|
||||
m_DataZoom.isDraging = true;
|
||||
m_DataZoomEndDrag = true;
|
||||
}
|
||||
else if (m_DataZoom.IsInSelectedZoom(pos, coordinateX, coordinateWid))
|
||||
{
|
||||
m_DataZoom.isDraging = true;
|
||||
m_DataZoomDrag = true;
|
||||
}
|
||||
}
|
||||
OnDragVisualMapStart();
|
||||
}
|
||||
|
||||
public override void OnDrag(PointerEventData eventData)
|
||||
@@ -1374,6 +1422,7 @@ namespace XCharts
|
||||
float deltaPercent = deltaX / coordinateWid * 100;
|
||||
OnDragInside(deltaPercent);
|
||||
OnDragSlider(deltaPercent);
|
||||
OnDragVisualMap();
|
||||
}
|
||||
|
||||
private void OnDragInside(float deltaPercent)
|
||||
@@ -1471,7 +1520,7 @@ namespace XCharts
|
||||
m_DataZoomCoordinateDrag = false;
|
||||
m_DataZoomStartDrag = false;
|
||||
m_DataZoomEndDrag = false;
|
||||
m_DataZoom.isDraging = false;
|
||||
OnDragVisualMapEnd();
|
||||
}
|
||||
|
||||
public override void OnPointerDown(PointerEventData eventData)
|
||||
|
||||
@@ -49,8 +49,12 @@ namespace XCharts
|
||||
/// dataZoom component.
|
||||
/// 区域缩放组件。
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
public DataZoom dataZoom { get { return m_DataZoom; } }
|
||||
/// <summary>
|
||||
/// visualMap component.
|
||||
/// 视觉映射组件。
|
||||
/// </summary>
|
||||
public VisualMap visualMap { get { return m_VisualMap; } }
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -129,7 +133,15 @@ namespace XCharts
|
||||
|
||||
public bool IsCategory()
|
||||
{
|
||||
return !IsValue();
|
||||
foreach (var axis in m_XAxises)
|
||||
{
|
||||
if (axis.show && !axis.IsCategory()) return false;
|
||||
}
|
||||
foreach (var axis in m_YAxises)
|
||||
{
|
||||
if (axis.show && !axis.IsCategory()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsInCooridate(Vector2 local)
|
||||
|
||||
374
Scripts/UI/Internal/CoordinateChart_DrawHeatmap.cs
Normal file
374
Scripts/UI/Internal/CoordinateChart_DrawHeatmap.cs
Normal file
@@ -0,0 +1,374 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
public partial class CoordinateChart
|
||||
{
|
||||
private bool m_VisualMapMinDrag;
|
||||
private bool m_VisualMapMaxDrag;
|
||||
|
||||
protected void CheckVisualMap()
|
||||
{
|
||||
if (!m_VisualMap.enable || !m_VisualMap.show) return;
|
||||
Vector2 local;
|
||||
if (canvas == null) return;
|
||||
|
||||
if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform,
|
||||
Input.mousePosition, canvas.worldCamera, out local))
|
||||
{
|
||||
if (m_VisualMap.rtSelectedIndex >= 0)
|
||||
{
|
||||
m_VisualMap.rtSelectedIndex = -1;
|
||||
RefreshChart();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (local.x < 0 || local.x > chartWidth ||
|
||||
local.y < 0 || local.y > chartHeight ||
|
||||
!m_VisualMap.IsInRangeRect(local, chartWidth, chartHeight))
|
||||
{
|
||||
if (m_VisualMap.rtSelectedIndex >= 0)
|
||||
{
|
||||
m_VisualMap.rtSelectedIndex = -1;
|
||||
RefreshChart();
|
||||
}
|
||||
return;
|
||||
}
|
||||
var pos1 = Vector3.zero;
|
||||
var pos2 = Vector3.zero;
|
||||
var halfWid = m_VisualMap.itemWidth / 2;
|
||||
var halfHig = m_VisualMap.itemHeight / 2;
|
||||
var centerPos = m_VisualMap.location.GetPosition(chartWidth, chartHeight);
|
||||
var selectedIndex = -1;
|
||||
var value = 0f;
|
||||
switch (m_VisualMap.orient)
|
||||
{
|
||||
case Orient.Horizonal:
|
||||
pos1 = centerPos + Vector3.left * halfHig;
|
||||
pos2 = centerPos + Vector3.right * halfHig;
|
||||
value = m_VisualMap.min + (local.x - pos1.x) / (pos2.x - pos1.x) * (m_VisualMap.max - m_VisualMap.min);
|
||||
selectedIndex = m_VisualMap.GetIndex(value);
|
||||
break;
|
||||
case Orient.Vertical:
|
||||
pos1 = centerPos + Vector3.down * halfHig;
|
||||
pos2 = centerPos + Vector3.up * halfHig;
|
||||
value = m_VisualMap.min + (local.y - pos1.y) / (pos2.y - pos1.y) * (m_VisualMap.max - m_VisualMap.min);
|
||||
selectedIndex = m_VisualMap.GetIndex(value);
|
||||
break;
|
||||
}
|
||||
m_VisualMap.rtSelectedValue = value;
|
||||
m_VisualMap.rtSelectedIndex = selectedIndex;
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
protected void OnDragVisualMapStart()
|
||||
{
|
||||
if (!m_VisualMap.enable || !m_VisualMap.show || !m_VisualMap.calculable) return;
|
||||
var inMinRect = m_VisualMap.IsInRangeMinRect(pointerPos, chartWidth, chartHeight, m_Settings.visualMapTriangeLen);
|
||||
var inMaxRect = m_VisualMap.IsInRangeMaxRect(pointerPos, chartWidth, chartHeight, m_Settings.visualMapTriangeLen);
|
||||
if (inMinRect || inMaxRect)
|
||||
{
|
||||
if (inMinRect)
|
||||
{
|
||||
m_VisualMapMinDrag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_VisualMapMaxDrag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void OnDragVisualMap()
|
||||
{
|
||||
if (!m_VisualMap.enable || !m_VisualMap.show || !m_VisualMap.calculable) return;
|
||||
if (!m_VisualMapMinDrag && !m_VisualMapMaxDrag) return;
|
||||
|
||||
var centerPos = m_VisualMap.location.GetPosition(chartWidth, chartHeight);
|
||||
var isVertical = m_VisualMap.isVertical;
|
||||
var pos1 = centerPos + (isVertical ? Vector3.down : Vector3.left) * m_VisualMap.itemHeight / 2;
|
||||
var pos2 = centerPos + (isVertical ? Vector3.up : Vector3.right) * m_VisualMap.itemHeight / 2;
|
||||
var value = m_VisualMap.GetValue(pointerPos, chartWidth, chartHeight);
|
||||
if (m_VisualMapMinDrag)
|
||||
{
|
||||
m_VisualMap.rangeMin = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_VisualMap.rangeMax = value;
|
||||
}
|
||||
RefreshChart();
|
||||
}
|
||||
|
||||
protected void OnDragVisualMapEnd()
|
||||
{
|
||||
if (!m_VisualMap.enable || !m_VisualMap.show || !m_VisualMap.calculable) return;
|
||||
if (m_VisualMapMinDrag || m_VisualMapMaxDrag)
|
||||
{
|
||||
RefreshChart();
|
||||
m_VisualMapMinDrag = false;
|
||||
m_VisualMapMaxDrag = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawHeatmapSerie(VertexHelper vh, int colorIndex, Serie serie)
|
||||
{
|
||||
var yAxis = m_YAxises[serie.axisIndex];
|
||||
var xAxis = m_XAxises[serie.axisIndex];
|
||||
var xCount = xAxis.data.Count;
|
||||
var yCount = yAxis.data.Count;
|
||||
var xWidth = coordinateWid / xCount;
|
||||
var yWidth = coordinateHig / yCount;
|
||||
|
||||
var zeroX = coordinateX;
|
||||
var zeroY = coordinateY;
|
||||
var dataList = serie.GetDataList();
|
||||
var rangeMin = m_VisualMap.rangeMin;
|
||||
var rangeMax = m_VisualMap.rangeMax;
|
||||
var color = m_ThemeInfo.GetColor(serie.index);
|
||||
var borderWidth = serie.itemStyle.show ? serie.itemStyle.borderWidth : 0;
|
||||
var borderColor = serie.itemStyle.opacity > 0 ? serie.itemStyle.borderColor : Color.clear;
|
||||
borderColor.a *= serie.itemStyle.opacity;
|
||||
serie.dataPoints.Clear();
|
||||
for (int i = 0; i < xCount; i++)
|
||||
{
|
||||
for (int j = 0; j < yCount; j++)
|
||||
{
|
||||
var dataIndex = i * yCount + j;
|
||||
if (dataIndex >= dataList.Count) continue;
|
||||
var serieData = dataList[dataIndex];
|
||||
var dimension = m_VisualMap.enable && m_VisualMap.dimension > 0 ? m_VisualMap.dimension - 1 :
|
||||
serieData.data.Count - 1;
|
||||
var value = serieData.data[dimension];
|
||||
var pos = new Vector3(zeroX + (i + 0.5f) * xWidth, zeroY + (j + 0.5f) * yWidth);
|
||||
serie.dataPoints.Add(pos);
|
||||
serieData.canShowLabel = false;
|
||||
if (value == 0) continue;
|
||||
if (m_VisualMap.enable)
|
||||
{
|
||||
if ((value < rangeMin && rangeMin != m_VisualMap.min)
|
||||
|| (value > rangeMax && rangeMax != m_VisualMap.max))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!m_VisualMap.IsInSelectedValue(value)) continue;
|
||||
color = m_VisualMap.GetColor(value);
|
||||
}
|
||||
serieData.canShowLabel = true;
|
||||
var emphasis = (m_Tooltip.show && i == (int)m_Tooltip.xValues[0] && j == (int)m_Tooltip.yValues[0])
|
||||
|| m_VisualMap.rtSelectedIndex > 0;
|
||||
var rectWid = xWidth - 2 * borderWidth;
|
||||
var rectHig = yWidth - 2 * borderWidth;
|
||||
ChartDrawer.DrawPolygon(vh, pos, rectWid / 2, rectHig / 2, color);
|
||||
if (borderWidth > 0 && borderColor != Color.clear)
|
||||
{
|
||||
ChartDrawer.DrawBorder(vh, pos, rectWid, rectHig, borderWidth, borderColor);
|
||||
}
|
||||
if (m_VisualMap.hoverLink && emphasis && serie.emphasis.show && serie.emphasis.itemStyle.borderWidth > 0)
|
||||
{
|
||||
var emphasisBorderWidth = serie.emphasis.itemStyle.borderWidth;
|
||||
var emphasisBorderColor = serie.emphasis.itemStyle.opacity > 0 ? serie.emphasis.itemStyle.borderColor : Color.clear;
|
||||
ChartDrawer.DrawBorder(vh, pos, rectWid, rectHig, emphasisBorderWidth, emphasisBorderColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void DrawVisualMap(VertexHelper vh)
|
||||
{
|
||||
if (!m_VisualMap.enable || !m_VisualMap.show) return;
|
||||
var centerPos = m_VisualMap.location.GetPosition(chartWidth, chartHeight);
|
||||
|
||||
var pos1 = Vector3.zero;
|
||||
var pos2 = Vector3.zero;
|
||||
var dir = Vector3.zero;
|
||||
var halfWid = m_VisualMap.itemWidth / 2;
|
||||
var halfHig = m_VisualMap.itemHeight / 2;
|
||||
var xRadius = 0f;
|
||||
var yRadius = 0f;
|
||||
var splitNum = m_VisualMap.rtInRange.Count;
|
||||
var splitWid = m_VisualMap.itemHeight / (splitNum - 1);
|
||||
var isVertical = false;
|
||||
var colors = m_VisualMap.rtInRange;
|
||||
var triangeLen = m_Settings.visualMapTriangeLen;
|
||||
switch (m_VisualMap.orient)
|
||||
{
|
||||
case Orient.Horizonal:
|
||||
pos1 = centerPos + Vector3.left * halfHig;
|
||||
pos2 = centerPos + Vector3.right * halfHig;
|
||||
dir = Vector3.right;
|
||||
xRadius = splitWid / 2;
|
||||
yRadius = halfWid;
|
||||
isVertical = false;
|
||||
if (m_VisualMap.calculable)
|
||||
{
|
||||
var p0 = pos1 + Vector3.right * m_VisualMap.rangeMinHeight;
|
||||
var p1 = p0 + Vector3.up * halfWid;
|
||||
var p2 = p0 + Vector3.up * (halfWid + triangeLen);
|
||||
var p3 = p2 + Vector3.left * triangeLen;
|
||||
var color = m_VisualMap.GetColor(m_VisualMap.rangeMin);
|
||||
ChartDrawer.DrawTriangle(vh, p1, p2, p3, color);
|
||||
p0 = pos1 + Vector3.right * m_VisualMap.rangeMaxHeight;
|
||||
p1 = p0 + Vector3.up * halfWid;
|
||||
p2 = p0 + Vector3.up * (halfWid + triangeLen);
|
||||
p3 = p2 + Vector3.right * triangeLen;
|
||||
color = m_VisualMap.GetColor(m_VisualMap.rangeMax);
|
||||
ChartDrawer.DrawTriangle(vh, p1, p2, p3, color);
|
||||
}
|
||||
break;
|
||||
case Orient.Vertical:
|
||||
pos1 = centerPos + Vector3.down * halfHig;
|
||||
pos2 = centerPos + Vector3.up * halfHig;
|
||||
dir = Vector3.up;
|
||||
xRadius = halfWid;
|
||||
yRadius = splitWid / 2;
|
||||
isVertical = true;
|
||||
if (m_VisualMap.calculable)
|
||||
{
|
||||
var p0 = pos1 + Vector3.up * m_VisualMap.rangeMinHeight;
|
||||
var p1 = p0 + Vector3.right * halfWid;
|
||||
var p2 = p0 + Vector3.right * (halfWid + triangeLen);
|
||||
var p3 = p2 + Vector3.down * triangeLen;
|
||||
var color = m_VisualMap.GetColor(m_VisualMap.rangeMin);
|
||||
ChartDrawer.DrawTriangle(vh, p1, p2, p3, color);
|
||||
p0 = pos1 + Vector3.up * m_VisualMap.rangeMaxHeight;
|
||||
p1 = p0 + Vector3.right * halfWid;
|
||||
p2 = p0 + Vector3.right * (halfWid + triangeLen);
|
||||
p3 = p2 + Vector3.up * triangeLen;
|
||||
color = m_VisualMap.GetColor(m_VisualMap.rangeMax);
|
||||
ChartDrawer.DrawTriangle(vh, p1, p2, p3, color);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (m_VisualMap.calculable && (m_VisualMap.rangeMin > m_VisualMap.min
|
||||
|| m_VisualMap.rangeMax < m_VisualMap.max))
|
||||
{
|
||||
var rangeMin = m_VisualMap.rangeMin;
|
||||
var rangeMax = m_VisualMap.rangeMax;
|
||||
var diff = (m_VisualMap.max - m_VisualMap.min) / (splitNum - 1);
|
||||
for (int i = 1; i < splitNum; i++)
|
||||
{
|
||||
var splitMin = m_VisualMap.min + (i - 1) * diff;
|
||||
var splitMax = splitMin + diff;
|
||||
if (rangeMin > splitMax || rangeMax < splitMin)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (rangeMin <= splitMin && rangeMax >= splitMax)
|
||||
{
|
||||
var splitPos = pos1 + dir * (i - 1 + 0.5f) * splitWid;
|
||||
var startColor = colors[i - 1];
|
||||
var toColor = colors[i];
|
||||
ChartDrawer.DrawPolygon(vh, splitPos, xRadius, yRadius, startColor, toColor, isVertical);
|
||||
}
|
||||
else if (rangeMin > splitMin && rangeMax >= splitMax)
|
||||
{
|
||||
var p0 = pos1 + dir * m_VisualMap.rangeMinHeight;
|
||||
var splitMaxPos = pos1 + dir * i * splitWid;
|
||||
var splitPos = p0 + (splitMaxPos - p0) / 2;
|
||||
var startColor = m_VisualMap.GetColor(m_VisualMap.rangeMin);
|
||||
var toColor = colors[i];
|
||||
var yRadius1 = Vector3.Distance(p0, splitMaxPos) / 2;
|
||||
if (m_VisualMap.orient == Orient.Vertical)
|
||||
ChartDrawer.DrawPolygon(vh, splitPos, xRadius, yRadius1, startColor, toColor, isVertical);
|
||||
else
|
||||
ChartDrawer.DrawPolygon(vh, splitPos, yRadius1, yRadius, startColor, toColor, isVertical);
|
||||
}
|
||||
else if (rangeMax < splitMax && rangeMin <= splitMin)
|
||||
{
|
||||
var p0 = pos1 + dir * m_VisualMap.rangeMaxHeight;
|
||||
var splitMinPos = pos1 + dir * (i - 1) * splitWid;
|
||||
var splitPos = splitMinPos + (p0 - splitMinPos) / 2;
|
||||
var startColor = colors[i - 1];
|
||||
var toColor = m_VisualMap.GetColor(m_VisualMap.rangeMax);
|
||||
var yRadius1 = Vector3.Distance(p0, splitMinPos) / 2;
|
||||
if (m_VisualMap.orient == Orient.Vertical)
|
||||
ChartDrawer.DrawPolygon(vh, splitPos, xRadius, yRadius1, startColor, toColor, isVertical);
|
||||
else
|
||||
ChartDrawer.DrawPolygon(vh, splitPos, yRadius1, yRadius, startColor, toColor, isVertical);
|
||||
}
|
||||
else
|
||||
{
|
||||
var p0 = pos1 + dir * m_VisualMap.rangeMinHeight;
|
||||
var p1 = pos1 + dir * m_VisualMap.rangeMaxHeight;
|
||||
var splitPos = (p0 + p1) / 2;
|
||||
var startColor = m_VisualMap.GetColor(m_VisualMap.rangeMin);
|
||||
var toColor = m_VisualMap.GetColor(m_VisualMap.rangeMax);
|
||||
var yRadius1 = Vector3.Distance(p0, p1) / 2;
|
||||
if (m_VisualMap.orient == Orient.Vertical)
|
||||
ChartDrawer.DrawPolygon(vh, splitPos, xRadius, yRadius1, startColor, toColor, isVertical);
|
||||
else
|
||||
ChartDrawer.DrawPolygon(vh, splitPos, yRadius1, yRadius, startColor, toColor, isVertical);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 1; i < splitNum; i++)
|
||||
{
|
||||
var splitPos = pos1 + dir * (i - 1 + 0.5f) * splitWid;
|
||||
var startColor = colors[i - 1];
|
||||
var toColor = colors[i];
|
||||
ChartDrawer.DrawPolygon(vh, splitPos, xRadius, yRadius, startColor, toColor, isVertical);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_VisualMap.rangeMin > m_VisualMap.min)
|
||||
{
|
||||
var p0 = pos1 + dir * m_VisualMap.rangeMinHeight;
|
||||
ChartDrawer.DrawPolygon(vh, pos1, p0, m_VisualMap.itemWidth / 2, m_ThemeInfo.visualMapBackgroundColor);
|
||||
}
|
||||
if (m_VisualMap.rangeMax < m_VisualMap.max)
|
||||
{
|
||||
var p1 = pos1 + dir * m_VisualMap.rangeMaxHeight;
|
||||
ChartDrawer.DrawPolygon(vh, p1, pos2, m_VisualMap.itemWidth / 2, m_ThemeInfo.visualMapBackgroundColor);
|
||||
}
|
||||
|
||||
if (m_VisualMap.hoverLink)
|
||||
{
|
||||
if (m_VisualMap.rtSelectedIndex >= 0)
|
||||
{
|
||||
var p0 = pos1 + dir * m_VisualMap.rangeMinHeight;
|
||||
var p1 = pos1 + dir * m_VisualMap.rangeMaxHeight;
|
||||
|
||||
if (m_VisualMap.orient == Orient.Vertical)
|
||||
{
|
||||
var p2 = new Vector3(centerPos.x + halfWid, Mathf.Clamp(pointerPos.y + (triangeLen / 2), p0.y, p1.y));
|
||||
var p3 = new Vector3(centerPos.x + halfWid, Mathf.Clamp(pointerPos.y - (triangeLen / 2), p0.y, p1.y));
|
||||
var p4 = new Vector3(centerPos.x + halfWid + triangeLen / 2, pointerPos.y);
|
||||
ChartDrawer.DrawTriangle(vh, p2, p3, p4, colors[m_VisualMap.rtSelectedIndex]);
|
||||
}
|
||||
else
|
||||
{
|
||||
var p2 = new Vector3(Mathf.Clamp(pointerPos.x + (triangeLen / 2), p0.x, p1.x), centerPos.y + halfWid);
|
||||
var p3 = new Vector3(Mathf.Clamp(pointerPos.x - (triangeLen / 2), p0.x, p1.x), centerPos.y + halfWid);
|
||||
var p4 = new Vector3(pointerPos.x, centerPos.y + halfWid + triangeLen / 2);
|
||||
ChartDrawer.DrawTriangle(vh, p2, p3, p4, colors[m_VisualMap.rtSelectedIndex]);
|
||||
}
|
||||
}
|
||||
else if (m_Tooltip.show && m_Tooltip.xValues[0] >= 0 && m_Tooltip.yValues[0] >= 0)
|
||||
{
|
||||
// var p0 = pos1 + dir * m_VisualMap.rangeMinHeight;
|
||||
// var p1 = pos1 + dir * m_VisualMap.rangeMaxHeight;
|
||||
// if (m_VisualMap.orient == Orient.Vertical)
|
||||
// {
|
||||
// var p2 = new Vector3(centerPos.x + halfWid, Mathf.Clamp(pointerPos.y + (triangeLen / 2), p0.y, p1.y));
|
||||
// var p3 = new Vector3(centerPos.x + halfWid, Mathf.Clamp(pointerPos.y - (triangeLen / 2), p0.y, p1.y));
|
||||
// var p4 = new Vector3(centerPos.x + halfWid + triangeLen / 2, pointerPos.y);
|
||||
// ChartDrawer.DrawTriangle(vh, p2, p3, p4, colors[m_VisualMap.rtSelectedIndex]);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var p2 = new Vector3(Mathf.Clamp(pointerPos.x + (triangeLen / 2), p0.x, p1.x), centerPos.y + halfWid);
|
||||
// var p3 = new Vector3(Mathf.Clamp(pointerPos.x - (triangeLen / 2), p0.x, p1.x), centerPos.y + halfWid);
|
||||
// var p4 = new Vector3(pointerPos.x, centerPos.y + halfWid + triangeLen / 2);
|
||||
// ChartDrawer.DrawTriangle(vh, p2, p3, p4, colors[m_VisualMap.rtSelectedIndex]);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Scripts/UI/Internal/CoordinateChart_DrawHeatmap.cs.meta
Normal file
11
Scripts/UI/Internal/CoordinateChart_DrawHeatmap.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2713cb84109d8491aa61bf37d1fa850e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
28
Scripts/UI/Internal/Emphasis.cs
Normal file
28
Scripts/UI/Internal/Emphasis.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// 高亮的图形样式和文本标签样式。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class Emphasis
|
||||
{
|
||||
[SerializeField] private bool m_Show;
|
||||
[SerializeField] private SerieLabel m_Label = new SerieLabel();
|
||||
[SerializeField] private ItemStyle m_ItemStyle = new ItemStyle();
|
||||
/// <summary>
|
||||
/// 是否启用高亮样式。
|
||||
/// </summary>
|
||||
public bool show { get { return m_Show; } set { m_Show = value; } }
|
||||
/// <summary>
|
||||
/// 图形文本标签。
|
||||
/// </summary>
|
||||
public SerieLabel label { get { return m_Label; } }
|
||||
/// <summary>
|
||||
/// 图形样式。
|
||||
/// </summary>
|
||||
public ItemStyle itemStyle { get { return m_ItemStyle; } }
|
||||
}
|
||||
}
|
||||
11
Scripts/UI/Internal/Emphasis.cs.meta
Normal file
11
Scripts/UI/Internal/Emphasis.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6306ce69fc614416b82469b327516a49
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
62
Scripts/UI/Internal/ItemStyle.cs
Normal file
62
Scripts/UI/Internal/ItemStyle.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XCharts
|
||||
{
|
||||
/// <summary>
|
||||
/// 图形样式。
|
||||
/// </summary>
|
||||
[System.Serializable]
|
||||
public class ItemStyle
|
||||
{
|
||||
/// <summary>
|
||||
/// 线的类型。
|
||||
/// </summary>
|
||||
public enum Type
|
||||
{
|
||||
/// <summary>
|
||||
/// 实线
|
||||
/// </summary>
|
||||
Solid,
|
||||
/// <summary>
|
||||
/// 虚线
|
||||
/// </summary>
|
||||
Dashed,
|
||||
/// <summary>
|
||||
/// 点线
|
||||
/// </summary>
|
||||
Dotted
|
||||
}
|
||||
[SerializeField] private bool m_Show = false;
|
||||
[SerializeField] private Color m_Color;
|
||||
[SerializeField] private Type m_BorderType = Type.Solid;
|
||||
[SerializeField] private float m_BorderWidth = 0;
|
||||
[SerializeField] private Color m_BorderColor;
|
||||
[SerializeField] [Range(0, 1)] private float m_Opacity = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用。
|
||||
/// </summary>
|
||||
public bool show { get { return m_Show; } set { m_Show = value; } }
|
||||
/// <summary>
|
||||
/// 数据项颜色。
|
||||
/// </summary>
|
||||
public Color color { get { return m_Color; } set { m_Color = value; } }
|
||||
/// <summary>
|
||||
/// 边框的类型。
|
||||
/// </summary>
|
||||
public Type borderType { get { return m_BorderType; } set { m_BorderType = value; } }
|
||||
/// <summary>
|
||||
/// 边框的颜色。
|
||||
/// </summary>
|
||||
public Color borderColor { get { return m_BorderColor; } set { m_BorderColor = value; } }
|
||||
/// <summary>
|
||||
/// 边框宽。
|
||||
/// </summary>
|
||||
public float borderWidth { get { return m_BorderWidth; } set { m_BorderWidth = value; } }
|
||||
/// <summary>
|
||||
/// 透明度。支持从 0 到 1 的数字,为 0 时不绘制该图形。
|
||||
/// </summary>
|
||||
public float opacity { get { return m_Opacity; } set { m_Opacity = value; } }
|
||||
}
|
||||
}
|
||||
11
Scripts/UI/Internal/ItemStyle.cs.meta
Normal file
11
Scripts/UI/Internal/ItemStyle.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a89f8d34b0da24de4b59b179b022e685
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -213,31 +213,31 @@ namespace XCharts
|
||||
/// <summary>
|
||||
/// 返回在坐标系中的具体位置
|
||||
/// </summary>
|
||||
/// <param name="chartWidht"></param>
|
||||
/// <param name="chartWidth"></param>
|
||||
/// <param name="chartHeight"></param>
|
||||
/// <returns></returns>
|
||||
public Vector2 GetPosition(float chartWidht, float chartHeight)
|
||||
public Vector3 GetPosition(float chartWidth, float chartHeight)
|
||||
{
|
||||
switch (align)
|
||||
{
|
||||
case Align.BottomCenter:
|
||||
return new Vector2(chartWidht / 2, bottom);
|
||||
return new Vector3(chartWidth / 2, bottom);
|
||||
case Align.BottomLeft:
|
||||
return new Vector2(left, bottom);
|
||||
return new Vector3(left, bottom);
|
||||
case Align.BottomRight:
|
||||
return new Vector2(chartWidht - right, bottom);
|
||||
return new Vector3(chartWidth - right, bottom);
|
||||
case Align.Center:
|
||||
return new Vector2(chartWidht / 2, chartHeight / 2);
|
||||
return new Vector3(chartWidth / 2, chartHeight / 2);
|
||||
case Align.CenterLeft:
|
||||
return new Vector2(left, chartHeight / 2);
|
||||
return new Vector3(left, chartHeight / 2);
|
||||
case Align.CenterRight:
|
||||
return new Vector2(chartWidht - right, chartHeight / 2);
|
||||
return new Vector3(chartWidth - right, chartHeight / 2);
|
||||
case Align.TopCenter:
|
||||
return new Vector2(chartWidht / 2, chartHeight - top);
|
||||
return new Vector3(chartWidth / 2, chartHeight - top);
|
||||
case Align.TopLeft:
|
||||
return new Vector2(left, chartHeight - top);
|
||||
return new Vector3(left, chartHeight - top);
|
||||
case Align.TopRight:
|
||||
return new Vector2(chartWidht - right, chartHeight - top);
|
||||
return new Vector3(chartWidth - right, chartHeight - top);
|
||||
default:
|
||||
return Vector2.zero;
|
||||
}
|
||||
|
||||
@@ -331,7 +331,7 @@ namespace XCharts
|
||||
{
|
||||
if (serieData.labelText == null) return;
|
||||
var currAngle = serieData.pieHalfAngle;
|
||||
var isHighlight = (serieData.highlighted && serie.highlightLabel.show);
|
||||
var isHighlight = (serieData.highlighted && serie.emphasis.label.show);
|
||||
var showLabel = ((serie.label.show || isHighlight) && serieData.canShowLabel);
|
||||
if (showLabel || serieData.showIcon)
|
||||
{
|
||||
@@ -346,7 +346,7 @@ namespace XCharts
|
||||
Color color = serieColor;
|
||||
if (isHighlight)
|
||||
{
|
||||
if (serie.highlightLabel.color != Color.clear) color = serie.highlightLabel.color;
|
||||
if (serie.emphasis.label.color != Color.clear) color = serie.emphasis.label.color;
|
||||
}
|
||||
else if (serie.label.color != Color.clear)
|
||||
{
|
||||
@@ -356,8 +356,8 @@ namespace XCharts
|
||||
{
|
||||
color = isInsidePosition ? Color.white : serieColor;
|
||||
}
|
||||
var fontSize = isHighlight ? serie.highlightLabel.fontSize : serie.label.fontSize;
|
||||
var fontStyle = isHighlight ? serie.highlightLabel.fontStyle : serie.label.fontStyle;
|
||||
var fontSize = isHighlight ? serie.emphasis.label.fontSize : serie.label.fontSize;
|
||||
var fontStyle = isHighlight ? serie.emphasis.label.fontStyle : serie.label.fontStyle;
|
||||
|
||||
serieData.labelText.color = color;
|
||||
serieData.labelText.fontSize = fontSize;
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace XCharts
|
||||
private static Dictionary<float, string> s_ValueToF2Str = new Dictionary<float, string>(1000);
|
||||
private static Dictionary<float, string> s_ValueToStr = new Dictionary<float, string>(1000);
|
||||
private static Dictionary<int, string> s_IntToStr = new Dictionary<int, string>(1000);
|
||||
private static Dictionary<Color, string> s_ColorToStr = new Dictionary<Color, string>(1000);
|
||||
|
||||
public static string FloatToStr(float value, int f = 0)
|
||||
{
|
||||
@@ -42,5 +43,18 @@ namespace XCharts
|
||||
return s_IntToStr[value];
|
||||
}
|
||||
}
|
||||
|
||||
public static string ColorToStr(Color color)
|
||||
{
|
||||
if (s_ColorToStr.ContainsKey(color))
|
||||
{
|
||||
return s_ColorToStr[color];
|
||||
}
|
||||
else
|
||||
{
|
||||
s_ColorToStr[color] = ColorUtility.ToHtmlStringRGBA(color);
|
||||
return s_ColorToStr[color];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,15 +122,74 @@ namespace XCharts
|
||||
DrawLine(vh, sp, p2, size, color);
|
||||
}
|
||||
|
||||
public static void DrawPolygon(VertexHelper vh, Vector3 p, float size, Color32 color)
|
||||
public static void DrawPolygon(VertexHelper vh, Vector3 p, float radius, Color32 color,
|
||||
bool vertical = true)
|
||||
{
|
||||
Vector3 p1 = new Vector3(p.x - size, p.y - size);
|
||||
Vector3 p2 = new Vector3(p.x + size, p.y - size);
|
||||
Vector3 p3 = new Vector3(p.x + size, p.y + size);
|
||||
Vector3 p4 = new Vector3(p.x - size, p.y + size);
|
||||
Vector3 p1, p2, p3, p4;
|
||||
if (vertical)
|
||||
{
|
||||
p1 = new Vector3(p.x + radius, p.y - radius);
|
||||
p2 = new Vector3(p.x - radius, p.y - radius);
|
||||
p3 = new Vector3(p.x - radius, p.y + radius);
|
||||
p4 = new Vector3(p.x + radius, p.y + radius);
|
||||
}
|
||||
else
|
||||
{
|
||||
p1 = new Vector3(p.x - radius, p.y - radius);
|
||||
p2 = new Vector3(p.x - radius, p.y + radius);
|
||||
p3 = new Vector3(p.x + radius, p.y + radius);
|
||||
p4 = new Vector3(p.x + radius, p.y - radius);
|
||||
}
|
||||
DrawPolygon(vh, p1, p2, p3, p4, color, color);
|
||||
}
|
||||
|
||||
public static void DrawPolygon(VertexHelper vh, Vector3 p1, Vector3 p2, float radius, Color32 color)
|
||||
{
|
||||
DrawPolygon(vh, p1, p2, radius, color, color);
|
||||
}
|
||||
|
||||
public static void DrawPolygon(VertexHelper vh, Vector3 p1, Vector3 p2, float radius, Color32 color, Color32 toColor)
|
||||
{
|
||||
var dir = (p2 - p1).normalized;
|
||||
var dirv = Vector3.Cross(dir, Vector3.forward).normalized;
|
||||
|
||||
var p3 = p1 + dirv * radius;
|
||||
var p4 = p1 - dirv * radius;
|
||||
var p5 = p2 - dirv * radius;
|
||||
var p6 = p2 + dirv * radius;
|
||||
DrawPolygon(vh, p3, p4, p5, p6, color, toColor);
|
||||
}
|
||||
|
||||
public static void DrawPolygon(VertexHelper vh, Vector3 p, float xRadius, float yRadius,
|
||||
Color32 color, bool vertical = true)
|
||||
{
|
||||
DrawPolygon(vh, p, xRadius, yRadius, color, color, vertical);
|
||||
}
|
||||
|
||||
public static void DrawPolygon(VertexHelper vh, Vector3 p, float xRadius, float yRadius,
|
||||
Color32 color, Color toColor, bool vertical = true)
|
||||
{
|
||||
Vector3 p1, p2, p3, p4;
|
||||
if (vertical)
|
||||
{
|
||||
p1 = new Vector3(p.x + xRadius, p.y - yRadius);
|
||||
p2 = new Vector3(p.x - xRadius, p.y - yRadius);
|
||||
p3 = new Vector3(p.x - xRadius, p.y + yRadius);
|
||||
p4 = new Vector3(p.x + xRadius, p.y + yRadius);
|
||||
}
|
||||
else
|
||||
{
|
||||
p1 = new Vector3(p.x - xRadius, p.y - yRadius);
|
||||
p2 = new Vector3(p.x - xRadius, p.y + yRadius);
|
||||
p3 = new Vector3(p.x + xRadius, p.y + yRadius);
|
||||
p4 = new Vector3(p.x + xRadius, p.y - yRadius);
|
||||
}
|
||||
|
||||
DrawPolygon(vh, p1, p2, p3, p4, color, toColor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void DrawPolygon(VertexHelper vh, Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
|
||||
Color32 color)
|
||||
{
|
||||
@@ -152,6 +211,25 @@ namespace XCharts
|
||||
vh.AddUIVertexQuad(vertex);
|
||||
}
|
||||
|
||||
public static void DrawBorder(VertexHelper vh, Vector3 p, float rectWidth, float rectHeight,
|
||||
float borderWidth, Color32 color)
|
||||
{
|
||||
var halfWid = rectWidth / 2;
|
||||
var halfHig = rectHeight / 2;
|
||||
var p1In = new Vector3(p.x - halfWid, p.y - halfHig);
|
||||
var p1Ot = new Vector3(p.x - halfWid - borderWidth, p.y - halfHig - borderWidth);
|
||||
var p2In = new Vector3(p.x - halfWid, p.y + halfHig);
|
||||
var p2Ot = new Vector3(p.x - halfWid - borderWidth, p.y + halfHig + borderWidth);
|
||||
var p3In = new Vector3(p.x + halfWid, p.y + halfHig);
|
||||
var p3Ot = new Vector3(p.x + halfWid + borderWidth, p.y + halfHig + borderWidth);
|
||||
var p4In = new Vector3(p.x + halfWid, p.y - halfHig);
|
||||
var p4Ot = new Vector3(p.x + halfWid + borderWidth, p.y - halfHig - borderWidth);
|
||||
DrawPolygon(vh, p1In, p1Ot, p2Ot, p2In, color);
|
||||
DrawPolygon(vh, p2In, p2Ot, p3Ot, p3In, color);
|
||||
DrawPolygon(vh, p3In, p3Ot, p4Ot, p4In, color);
|
||||
DrawPolygon(vh, p4In, p4Ot, p1Ot, p1In, color);
|
||||
}
|
||||
|
||||
public static void DrawTriangle(VertexHelper vh, Vector3 p1,
|
||||
Vector3 p2, Vector3 p3, Color32 color)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user