增加LineChart可通过VisualMapItemStyle配置渐变#78

This commit is contained in:
monitor1394
2020-07-30 09:31:44 +08:00
parent 6ea04ed671
commit 4c9f60e6c6
16 changed files with 332 additions and 58 deletions

View File

@@ -1,6 +1,7 @@
# 更新日志
* (2020.07.30) Added `LineChart` to configure gradient through `VisualMap` or `ItemStyle`#78
* (2020.07.25) Fixed a problem with `LineChart` emerging abnormal in animation drawing#79
* (2020.07.25) Fixed a problem with gradual discoloration on `LiquidChart` at `100%`#80
* (2020.07.25) Added `RadarChart` support for `formatter` of `Tooltip`#77

View File

@@ -1,6 +1,7 @@
# 更新日志
* (2020.07.30) 增加`LineChart`可通过`VisualMap``ItemStyle`配置渐变#78
* (2020.07.25) 修复`LineChart`渐出动画绘制异常的问题#79
* (2020.07.25) 修复`LiquidChart``100%`时渐变色会失效的问题#80
* (2020.07.25) 增加`RadarChart``Tooltip``formatter`支持#77

View File

@@ -300,8 +300,9 @@
* ~~`selectedMode`:分段型的选择模式,支持以下模式:~~
* ~~`Multiple`:多选。~~
* ~~`Single`:单选。~~
* `min`:允许的最小值。'min' 必须用户指定。[visualMap.min, visualMap.max] 形成了视觉映射的『定义域』
* `max`:允许的最值。'max' 必须用户指定。[visualMap.min, visualMax.max] 形成了视觉映射的『定义域』。
* `autoMinMax`:自动设置`min``max`的值
* `min`:允许的最值。`autoMinMax``false`时必须指定。`[min, max]` 形成了视觉映射的『定义域』。
* `max`:允许的最大值。`autoMinMax``false`时必须指定。`[min, max]` 形成了视觉映射的『定义域』。
* `range`指定手柄对应数值的位置。range 应在 min max 范围内。
* ~~`text`:两端的文本,如 ['High', 'Low']。~~
* ~~`textGap`两端文字主体之间的距离单位为px。~~
@@ -831,6 +832,8 @@
* `show`:是否启用。
* `color`:颜色。
* `toColor`渐变颜色1。
* `toColor2`渐变颜色2。只在折线图中有效。
* `backgroundColor`:背景颜色。
* `backgroundWidth`:背景的宽。
* `centerColor`:中心区域的颜色。如环形图的中心区域。

View File

@@ -299,6 +299,8 @@ VisualMap component. mapping data to visual elements such as colors.
* ~~`selectedMode`: the selected mode for Piecewise visualMap.~~
* ~~`Multiple`: Multiple.~~
* ~~`Single`: Single.~~
* `autoMinMax`: Automatically set min, Max value.
* `min`: The minimum allowed. `min` must be user specified. `[min, max]` forms the domain of the visualMap.
* `max`: The maximum allowed. `max` must be user specified. `[min, max]` forms the domain of the visualMap.
* `range`: Specifies the position of the numeric value corresponding to the handle. Range should be within the range of [min,max].
@@ -406,7 +408,7 @@ Check each serie for parameters.
Line chart serie.
* `show`: Whether to show serie in chart.
* `type`: `Line`
* `type`: `Line`.
* `name`: Series name used for displaying in tooltip and filtering with legend.
* `stack`: If stack the value. On the same category axis, the series with the same stack name would be put on top of each other.
* `axisIndex`: Index of axis to combine with, which is useful for multiple x axes in one chart.
@@ -723,6 +725,8 @@ Line chart serie.
* `show`: 是否启用。
* `color`: 颜色。
* `toColor`gradient color1.
* `toColor2`gradient color2.
* `backgroundColor`: 背景颜色。
* `backgroundWidth`: 背景的宽。
* `centerColor`: 中心区域的颜色。如环形图的中心区域。

View File

@@ -43,7 +43,7 @@ namespace XCharts
{
EditorGUILayout.PropertyField(m_DataZoom);
}
if (m_Target is HeatmapChart)
if (m_Target is HeatmapChart || m_Target is LineChart)
{
EditorGUILayout.PropertyField(m_VisualMap);
}

