增加HeatmapChart热力图

This commit is contained in:
monitor1394
2019-10-14 07:45:56 +08:00
parent c54c8e60d2
commit d7933eb06e
41 changed files with 182730 additions and 60532 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -16,6 +16,7 @@ namespace XCharts
protected SerializedProperty m_MultipleYAxis;
protected SerializedProperty m_YAxises;
protected SerializedProperty m_DataZoom;
protected SerializedProperty m_VisualMap;
protected override void OnEnable()
{
@@ -25,12 +26,14 @@ namespace XCharts
m_XAxises = serializedObject.FindProperty("m_XAxises");
m_YAxises = serializedObject.FindProperty("m_YAxises");
m_DataZoom = serializedObject.FindProperty("m_DataZoom");
m_VisualMap = serializedObject.FindProperty("m_VisualMap");
}
protected override void OnStartInspectorGUI()
{
base.OnStartInspectorGUI();
EditorGUILayout.PropertyField(m_DataZoom);
EditorGUILayout.PropertyField(m_VisualMap);
EditorGUILayout.PropertyField(m_Grid);
for (int i = 0; i < m_XAxises.arraySize; i++)
{

View File

@@ -0,0 +1,23 @@
using UnityEditor;
namespace XCharts
{
/// <summary>
/// Editor class used to edit UI HeatmapChart.
/// </summary>
[CustomEditor(typeof(HeatmapChart), false)]
public class HeatmapChartEditor : CoordinateChartEditor
{
protected override void OnEnable()
{
base.OnEnable();
m_Target = (HeatmapChart)target;
}
protected override void OnEndInspectorGUI()
{
base.OnEndInspectorGUI();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1144057dfc00f4572913a63ba5291dd7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,48 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(Emphasis), true)]
public class EmphasisDrawer : PropertyDrawer
{
private Dictionary<string, bool> m_EmphasisToggle = new Dictionary<string, bool>();
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
Rect drawRect = pos;
drawRect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty show = prop.FindPropertyRelative("m_Show");
SerializedProperty m_Label = prop.FindPropertyRelative("m_Label");
SerializedProperty m_ItemStyle = prop.FindPropertyRelative("m_ItemStyle");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_EmphasisToggle, prop, "Emphasis", show, false);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (ChartEditorHelper.IsToggle(m_EmphasisToggle, prop))
{
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_Label);
drawRect.y += EditorGUI.GetPropertyHeight(m_Label);
EditorGUI.PropertyField(drawRect, m_ItemStyle);
drawRect.y += EditorGUI.GetPropertyHeight(m_ItemStyle);
--EditorGUI.indentLevel;
}
}
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
float height = 0;
if (ChartEditorHelper.IsToggle(m_EmphasisToggle, prop))
{
height += 1 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing;
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Label"));
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_ItemStyle"));
}
else
{
height += 1 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing;
}
return height;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7de9b5e4c5d474fdd88ebb89f0924305
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,55 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(ItemStyle), true)]
public class ItemStyleDrawer : PropertyDrawer
{
private Dictionary<string, bool> m_ItemStyleToggle = new Dictionary<string, bool>();
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
Rect drawRect = pos;
drawRect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty show = prop.FindPropertyRelative("m_Show");
SerializedProperty m_Color = prop.FindPropertyRelative("m_Color");
SerializedProperty m_BorderType = prop.FindPropertyRelative("m_BorderType");
SerializedProperty m_BorderWidth = prop.FindPropertyRelative("m_BorderWidth");
SerializedProperty m_BorderColor = prop.FindPropertyRelative("m_BorderColor");
SerializedProperty m_Opacity = prop.FindPropertyRelative("m_Opacity");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_ItemStyleToggle, prop, "Item Style", show, false);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (ChartEditorHelper.IsToggle(m_ItemStyleToggle, prop))
{
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_Color);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_BorderType);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_BorderWidth);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_BorderColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Opacity);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
--EditorGUI.indentLevel;
}
}
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
float height = 0;
if (ChartEditorHelper.IsToggle(m_ItemStyleToggle, prop))
{
height += 6 * EditorGUIUtility.singleLineHeight + 5 * EditorGUIUtility.standardVerticalSpacing;
}
else
{
height += 1 * EditorGUIUtility.singleLineHeight + 1 * EditorGUIUtility.standardVerticalSpacing;
}
return height;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f40830a3b05574467ad0d8873c6c8790
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -27,6 +27,7 @@ namespace XCharts
SerializedProperty m_MaxCache = prop.FindPropertyRelative("m_MaxCache");
SerializedProperty m_LineStyle = prop.FindPropertyRelative("m_LineStyle");
SerializedProperty m_ItemStyle = prop.FindPropertyRelative("m_ItemStyle");
SerializedProperty m_LineArrow = prop.FindPropertyRelative("m_LineArrow");
SerializedProperty m_LineType = prop.FindPropertyRelative("m_LineType");
SerializedProperty m_SampleDist = prop.FindPropertyRelative("m_SampleDist");
@@ -42,7 +43,7 @@ namespace XCharts
SerializedProperty m_Center = prop.FindPropertyRelative("m_Center");
SerializedProperty m_Radius = prop.FindPropertyRelative("m_Radius");
SerializedProperty m_Label = prop.FindPropertyRelative("m_Label");
SerializedProperty m_HighlightLabel = prop.FindPropertyRelative("m_HighlightLabel");
SerializedProperty m_Emphasis = prop.FindPropertyRelative("m_Emphasis");
SerializedProperty m_Animation = prop.FindPropertyRelative("m_Animation");
SerializedProperty m_DataDimension = prop.FindPropertyRelative("m_ShowDataDimension");
SerializedProperty m_ShowDataName = prop.FindPropertyRelative("m_ShowDataName");
@@ -125,31 +126,8 @@ namespace XCharts
EditorGUI.PropertyField(drawRect, m_Space);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.LabelField(drawRect, "Center");
var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * 15;
var tempWidth = (pos.width - startX + 35) / 2;
var centerXRect = new Rect(startX, drawRect.y, tempWidth, drawRect.height);
var centerYRect = new Rect(centerXRect.x + tempWidth - 20, drawRect.y, tempWidth, drawRect.height);
while (m_Center.arraySize < 2)
{
m_Center.InsertArrayElementAtIndex(m_Center.arraySize);
}
EditorGUI.PropertyField(centerXRect, m_Center.GetArrayElementAtIndex(0), GUIContent.none);
EditorGUI.PropertyField(centerYRect, m_Center.GetArrayElementAtIndex(1), GUIContent.none);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
centerXRect = new Rect(startX, drawRect.y, tempWidth, drawRect.height);
centerYRect = new Rect(centerXRect.x + tempWidth - 20, drawRect.y, tempWidth, drawRect.height);
EditorGUI.LabelField(drawRect, "Radius");
while (m_Radius.arraySize < 2)
{
m_Radius.InsertArrayElementAtIndex(m_Radius.arraySize);
}
EditorGUI.PropertyField(centerXRect, m_Radius.GetArrayElementAtIndex(0), GUIContent.none);
EditorGUI.PropertyField(centerYRect, m_Radius.GetArrayElementAtIndex(1), GUIContent.none);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_ClickOffset);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
ChartEditorHelper.MakeTwoField(ref drawRect,pos.width,m_Center,"Center");
ChartEditorHelper.MakeTwoField(ref drawRect,pos.width,m_Center,"Radius");
}
EditorGUI.PropertyField(drawRect, m_LineStyle);
@@ -159,12 +137,14 @@ namespace XCharts
EditorGUI.PropertyField(drawRect, m_LineArrow);
drawRect.y += EditorGUI.GetPropertyHeight(m_LineArrow);
}
EditorGUI.PropertyField(drawRect, m_ItemStyle);
drawRect.y += EditorGUI.GetPropertyHeight(m_ItemStyle);
EditorGUI.PropertyField(drawRect, m_AreaStyle);
drawRect.y += EditorGUI.GetPropertyHeight(m_AreaStyle);
EditorGUI.PropertyField(drawRect, m_Label, new GUIContent("Normal Label"));
EditorGUI.PropertyField(drawRect, m_Label);
drawRect.y += EditorGUI.GetPropertyHeight(m_Label);
EditorGUI.PropertyField(drawRect, m_HighlightLabel, new GUIContent("Highlight Label"));
drawRect.y += EditorGUI.GetPropertyHeight(m_HighlightLabel);
EditorGUI.PropertyField(drawRect, m_Emphasis);
drawRect.y += EditorGUI.GetPropertyHeight(m_Emphasis);
EditorGUI.PropertyField(drawRect, m_Animation);
drawRect.y += EditorGUI.GetPropertyHeight(m_Animation);
drawRect.width = EditorGUIUtility.labelWidth + 10;
@@ -344,9 +324,10 @@ namespace XCharts
{
height += 9 * EditorGUIUtility.singleLineHeight + 8 * EditorGUIUtility.standardVerticalSpacing;
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_LineStyle"));
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_ItemStyle"));
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_AreaStyle"));
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Label"));
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_HighlightLabel"));
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Emphasis"));
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Animation"));
SerializedProperty type = prop.FindPropertyRelative("m_Type");
var serieType = (SerieType)type.enumValueIndex;

View File

@@ -17,6 +17,7 @@ namespace XCharts
SerializedProperty m_LineSmoothness = prop.FindPropertyRelative("m_LineSmoothness");
SerializedProperty m_LineSegmentDistance = prop.FindPropertyRelative("m_LineSegmentDistance");
SerializedProperty m_CicleSmoothness = prop.FindPropertyRelative("m_CicleSmoothness");
SerializedProperty m_VisualMapTriangeLen = prop.FindPropertyRelative("m_VisualMapTriangeLen");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_SettingsModuleToggle, "Settings");
EditorGUI.LabelField(drawRect, "Settings", EditorStyles.boldLabel);
@@ -32,6 +33,8 @@ namespace XCharts
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_CicleSmoothness);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_VisualMapTriangeLen);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
--EditorGUI.indentLevel;
}
}
@@ -41,7 +44,7 @@ namespace XCharts
int num = 1;
if (m_SettingsModuleToggle)
{
num = 5;
num = 6;
}
return num * EditorGUIUtility.singleLineHeight + (num - 1) * EditorGUIUtility.standardVerticalSpacing;
}

View File

@@ -35,6 +35,8 @@ namespace XCharts
SerializedProperty m_DataZoomLineColor = prop.FindPropertyRelative("m_DataZoomLineColor");
SerializedProperty m_DataZoomSelectedColor = prop.FindPropertyRelative("m_DataZoomSelectedColor");
SerializedProperty m_DataZoomTextColor = prop.FindPropertyRelative("m_DataZoomTextColor");
SerializedProperty m_VisualMapBackgroundColor = prop.FindPropertyRelative("m_VisualMapBackgroundColor");
SerializedProperty m_VisualMapBorderColor = prop.FindPropertyRelative("m_VisualMapBorderColor");
SerializedProperty m_ColorPalette = prop.FindPropertyRelative("m_ColorPalette");
SerializedProperty m_CustomFont = prop.FindPropertyRelative("m_CustomFont");
@@ -54,6 +56,8 @@ namespace XCharts
SerializedProperty m_CustomDataZoomLineColor = prop.FindPropertyRelative("m_CustomDataZoomLineColor");
SerializedProperty m_CustomDataZoomSelectedColor = prop.FindPropertyRelative("m_CustomDataZoomSelectedColor");
SerializedProperty m_CustomDataZoomTextColor = prop.FindPropertyRelative("m_CustomDataZoomTextColor");
SerializedProperty m_CustomVisualMapBackgroundColor = prop.FindPropertyRelative("m_CustomVisualMapBackgroundColor");
SerializedProperty m_CustomVisualMapBorderColor = prop.FindPropertyRelative("m_CustomVisualMapBorderColor");
SerializedProperty m_CustomColorPalette = prop.FindPropertyRelative("m_CustomColorPalette");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_ThemeModuleToggle, "Theme");
@@ -83,6 +87,8 @@ namespace XCharts
m_CustomDataZoomLineColor.colorValue = Color.clear;
m_CustomDataZoomSelectedColor.colorValue = Color.clear;
m_CustomDataZoomTextColor.colorValue = Color.clear;
m_CustomVisualMapBackgroundColor.colorValue = Color.clear;
m_CustomVisualMapBorderColor.colorValue = Color.clear;
for (int i = 0; i < m_CustomColorPalette.arraySize; i++)
{
m_CustomColorPalette.GetArrayElementAtIndex(i).colorValue = Color.clear;
@@ -112,6 +118,8 @@ namespace XCharts
m_DataZoomLineColor.colorValue = defaultThemeInfo.dataZoomLineColor;
m_DataZoomSelectedColor.colorValue = defaultThemeInfo.dataZoomSelectedColor;
m_DataZoomTextColor.colorValue = defaultThemeInfo.dataZoomTextColor;
m_VisualMapBackgroundColor.colorValue = defaultThemeInfo.visualMapBackgroundColor;
m_VisualMapBorderColor.colorValue = defaultThemeInfo.visualMapBorderColor;
for (int i = 0; i < m_ColorPalette.arraySize; i++)
{
m_ColorPalette.GetArrayElementAtIndex(i).colorValue = defaultThemeInfo.GetColor(i);
@@ -276,6 +284,24 @@ namespace XCharts
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomVisualMapBackgroundColor.colorValue != Color.clear ? m_CustomVisualMapBackgroundColor : m_VisualMapBackgroundColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("VisualMap Background Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomVisualMapBackgroundColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.BeginChangeCheck();
color = m_CustomVisualMapBorderColor.colorValue != Color.clear ? m_CustomVisualMapBorderColor : m_VisualMapBorderColor;
EditorGUI.PropertyField(drawRect, color, new GUIContent("VisualMap Border Color"));
if (EditorGUI.EndChangeCheck())
{
m_CustomVisualMapBorderColor.colorValue = color.colorValue;
}
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
m_ColorPaletteFoldout = EditorGUI.Foldout(drawRect, m_ColorPaletteFoldout, "ColorPalette");
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_ColorPaletteFoldout)
@@ -315,7 +341,7 @@ namespace XCharts
else
{
float height = 0;
int propertyCount = 18;
int propertyCount = 20;
if (m_ColorPaletteFoldout)
{
SerializedProperty m_ColorPalette = prop.FindPropertyRelative("m_ColorPalette");

View File

@@ -0,0 +1,138 @@
using UnityEditor;
using UnityEngine;
namespace XCharts
{
[CustomPropertyDrawer(typeof(VisualMap), true)]
public class VisualMapDrawer : PropertyDrawer
{
private bool m_VisualMapModuleToggle = false;
private bool m_InRangeFoldout;
private bool m_OutOfRangeFoldout;
private int m_InRangeSize;
private int m_OutOfRangeSize;
public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label)
{
Rect drawRect = pos;
drawRect.height = EditorGUIUtility.singleLineHeight;
SerializedProperty m_Enable = prop.FindPropertyRelative("m_Enable");
SerializedProperty m_Type = prop.FindPropertyRelative("m_Type");
SerializedProperty m_Show = prop.FindPropertyRelative("m_Show");
SerializedProperty m_SelectedMode = prop.FindPropertyRelative("m_SelectedMode");
SerializedProperty m_Min = prop.FindPropertyRelative("m_Min");
SerializedProperty m_Max = prop.FindPropertyRelative("m_Max");
SerializedProperty m_Range = prop.FindPropertyRelative("m_Range");
SerializedProperty m_Text = prop.FindPropertyRelative("m_Text");
SerializedProperty m_TextGap = prop.FindPropertyRelative("m_TextGap");
SerializedProperty m_SplitNumber = prop.FindPropertyRelative("m_SplitNumber");
SerializedProperty m_Calculable = prop.FindPropertyRelative("m_Calculable");
SerializedProperty m_ItemWidth = prop.FindPropertyRelative("m_ItemWidth");
SerializedProperty m_ItemHeight = prop.FindPropertyRelative("m_ItemHeight");
SerializedProperty m_BorderWidth = prop.FindPropertyRelative("m_BorderWidth");
SerializedProperty m_Dimension = prop.FindPropertyRelative("m_Dimension");
SerializedProperty m_HoverLink = prop.FindPropertyRelative("m_HoverLink");
SerializedProperty m_Orient = prop.FindPropertyRelative("m_Orient");
SerializedProperty m_Location = prop.FindPropertyRelative("m_Location");
SerializedProperty m_InRange = prop.FindPropertyRelative("m_InRange");
SerializedProperty m_OutOfRange = prop.FindPropertyRelative("m_OutOfRange");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_VisualMapModuleToggle, "Visual Map", m_Enable);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_VisualMapModuleToggle)
{
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_Type);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Min);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Max);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_SplitNumber);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Dimension);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_HoverLink);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
m_InRangeFoldout = EditorGUI.Foldout(drawRect, m_InRangeFoldout, "InRange");
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_InRangeFoldout)
{
ChartEditorHelper.MakeList(ref drawRect, ref m_InRangeSize, m_InRange);
}
// drawRect.width = pos.width;
// m_OutOfRangeFoldout = EditorGUI.Foldout(drawRect, m_OutOfRangeFoldout, "OutOfRange");
// drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
// if (m_OutOfRangeFoldout)
// {
// ChartEditorHelper.MakeList(ref drawRect, ref m_OutOfRangeSize, m_OutOfRange);
// }
// drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Show);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
if (m_Show.boolValue)
{
EditorGUI.PropertyField(drawRect, m_SelectedMode);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
ChartEditorHelper.MakeTwoField(ref drawRect, pos.width, m_Range, "Range");
ChartEditorHelper.MakeTwoField(ref drawRect, pos.width, m_Text, "Text");
ChartEditorHelper.MakeTwoField(ref drawRect, pos.width, m_Text, "TextGap");
EditorGUI.PropertyField(drawRect, m_Calculable);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_ItemWidth);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_ItemHeight);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_BorderWidth);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Orient);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Location);
drawRect.y += EditorGUI.GetPropertyHeight(m_Location);
}
--EditorGUI.indentLevel;
}
}
public override float GetPropertyHeight(SerializedProperty prop, GUIContent label)
{
float height = 0;
int num = 1;
if (m_VisualMapModuleToggle)
{
num += 8;
height += num * EditorGUIUtility.singleLineHeight + (num - 1) * EditorGUIUtility.standardVerticalSpacing;
if (m_InRangeFoldout)
{
SerializedProperty m_InRange = prop.FindPropertyRelative("m_InRange");
int size = m_InRange.arraySize + 1;
height += size * EditorGUIUtility.singleLineHeight + (size - 1) * EditorGUIUtility.standardVerticalSpacing;
height += EditorGUIUtility.standardVerticalSpacing;
}
// if (m_OutOfRangeFoldout)
// {
// SerializedProperty m_OutOfRange = prop.FindPropertyRelative("m_OutOfRange");
// int size = m_OutOfRange.arraySize + 1;
// height += size * EditorGUIUtility.singleLineHeight + (size - 1) * EditorGUIUtility.standardVerticalSpacing;
// height += EditorGUIUtility.standardVerticalSpacing;
// }
if (prop.FindPropertyRelative("m_Show").boolValue)
{
height += 9 * EditorGUIUtility.singleLineHeight + 8 * EditorGUIUtility.standardVerticalSpacing;
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Location"));
}
}
else
{
height += num * EditorGUIUtility.singleLineHeight + (num - 1) * EditorGUIUtility.standardVerticalSpacing;
}
return height;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0fe31d791669a4014ac78fd7a2af9a6c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -19,6 +19,29 @@ public class ChartEditorHelper
drawRect = offset.Remove(drawRect);
}
public static void MakeTwoField(ref Rect drawRect, float rectWidth, SerializedProperty arrayProp, string name)
{
while (arrayProp.arraySize < 2)
{
arrayProp.InsertArrayElementAtIndex(arrayProp.arraySize);
}
MakeTwoField(ref drawRect, rectWidth, arrayProp.GetArrayElementAtIndex(0), arrayProp.GetArrayElementAtIndex(1), name);
}
public static void MakeTwoField(ref Rect drawRect, float rectWidth, SerializedProperty prop1, SerializedProperty prop2, string name)
{
EditorGUI.LabelField(drawRect, name);
var startX = drawRect.x + EditorGUIUtility.labelWidth - EditorGUI.indentLevel * 15;
var diff = 14 + EditorGUI.indentLevel * 14;
var offset = diff - 15;
var tempWidth = (rectWidth - startX + diff) / 2;
var centerXRect = new Rect(startX, drawRect.y, tempWidth, drawRect.height);
var centerYRect = new Rect(centerXRect.x + tempWidth - offset, drawRect.y, tempWidth, drawRect.height);
EditorGUI.PropertyField(centerXRect, prop1, GUIContent.none);
EditorGUI.PropertyField(centerYRect, prop2, GUIContent.none);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
}
public static void MakeJsonData(ref Rect drawRect, ref bool showTextArea, ref string inputString,
SerializedProperty prop, float currentWidth, float diff = 0)
{
@@ -91,7 +114,7 @@ public class ChartEditorHelper
{
if (showProp.propertyType == SerializedPropertyType.Boolean)
{
drawRect.width = 40;
drawRect.width = 60;
}
else
{

View File

@@ -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.
/// 坐标轴轴线。

View File

@@ -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.
/// 组件的开始信息文本。

View File

@@ -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,

View File

@@ -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)
{

View File

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

View File

@@ -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),

View File

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

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

View 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
View 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]);
}
}
}
}

View 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
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 58d150a402b5e4bfcbec6a28cba7ed44
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View 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
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 947fc87a63dec45f8b27ade5f0d050c4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -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)

View File

@@ -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)

View 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]);
// }
}
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2713cb84109d8491aa61bf37d1fa850e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6306ce69fc614416b82469b327516a49
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a89f8d34b0da24de4b59b179b022e685
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

@@ -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;

View File

@@ -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];
}
}
}
}

View File

@@ -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)
{