View File

@@ -25,6 +25,7 @@ namespace XCharts
SerializedProperty show = prop.FindPropertyRelative("m_Show");
SerializedProperty m_Color = prop.FindPropertyRelative("m_Color");
SerializedProperty m_ToColor = prop.FindPropertyRelative("m_ToColor");
SerializedProperty m_ToColor2 = prop.FindPropertyRelative("m_ToColor2");
SerializedProperty m_BackgroundColor = prop.FindPropertyRelative("m_BackgroundColor");
SerializedProperty m_BackgroundWidth = prop.FindPropertyRelative("m_BackgroundWidth");
SerializedProperty m_CenterColor = prop.FindPropertyRelative("m_CenterColor");
@@ -45,6 +46,8 @@ namespace XCharts
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_ToColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_ToColor2);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_BackgroundColor);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_BackgroundWidth);
@@ -80,7 +83,7 @@ namespace XCharts
float height = 0;
if (ChartEditorHelper.IsToggle(m_ItemStyleToggle, prop))
{
height += 14 * EditorGUIUtility.singleLineHeight + 13 * EditorGUIUtility.standardVerticalSpacing;
height += 15 * EditorGUIUtility.singleLineHeight + 14 * EditorGUIUtility.standardVerticalSpacing;
var m_CornerRadius = prop.FindPropertyRelative("m_CornerRadius");
if (ChartEditorHelper.IsToggle(m_CornerRadiusToggle, m_CornerRadius))
{

View File

@@ -42,7 +42,9 @@ namespace XCharts
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");
SerializedProperty m_AutoMinMax = prop.FindPropertyRelative("m_AutoMinMax");
SerializedProperty m_Direction = prop.FindPropertyRelative("m_Direction");
SerializedProperty m_OutOfRange = prop.FindPropertyRelative("m_OutOfRange");
ChartEditorHelper.MakeFoldout(ref drawRect, ref m_VisualMapModuleToggle, "Visual Map", m_Enable);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
@@ -51,7 +53,10 @@ namespace XCharts
++EditorGUI.indentLevel;
EditorGUI.PropertyField(drawRect, m_Type);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Direction);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_AutoMinMax);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Min);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Max);
@@ -60,8 +65,6 @@ namespace XCharts
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;
@@ -71,12 +74,12 @@ namespace XCharts
}
// 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);
// }
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);
@@ -88,6 +91,8 @@ namespace XCharts
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_HoverLink);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_Calculable);
drawRect.y += EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
EditorGUI.PropertyField(drawRect, m_ItemWidth);
@@ -111,7 +116,7 @@ namespace XCharts
int num = 1;
if (m_VisualMapModuleToggle)
{
num += 8;
num += 10;
height += num * EditorGUIUtility.singleLineHeight + (num - 1) * EditorGUIUtility.standardVerticalSpacing;
if (m_InRangeFoldout)
@@ -121,16 +126,16 @@ namespace XCharts
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 (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 += 10 * EditorGUIUtility.singleLineHeight + 9 * EditorGUIUtility.standardVerticalSpacing;
height += EditorGUI.GetPropertyHeight(prop.FindPropertyRelative("m_Location"));
}
}

View File

@@ -303,6 +303,7 @@ namespace XCharts
splitLine.ClearVerticesDirty();
splitArea.ClearVerticesDirty();
}
public int index { get; internal set; }
/// <summary>
/// the axis label text list.
/// 坐标轴刻度标签的Text列表。

View File

@@ -32,6 +32,25 @@ namespace XCharts
Piecewise
}
/// <summary>
/// 方向。X轴还是Y轴。
/// </summary>
public enum Direction
{
/// <summary>
/// 默认方向。
/// </summary>
Default,
/// <summary>
/// X轴方向。
/// </summary>
X,
/// <summary>
/// Y轴方向。
/// </summary>
Y
}
/// <summary>
/// 选择模式
/// </summary>
@@ -50,6 +69,7 @@ namespace XCharts
[SerializeField] private bool m_Enable = false;
[SerializeField] private bool m_Show = true;
[SerializeField] private Type m_Type = Type.Continuous;
[SerializeField] private Direction m_Direction = Direction.Default;
[SerializeField] private SelectedMode m_SelectedMode = SelectedMode.Multiple;
[SerializeField] private float m_Min = 0;
[SerializeField] private float m_Max = 100f;
@@ -63,8 +83,9 @@ namespace XCharts
[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 int m_Dimension = -1;
[SerializeField] private bool m_HoverLink = true;
[SerializeField] private bool m_AutoMinMax = true;
[SerializeField] private Orient m_Orient = Orient.Horizonal;
[SerializeField] private Location m_Location = Location.defaultLeft;
[SerializeField] private List<Color> m_InRange = new List<Color>();
@@ -92,7 +113,7 @@ namespace XCharts
public bool show
{
get { return m_Show; }
set { if (PropertyUtility.SetStruct(ref m_Enable, value)) SetVerticesDirty(); }
set { if (PropertyUtility.SetStruct(ref m_Show, value)) SetVerticesDirty(); }
}
/// <summary>
/// the type of visualmap component.
@@ -104,6 +125,14 @@ namespace XCharts
set { if (PropertyUtility.SetStruct(ref m_Type, value)) SetVerticesDirty(); }
}
/// <summary>
/// 映射方向。
/// </summary>
public Direction direction
{
get { return m_Direction; }
set { if (PropertyUtility.SetStruct(ref m_Direction, value)) SetVerticesDirty(); }
}
/// <summary>
/// the selected mode for Piecewise visualMap.
/// 选择模式。
/// </summary>
@@ -115,7 +144,7 @@ namespace XCharts
/// <summary>
/// The minimum allowed. 'min' must be user specified. [visualmap.min, visualmap.max] forms the "domain" of the visualMap.
///
/// 允许的最小值。'min' 必须用户指定。[visualMap.min, visualMap.max] 形成了视觉映射的『定义域』。
/// 允许的最小值。`autoMinMax`为`false`时必须指定。[visualMap.min, visualMap.max] 形成了视觉映射的『定义域』。
/// </summary>
public float min
{
@@ -125,12 +154,12 @@ namespace XCharts
/// <summary>
/// The maximum allowed. 'max' must be user specified. [visualmap.min, visualmap.max] forms the "domain" of the visualMap.
///
/// 允许的最大值。'max' 必须用户指定。[visualMap.min, visualMax.max] 形成了视觉映射的『定义域』。
/// 允许的最大值。`autoMinMax`为`false`时必须指定。[visualMap.min, visualMax.max] 形成了视觉映射的『定义域』。
/// </summary>
public float max
{
get { return m_Max; }
set { m_Max = value < min ? min + 1 : value; SetVerticesDirty(); }
set { m_Max = (value < min ? min + 1 : value); SetVerticesDirty(); }
}
/// <summary>
/// Specifies the position of the numeric value corresponding to the handle. Range should be within the range of [min,max].
@@ -237,6 +266,15 @@ namespace XCharts
set { if (PropertyUtility.SetStruct(ref m_HoverLink, value)) SetVerticesDirty(); }
}
/// <summary>
/// Automatically set min, Max value
/// 自动设置minmax的值
/// </summary>
public bool autoMinMax
{
get { return m_AutoMinMax; }
set { if (PropertyUtility.SetStruct(ref m_AutoMinMax, value)) SetVerticesDirty(); }
}
/// <summary>
/// Specify whether the layout of component is horizontal or vertical.
///
/// 布局方式是横还是竖。
@@ -330,7 +368,7 @@ namespace XCharts
get
{
if (splitNumber > 0 && splitNumber <= m_InRange.Count) return splitNumber;
else return inRange.Count;
else return m_InRange.Count;
}
}
@@ -342,7 +380,10 @@ namespace XCharts
{
get
{
if (splitNumber == 0 || m_InRange.Count >= splitNumber || m_InRange.Count < 1) return m_InRange;
if (splitNumber == 0 || m_InRange.Count >= splitNumber || m_InRange.Count < 1 || IsPiecewise())
{
return m_InRange;
}
else
{
if (m_RtInRange.Count != runtimeSplitNumber)
@@ -383,29 +424,41 @@ namespace XCharts
public Color GetColor(float value)
{
if (value < m_Min || value > m_Max)
{
if (m_OutOfRange.Count > 0) return m_OutOfRange[0];
else return Color.clear;
}
int splitNumber = runtimeInRange.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 runtimeInRange[index];
else return Color.Lerp(runtimeInRange[index], runtimeInRange[index + 1], rate);
if (m_Type == VisualMap.Type.Piecewise)
{
if (index >= 0 && index < runtimeInRange.Count)
return runtimeInRange[index];
else return Color.clear;
}
else
{
var diff = (m_Max - m_Min) / (splitNumber - 1);
var nowMin = m_Min + index * diff;
var rate = (value - nowMin) / diff;
if (index == splitNumber - 1) return runtimeInRange[index];
else return Color.Lerp(runtimeInRange[index], runtimeInRange[index + 1], rate);
}
}
public int GetIndex(float value)
{
int splitNumber = runtimeInRange.Count;
if (splitNumber <= 0) return -1;
value = Mathf.Clamp(value, min, max);
value = Mathf.Clamp(value, m_Min, m_Max);
var diff = (max - min) / (splitNumber - 1);
var diff = (m_Max - m_Min) / (splitNumber - (IsPiecewise() ? 0 : 1));
var index = -1;
for (int i = 0; i < splitNumber; i++)
{
if (value <= min + (i + 1) * diff)
if (value <= m_Min + (i + 1) * diff)
{
index = i;
break;
@@ -414,6 +467,11 @@ namespace XCharts
return index;
}
public bool IsPiecewise()
{
return m_Type == VisualMap.Type.Piecewise;
}
public bool IsInSelectedValue(float value)
{
if (runtimeSelectedIndex < 0) return true;

View File

@@ -38,6 +38,7 @@ namespace XCharts
[SerializeField] private bool m_Show = false;
[SerializeField] private Color m_Color;
[SerializeField] private Color m_ToColor;
[SerializeField] private Color m_ToColor2;
[SerializeField] private Color m_BackgroundColor;
[SerializeField] private float m_BackgroundWidth;
[SerializeField] private Color m_CenterColor;
@@ -55,6 +56,7 @@ namespace XCharts
m_Show = false;
m_Color = Color.clear;
m_ToColor = Color.clear;
m_ToColor2 = Color.clear;
m_BackgroundColor = Color.clear;
m_BackgroundWidth = 0;
m_CenterColor = Color.clear;
@@ -93,8 +95,8 @@ namespace XCharts
set { if (PropertyUtility.SetColor(ref m_Color, value)) SetVerticesDirty(); }
}
/// <summary>
/// Gradient color, start color to toColor.
/// 渐变色的终点颜色。
/// Gradient color1.
/// 渐变色的颜色1
/// </summary>
public Color toColor
{
@@ -102,6 +104,15 @@ namespace XCharts
set { if (PropertyUtility.SetColor(ref m_ToColor, value)) SetVerticesDirty(); }
}
/// <summary>
/// Gradient color2.Only valid in line diagrams.
/// 渐变色的颜色2。只在折线图中有效。
/// </summary>
public Color toColor2
{
get { return m_ToColor2; }
set { if (PropertyUtility.SetColor(ref m_ToColor2, value)) SetVerticesDirty(); }
}
/// <summary>
/// 数据项背景颜色。
/// </summary>
public Color backgroundColor
@@ -214,5 +225,26 @@ namespace XCharts
color.a *= m_Opacity;
return color;
}
public bool IsNeedGradient()
{
return !ChartHelper.IsClearColor(m_ToColor) || !ChartHelper.IsClearColor(m_ToColor2);
}
public Color GetGradientColor(float value, Color defaultColor)
{
if (!IsNeedGradient()) return Color.clear;
value = Mathf.Clamp01(value);
var startColor = m_Color == Color.clear ? defaultColor : m_Color;
if (m_ToColor2 != Color.clear)
{
if (value <= 0.5f) return Color.Lerp(startColor, m_ToColor, 2 * value);
else return Color.Lerp(m_ToColor, m_ToColor2, 2 * (value - 0.5f));
}
else
{
return Color.Lerp(startColor, m_ToColor, value);
}
}
}
}

View File

@@ -764,11 +764,6 @@ 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]);
@@ -781,7 +776,14 @@ namespace XCharts
private void UpdateAxisMinMaxValue(int axisIndex, Axis axis, bool updateChart = true)
{
if (axis.IsCategory() || !axis.show) return;
if (!axis.show) return;
if (axis.IsCategory())
{
m_CheckMinMaxValue = true;
axis.runtimeMinValue = 0;
axis.runtimeMaxValue = SeriesHelper.GetMaxSerieDataCount(m_Series);
return;
}
float tempMinValue = 0;
float tempMaxValue = 0;
@@ -864,10 +866,12 @@ namespace XCharts
DrawGrid(vh);
for (int i = 0; i < m_XAxises.Count; i++)
{
m_XAxises[i].index = i;
DrawXAxisSplit(vh, i, m_XAxises[i]);
}
for (int i = 0; i < m_YAxises.Count; i++)
{
m_YAxises[i].index = i;
DrawYAxisSplit(vh, i, m_YAxises[i]);
}
for (int i = 0; i < m_XAxises.Count; i++)
@@ -1494,8 +1498,7 @@ namespace XCharts
if (serie.type == SerieType.Heatmap)
{
dimension = m_VisualMap.enable && m_VisualMap.dimension > 0 ? m_VisualMap.dimension - 1 :
serieData.data.Count - 1;
dimension = VisualMapHelper.GetDimension(m_VisualMap, serieData.data.Count);
}
SerieLabelHelper.ResetLabel(serieData, serieLabel, themeInfo, i);

View File

@@ -145,8 +145,7 @@ namespace XCharts
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 dimension = VisualMapHelper.GetDimension(m_VisualMap, serieData.data.Count);
if (serie.IsIgnoreIndex(dataIndex, dimension))
{
serie.dataPoints.Add(Vector3.zero);

View File

@@ -220,6 +220,7 @@ namespace XCharts
{
lastNextPos = endPos;
}
VisualMapHelper.AutoSetLineMinMax(visualMap, serie, xAxis, yAxis);
for (i = startIndex + 1; i < serie.dataPoints.Count; i++)
{
np = serie.dataPoints[i];
@@ -641,10 +642,11 @@ namespace XCharts
private Vector3 stPos1, stPos2, lastDir, lastDnPos;
private bool lastIsDown;
private bool DrawNormalLine(VertexHelper vh, Serie serie, Axis axis, Vector3 lp,
Vector3 np, Vector3 nnp, int dataIndex, Color lineColor, Color areaColor, Color areaToColor,
private bool DrawNormalLine(VertexHelper vh, Serie serie, Axis axis, Vector3 lp, Vector3 np, Vector3 nnp,
int dataIndex, Color lineColor, Color areaColor, Color areaToColor,
Vector3 zeroPos, int startIndex = 0)
{
var defaultLineColor = lineColor;
var isSecond = dataIndex == startIndex + 1;
var isTheLastPos = np == nnp;
bool isYAxis = axis is YAxis;
@@ -715,6 +717,7 @@ namespace XCharts
if (serie.animation.CheckDetailBreak(cp, isYAxis)) isBreak = true;
var tp1 = cp - dir1v * serie.lineStyle.width;
var tp2 = cp + dir1v * serie.lineStyle.width;
CheckLineGradientColor(cp, serie.itemStyle, axis, defaultLineColor, ref lineColor);
if (isDown)
{
if (!isBreak)
@@ -849,7 +852,7 @@ namespace XCharts
if (lastSerie != null)
{
var lastSmoothPoints = lastSerie.GetUpSmoothList(dataIndex);
DrawStackArea(vh, serie, axis, smoothDownPoints, lastSmoothPoints, lineColor, areaColor, areaToColor);
DrawStackArea(vh, serie, axis, smoothDownPoints, lastSmoothPoints, areaColor, areaToColor);
}
else
{
@@ -985,6 +988,14 @@ namespace XCharts
return !isBreak;
}
private void CheckLineGradientColor(Vector3 cp, ItemStyle itemStyle, Axis axis, Color defaultLineColor, ref Color lineColor)
{
if (VisualMapHelper.IsNeedGradient(m_VisualMap))
lineColor = VisualMapHelper.GetLineGradientColor(m_VisualMap, cp, this, axis, defaultLineColor);
else if (itemStyle.IsNeedGradient())
lineColor = VisualMapHelper.GetItemStyleGradientColor(itemStyle, cp, this, axis, defaultLineColor);
}
private bool IsInRightOrUp(bool isYAxis, bool isLastDown, Vector3 dnPos, Vector3 checkPos)
{
if ((isLastDown && ((isYAxis && checkPos.y <= dnPos.y) || (!isYAxis && checkPos.x <= dnPos.x))) ||
@@ -1082,6 +1093,7 @@ namespace XCharts
Vector3 np, Vector3 llp, Vector3 nnp, int dataIndex, Color lineColor, Color areaColor,
Color areaToColor, bool isStack, Vector3 zeroPos, int startIndex = 0)
{
var defaultLineColor = lineColor;
bool isYAxis = xAxis is YAxis;
var lineWidth = serie.lineStyle.width;
var smoothPoints = serie.GetUpSmoothList(dataIndex);
@@ -1096,6 +1108,7 @@ namespace XCharts
{
start = bezierPoints[i];
to = bezierPoints[i + 1];
CheckLineGradientColor(start, serie.itemStyle, xAxis, defaultLineColor, ref lineColor);
CheckClipAndDrawLine(vh, start, to, lineWidth, lineColor, serie.clip);
}
return true;
@@ -1118,6 +1131,7 @@ namespace XCharts
{
if (!serie.animation.IsInFadeOut())
{
CheckLineGradientColor(lp, serie.itemStyle, xAxis, defaultLineColor, ref lineColor);
CheckClipAndDrawTriangle(vh, smoothStartPosUp, startUp, lp, lineColor, serie.clip);
CheckClipAndDrawTriangle(vh, smoothStartPosDn, startDn, lp, lineColor, serie.clip);
}
@@ -1146,6 +1160,7 @@ namespace XCharts
diff = dir1v * lineWidth;
toUp = to - diff;
toDn = to + diff;
CheckLineGradientColor(to, serie.itemStyle, xAxis, defaultLineColor, ref lineColor);
if (isYAxis) CheckClipAndDrawPolygon(vh, startDn, toDn, toUp, startUp, lineColor, serie.clip);
else CheckClipAndDrawPolygon(vh, startUp, toUp, toDn, startDn, lineColor, serie.clip);
smoothPoints.Add(toUp);
@@ -1209,7 +1224,7 @@ namespace XCharts
if (lastSerie != null)
{
var lastSmoothPoints = lastSerie.GetUpSmoothList(dataIndex);
DrawStackArea(vh, serie, xAxis, smoothDownPoints, lastSmoothPoints, lineColor, areaColor, areaToColor);
DrawStackArea(vh, serie, xAxis, smoothDownPoints, lastSmoothPoints, areaColor, areaToColor);
}
}
return isFinish;
@@ -1241,7 +1256,7 @@ namespace XCharts
}
private void DrawStackArea(VertexHelper vh, Serie serie, Axis axis, List<Vector3> smoothPoints,
List<Vector3> lastSmoothPoints, Color lineColor, Color areaColor, Color areaToColor)
List<Vector3> lastSmoothPoints, Color areaColor, Color areaToColor)
{
if (!serie.areaStyle.show || lastSmoothPoints.Count <= 0) return;
Vector3 start, to;

View File

@@ -470,5 +470,15 @@ namespace XCharts
maxValue = max > 1 ? Mathf.CeilToInt(max) : max;
}
}
public static int GetMaxSerieDataCount(Series series)
{
int max = 0;
foreach (var serie in series.list)
{
if (serie.dataCount > max) max = serie.dataCount;
}
return max;
}
}
}

View File

@@ -0,0 +1,130 @@
/******************************************/
/* */
/* Copyright (c) 2018 monitor1394 */
/* https://github.com/monitor1394 */
/* */
/******************************************/
using System;
using System.Collections.Generic;
using UnityEngine;
namespace XCharts
{
public static class VisualMapHelper
{
public static void AutoSetLineMinMax(VisualMap visualMap, Serie serie, XAxis xAxis, YAxis yAxis)
{
if (!IsNeedGradient(visualMap) || !visualMap.autoMinMax) return;
float min = 0;
float max = 0;
switch (visualMap.direction)
{
case VisualMap.Direction.Default:
case VisualMap.Direction.X:
min = xAxis.IsCategory() ? 0 : xAxis.runtimeMinValue;
max = xAxis.IsCategory() ? serie.dataCount : xAxis.runtimeMaxValue;
SetMinMax(visualMap, min, max);
break;
case VisualMap.Direction.Y:
min = yAxis.IsCategory() ? 0 : yAxis.runtimeMinValue;
max = yAxis.IsCategory() ? serie.dataCount : yAxis.runtimeMaxValue;
SetMinMax(visualMap, min, max);
break;
}
}
public static void SetMinMax(VisualMap visualMap, float min, float max)
{
if (visualMap.enable && (visualMap.min != min || visualMap.max != max))
{
//Debug.LogError("minmax:"+min+","+max);
if (max >= min)
{
visualMap.min = min;
visualMap.max = max;
//Debug.LogError("minmax2222:"+visualMap.min+","+visualMap.max);
}
else
{
throw new Exception("SetMinMax:max < min:" + min + "," + max);
}
}
}
public static void GetLineGradientColor(VisualMap visualMap, float xValue, float yValue,
out Color startColor, out Color toColor)
{
startColor = Color.clear;
toColor = Color.clear;
switch (visualMap.direction)
{
case VisualMap.Direction.Default:
case VisualMap.Direction.X:
startColor = visualMap.IsPiecewise() ? visualMap.GetColor(xValue) : visualMap.GetColor(xValue - 1);
toColor = visualMap.IsPiecewise() ? startColor : visualMap.GetColor(xValue);
break;
case VisualMap.Direction.Y:
startColor = visualMap.IsPiecewise() ? visualMap.GetColor(yValue) : visualMap.GetColor(yValue - 1);
toColor = visualMap.IsPiecewise() ? startColor : visualMap.GetColor(yValue);
break;
}
}
internal static Color GetLineGradientColor(VisualMap visualMap, Vector3 pos, CoordinateChart chart, Axis axis, Color defaultColor)
{
float value = 0;
switch (visualMap.direction)
{
case VisualMap.Direction.Default:
case VisualMap.Direction.X:
var min = axis.runtimeMinValue;
var max = axis.runtimeMaxValue;
value = min + (pos.x - chart.coordinateX) / chart.coordinateWidth * (max - min);
break;
case VisualMap.Direction.Y:
if (axis is YAxis)
{
var yAxis = chart.xAxises[axis.index];
min = yAxis.runtimeMinValue;
max = yAxis.runtimeMaxValue;
}
else
{
var yAxis = chart.yAxises[axis.index];
min = yAxis.runtimeMinValue;
max = yAxis.runtimeMaxValue;
}
value = min + (pos.y - chart.coordinateY) / chart.coordinateHeight * (max - min);
break;
}
var color = visualMap.GetColor(value);
if (ChartHelper.IsClearColor(color)) return defaultColor;
else return color;
}
internal static Color GetItemStyleGradientColor(ItemStyle itemStyle, Vector3 pos, CoordinateChart chart, Axis axis, Color defaultColor)
{
var min = axis.runtimeMinValue;
var max = axis.runtimeMaxValue;
var value = min + (pos.x - chart.coordinateX) / chart.coordinateWidth * (max - min);
var rate = (value - min) / (max - min);
var color = itemStyle.GetGradientColor(rate, defaultColor);
if (ChartHelper.IsClearColor(color)) return defaultColor;
else return color;
}
public static bool IsNeedGradient(VisualMap visualMap)
{
if (!visualMap.enable || visualMap.inRange.Count <= 0) return false;
return true;
}
public static int GetDimension(VisualMap visualMap, int serieDataCount)
{
var dimension = visualMap.enable && visualMap.dimension >= 0 ? visualMap.dimension : serieDataCount - 1;
if (dimension > serieDataCount - 1) dimension = serieDataCount - 1;
return dimension;
}
}
}

View File

@@ -23,6 +23,15 @@ namespace XCharts
base.Reset();
m_Title.text = "LineChart";
m_Tooltip.type = Tooltip.Type.Line;
m_VisualMap.enable = false;
m_VisualMap.show = false;
m_VisualMap.autoMinMax = true;
m_VisualMap.direction = VisualMap.Direction.Y;
m_VisualMap.inRange.Clear();
m_VisualMap.inRange.Add(Color.blue);
m_VisualMap.inRange.Add(Color.red);
RemoveData();
var serie = AddSerie(SerieType.Line, "serie1");
serie.symbol.show = true;