[feature][heatmap] support heatmapType

This commit is contained in:
monitor1394
2022-09-06 07:22:04 +08:00
parent ce702fd1e3
commit ccc5110e8e
10 changed files with 282 additions and 50 deletions

View File

@@ -58,6 +58,7 @@
## master
* (2022.09.05) 增加`Heatmap``heatmapType`支持设置`Data``Count`两种不同映射方式的热力图
* (2022.09.05) 优化`Tooltip`在热力图为数值轴时的指示
* (2022.09.02) 增加`onPointerEnterPie`回调支持
* (2022.09.02) 优化`HeatmapChart`

View File

@@ -130,12 +130,14 @@ Inherits or Implemented: [MainComponentHandler](#MainComponentHandler)
| `GetAxisValueDistance()` |public static float GetAxisValueDistance(GridCoord grid, Axis axis, float scaleWidth, double value)</br>获得数值value在坐标轴上相对起点的距离 |
| `GetAxisValueLength()` |public static float GetAxisValueLength(GridCoord grid, Axis axis, float scaleWidth, double value)</br>获得数值value在坐标轴上对应的长度 |
| `GetAxisValuePosition()` |public static float GetAxisValuePosition(GridCoord grid, Axis axis, float scaleWidth, double value)</br>获得数值value在坐标轴上的坐标位置 |
| `GetAxisValueSplitIndex()` |public static int GetAxisValueSplitIndex(Axis axis, double value, int totalSplitNumber = -1)</br>获得数值value在坐标轴上对应的split索引 |
| `GetAxisXOrY()` |public static float GetAxisXOrY(GridCoord grid, Axis axis, Axis relativedAxis)</br> |
| `GetDataWidth()` |public static float GetDataWidth(Axis axis, float coordinateWidth, int dataCount, DataZoom dataZoom)</br>获得一个类目数据在坐标系中代表的宽度 |
| `GetEachWidth()` |public static float GetEachWidth(Axis axis, float coordinateWidth, DataZoom dataZoom = null)</br> |
| `GetScaleNumber()` |public static int GetScaleNumber(Axis axis, float coordinateWidth, DataZoom dataZoom = null)</br>获得分割线条数 |
| `GetScaleWidth()` |public static float GetScaleWidth(Axis axis, float coordinateWidth, int index, DataZoom dataZoom = null)</br>获得分割段宽度 |
| `GetSplitNumber()` |public static int GetSplitNumber(Axis axis, float coordinateWid, DataZoom dataZoom)</br>获得分割段数 |
| `GetTotalSplitGridNum()` |public static int GetTotalSplitGridNum(Axis axis)</br>获得分割网格个数,包含次刻度 |
| `GetXAxisXOrY()` |public static float GetXAxisXOrY(GridCoord grid, Axis xAxis, Axis relativedAxis)</br> |
| `GetYAxisXOrY()` |public static float GetYAxisXOrY(GridCoord grid, Axis yAxis, Axis relativedAxis)</br> |
| `NeedShowSplit()` |public static bool NeedShowSplit(Axis axis)</br> |
@@ -153,12 +155,12 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver
| `AddChartComponent()` |public MainComponent AddChartComponent(Type type)</br> |
| `AddData()` |public SerieData AddData(int serieIndex, DateTime time, double yValue, string dataName = null, string dataId = null)</br>Add a (time,y) data to serie. |
| `AddData()` |public SerieData AddData(int serieIndex, double data, string dataName = null, string dataId = null)</br>Add a data to serie. |
| `AddData()` |public SerieData AddData(int serieIndex, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)</br> |
| `AddData()` |public SerieData AddData(int serieIndex, double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)</br> |
| `AddData()` |public SerieData AddData(int serieIndex, double xValue, double yValue, string dataName = null, string dataId = null)</br>Add a (x,y) data to serie. |
| `AddData()` |public SerieData AddData(int serieIndex, List<double> multidimensionalData, string dataName = null, string dataId = null)</br>Add an arbitray dimension data to serie,such as (x,y,z,...). |
| `AddData()` |public SerieData AddData(string serieName, DateTime time, double yValue, string dataName = null, string dataId = null)</br>Add a (time,y) data to serie. |
| `AddData()` |public SerieData AddData(string serieName, double data, string dataName = null, string dataId = null)</br>Add a data to serie. |
| `AddData()` |public SerieData AddData(string serieName, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)</br> |
| `AddData()` |public SerieData AddData(string serieName, double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)</br> |
| `AddData()` |public SerieData AddData(string serieName, double xValue, double yValue, string dataName = null, string dataId = null)</br>Add a (x,y) data to serie. |
| `AddData()` |public SerieData AddData(string serieName, List<double> multidimensionalData, string dataName = null, string dataId = null)</br>Add an arbitray dimension data to serie,such as (x,y,z,...). |
| `AddXAxisData()` |public void AddXAxisData(string category, int xAxisIndex = 0)</br>Add a category data to xAxis. |
@@ -201,13 +203,13 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver
| `GetSeriesMinMaxValue()` |public virtual void GetSeriesMinMaxValue(Axis axis, int axisIndex, out double tempMinValue, out double tempMaxValue)</br> |
| `GetTitlePosition()` |public Vector3 GetTitlePosition(Title title)</br> |
| `GetVisualMapOfSerie()` |public VisualMap GetVisualMapOfSerie(Serie serie)</br> |
| `GetXDataZoomOfSerie()` |public DataZoom GetXDataZoomOfSerie(Serie serie)</br> |
| `GetXLerpColor()` |public Color32 GetXLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid)</br> |
| `GetYLerpColor()` |public Color32 GetYLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid)</br> |
| `HasChartComponent()` |public bool HasChartComponent(Type type)</br> |
| `HasChartComponent<T>()` |public bool HasChartComponent<T>()</br> |
| `HasSerie()` |public bool HasSerie(Type type)</br> |
| `Init()` |public void Init(bool defaultChart = true)</br> |
| `InitAxisRuntimeData()` |public virtual void InitAxisRuntimeData(Axis axis)</br> |
| `InsertSerie()` |public void InsertSerie(Serie serie, int index = -1, bool addToHead = false)</br> |
| `Internal_CheckAnimation()` |public void Internal_CheckAnimation()</br> |
| `IsActiveByLegend()` |public virtual bool IsActiveByLegend(string legendName)</br>Whether serie is activated. |
@@ -1038,7 +1040,7 @@ Inherits or Implemented: [MainComponentContext](#MainComponentContext)
|public method|description|
|--|--|
| `AutoSetLineMinMax()` |public static void AutoSetLineMinMax(VisualMap visualMap, Serie serie, bool isY, Axis axis, Axis relativedAxis)</br> |
| `GetDimension()` |public static int GetDimension(VisualMap visualMap, int serieDataCount)</br> |
| `GetDimension()` |public static int GetDimension(VisualMap visualMap, int defaultDimension)</br> |
| `IsNeedAreaGradient()` |public static bool IsNeedAreaGradient(VisualMap visualMap)</br> |
| `IsNeedGradient()` |public static bool IsNeedGradient(VisualMap visualMap)</br> |
| `IsNeedLineGradient()` |public static bool IsNeedLineGradient(VisualMap visualMap)</br> |

View File

@@ -130,12 +130,14 @@ Inherits or Implemented: [MainComponentHandler](#MainComponentHandler)
| `GetAxisValueDistance()` |public static float GetAxisValueDistance(GridCoord grid, Axis axis, float scaleWidth, double value)</br>获得数值value在坐标轴上相对起点的距离 |
| `GetAxisValueLength()` |public static float GetAxisValueLength(GridCoord grid, Axis axis, float scaleWidth, double value)</br>获得数值value在坐标轴上对应的长度 |
| `GetAxisValuePosition()` |public static float GetAxisValuePosition(GridCoord grid, Axis axis, float scaleWidth, double value)</br>获得数值value在坐标轴上的坐标位置 |
| `GetAxisValueSplitIndex()` |public static int GetAxisValueSplitIndex(Axis axis, double value, int totalSplitNumber = -1)</br>获得数值value在坐标轴上对应的split索引 |
| `GetAxisXOrY()` |public static float GetAxisXOrY(GridCoord grid, Axis axis, Axis relativedAxis)</br> |
| `GetDataWidth()` |public static float GetDataWidth(Axis axis, float coordinateWidth, int dataCount, DataZoom dataZoom)</br>获得一个类目数据在坐标系中代表的宽度 |
| `GetEachWidth()` |public static float GetEachWidth(Axis axis, float coordinateWidth, DataZoom dataZoom = null)</br> |
| `GetScaleNumber()` |public static int GetScaleNumber(Axis axis, float coordinateWidth, DataZoom dataZoom = null)</br>获得分割线条数 |
| `GetScaleWidth()` |public static float GetScaleWidth(Axis axis, float coordinateWidth, int index, DataZoom dataZoom = null)</br>获得分割段宽度 |
| `GetSplitNumber()` |public static int GetSplitNumber(Axis axis, float coordinateWid, DataZoom dataZoom)</br>获得分割段数 |
| `GetTotalSplitGridNum()` |public static int GetTotalSplitGridNum(Axis axis)</br>获得分割网格个数,包含次刻度 |
| `GetXAxisXOrY()` |public static float GetXAxisXOrY(GridCoord grid, Axis xAxis, Axis relativedAxis)</br> |
| `GetYAxisXOrY()` |public static float GetYAxisXOrY(GridCoord grid, Axis yAxis, Axis relativedAxis)</br> |
| `NeedShowSplit()` |public static bool NeedShowSplit(Axis axis)</br> |
@@ -153,12 +155,12 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver
| `AddChartComponent()` |public MainComponent AddChartComponent(Type type)</br> |
| `AddData()` |public SerieData AddData(int serieIndex, DateTime time, double yValue, string dataName = null, string dataId = null)</br>添加time,y数据到指定的系列中。 |
| `AddData()` |public SerieData AddData(int serieIndex, double data, string dataName = null, string dataId = null)</br>添加一个数据到指定的系列中。 |
| `AddData()` |public SerieData AddData(int serieIndex, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)</br> |
| `AddData()` |public SerieData AddData(int serieIndex, double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)</br> |
| `AddData()` |public SerieData AddData(int serieIndex, double xValue, double yValue, string dataName = null, string dataId = null)</br>添加x,y数据到指定系列中。 |
| `AddData()` |public SerieData AddData(int serieIndex, List<double> multidimensionalData, string dataName = null, string dataId = null)</br>添加多维数据x,y,z...)到指定的系列中。 |
| `AddData()` |public SerieData AddData(string serieName, DateTime time, double yValue, string dataName = null, string dataId = null)</br>添加time,y数据到指定的系列中。 |
| `AddData()` |public SerieData AddData(string serieName, double data, string dataName = null, string dataId = null)</br>If serieName doesn't exist in legend,will be add to legend. |
| `AddData()` |public SerieData AddData(string serieName, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)</br> |
| `AddData()` |public SerieData AddData(string serieName, double indexOrTimestamp, double open, double close, double lowest, double heighest, string dataName = null, string dataId = null)</br> |
| `AddData()` |public SerieData AddData(string serieName, double xValue, double yValue, string dataName = null, string dataId = null)</br>添加x,y数据到指定系列中。 |
| `AddData()` |public SerieData AddData(string serieName, List<double> multidimensionalData, string dataName = null, string dataId = null)</br>添加多维数据x,y,z...)到指定的系列中。 |
| `AddXAxisData()` |public void AddXAxisData(string category, int xAxisIndex = 0)</br>添加一个类目数据到指定的x轴。 |
@@ -201,13 +203,13 @@ Inherits or Implemented: [BaseGraph](#BaseGraph),[ISerializationCallbackReceiver
| `GetSeriesMinMaxValue()` |public virtual void GetSeriesMinMaxValue(Axis axis, int axisIndex, out double tempMinValue, out double tempMaxValue)</br> |
| `GetTitlePosition()` |public Vector3 GetTitlePosition(Title title)</br> |
| `GetVisualMapOfSerie()` |public VisualMap GetVisualMapOfSerie(Serie serie)</br> |
| `GetXDataZoomOfSerie()` |public DataZoom GetXDataZoomOfSerie(Serie serie)</br> |
| `GetXLerpColor()` |public Color32 GetXLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid)</br> |
| `GetYLerpColor()` |public Color32 GetYLerpColor(Color32 areaColor, Color32 areaToColor, Vector3 pos, GridCoord grid)</br> |
| `HasChartComponent()` |public bool HasChartComponent(Type type)</br> |
| `HasChartComponent<T>()` |public bool HasChartComponent<T>()</br> |
| `HasSerie()` |public bool HasSerie(Type type)</br> |
| `Init()` |public void Init(bool defaultChart = true)</br> |
| `InitAxisRuntimeData()` |public virtual void InitAxisRuntimeData(Axis axis)</br> |
| `InsertSerie()` |public void InsertSerie(Serie serie, int index = -1, bool addToHead = false)</br> |
| `Internal_CheckAnimation()` |public void Internal_CheckAnimation()</br> |
| `IsActiveByLegend()` |public virtual bool IsActiveByLegend(string legendName)</br>获得指定图例名字的系列是否显示。 |
@@ -1038,7 +1040,7 @@ Inherits or Implemented: [MainComponentContext](#MainComponentContext)
|public method|description|
|--|--|
| `AutoSetLineMinMax()` |public static void AutoSetLineMinMax(VisualMap visualMap, Serie serie, bool isY, Axis axis, Axis relativedAxis)</br> |
| `GetDimension()` |public static int GetDimension(VisualMap visualMap, int serieDataCount)</br> |
| `GetDimension()` |public static int GetDimension(VisualMap visualMap, int defaultDimension)</br> |
| `IsNeedAreaGradient()` |public static bool IsNeedAreaGradient(VisualMap visualMap)</br> |
| `IsNeedGradient()` |public static bool IsNeedGradient(VisualMap visualMap)</br> |
| `IsNeedLineGradient()` |public static bool IsNeedLineGradient(VisualMap visualMap)</br> |

View File

@@ -628,6 +628,9 @@ Grid component.
Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer)
|field|default|since|comment|
|--|--|--|--|
|`heatmapType`||3.3.0|The mapping type of heatmap.</br>`HeatmapType`:</br>- `Data`: Data mapping type.By default, the second dimension data is used as the color map.</br>- `Count`: Number mapping type.The number of occurrences of a statistic in a divided grid, as a color map.</br>|
## `IconStyle`
@@ -781,7 +784,7 @@ Legend component.The legend component shows different sets of tags, colors, and
|field|default|since|comment|
|--|--|--|--|
|`show`|true||Whether to show legend component.
|`iconType`|||Type of legend.</br>`Legend.Type`:</br>- `Auto`: 自动匹配。</br>- `Custom`: 自定义图标。</br>- `EmptyCircle`: 空心圆。</br>- `Circle`: 圆形。</br>- `Rect`: 正方形。可通过Setting的legendIconCornerRadius参数调整圆角。</br>- `Triangle`: 三角形。</br>- `Diamond`: 菱形。</br>|
|`iconType`|||Type of legend.</br>`Legend.Type`:</br>- `Auto`: 自动匹配。</br>- `Custom`: 自定义图标。</br>- `EmptyCircle`: 空心圆。</br>- `Circle`: 圆形。</br>- `Rect`: 正方形。可通过Setting的legendIconCornerRadius参数调整圆角。</br>- `Triangle`: 三角形。</br>- `Diamond`: 菱形。</br>- `Candlestick`: 烛台可用于K线图。</br>|
|`selectedMode`|||Selected mode of legend, which controls whether series can be toggled displaying by clicking legends.</br>`Legend.SelectedMode`:</br>- `Multiple`: 多选。</br>- `Single`: 单选。</br>- `None`: 无法选择。</br>|
|`orient`|||Specify whether the layout of legend component is horizontal or vertical.</br>`Orient`:</br>- `Horizonal`: 水平</br>- `Vertical`: 垂直</br>|
|`location`|||The location of legend. [Location](#Location)|
@@ -1479,7 +1482,7 @@ VisualMap component. Mapping data to visual elements such as colors.
|`selectedMode`|||the selected mode for Piecewise visualMap.</br>`VisualMap.SelectedMode`:</br>- `Multiple`: 多选。</br>- `Single`: 单选。</br>|
|`serieIndex`|0||the serie index of visualMap.
|`min`|0||范围最小值
|`max`|100||范围最大值
|`max`|0||范围最大值
|`range`|||Specifies the position of the numeric value corresponding to the handle. Range should be within the range of [min,max].
|`text`|||Text on both ends.
|`textGap`|||The distance between the two text bodies.

View File

@@ -628,6 +628,9 @@ Drawing grid in rectangular coordinate. Line chart, bar chart, and scatter chart
Inherits or Implemented: [Serie](#Serie),[INeedSerieContainer](#INeedSerieContainer)
|field|default|since|comment|
|--|--|--|--|
|`heatmapType`||3.3.0|热力图类型。通过颜色映射划分。</br>`HeatmapType`:</br>- `Data`: 数据映射型。默认用第2维数据作为颜色映射。要求数据至少有3个维度数据。</br>- `Count`: 个数映射型。统计数据在划分的格子中出现的次数作为颜色映射。要求数据至少有2个维度数据。</br>|
## `IconStyle`
@@ -781,7 +784,7 @@ Inherits or Implemented: [MainComponent](#MainComponent),[IPropertyChanged](#IPr
|field|default|since|comment|
|--|--|--|--|
|`show`|true||是否显示图例组件。
|`iconType`|||图例类型。</br>`Legend.Type`:</br>- `Auto`: 自动匹配。</br>- `Custom`: 自定义图标。</br>- `EmptyCircle`: 空心圆。</br>- `Circle`: 圆形。</br>- `Rect`: 正方形。可通过Setting的legendIconCornerRadius参数调整圆角。</br>- `Triangle`: 三角形。</br>- `Diamond`: 菱形。</br>|
|`iconType`|||图例类型。</br>`Legend.Type`:</br>- `Auto`: 自动匹配。</br>- `Custom`: 自定义图标。</br>- `EmptyCircle`: 空心圆。</br>- `Circle`: 圆形。</br>- `Rect`: 正方形。可通过Setting的legendIconCornerRadius参数调整圆角。</br>- `Triangle`: 三角形。</br>- `Diamond`: 菱形。</br>- `Candlestick`: 烛台可用于K线图。</br>|
|`selectedMode`|||选择模式。控制是否可以通过点击图例改变系列的显示状态。默认开启图例选择,可以设成 None 关闭。</br>`Legend.SelectedMode`:</br>- `Multiple`: 多选。</br>- `Single`: 单选。</br>- `None`: 无法选择。</br>|
|`orient`|||布局方式是横还是竖。</br>`Orient`:</br>- `Horizonal`: 水平</br>- `Vertical`: 垂直</br>|
|`location`|||图例显示的位置。 [Location](#Location)|
@@ -1479,7 +1482,7 @@ Inherits or Implemented: [MainComponent](#MainComponent)
|`selectedMode`|||选择模式。</br>`VisualMap.SelectedMode`:</br>- `Multiple`: 多选。</br>- `Single`: 单选。</br>|
|`serieIndex`|0||影响的serie索引。
|`min`|0||范围最小值
|`max`|100||范围最大值
|`max`|0||范围最大值
|`range`|||指定手柄对应数值的位置。range 应在[min,max]范围内。
|`text`|||两端的文本,如 ['High', 'Low']。
|`textGap`|||两端文字主体之间的距离单位为px。

View File

@@ -7,6 +7,7 @@ namespace XCharts.Editor
{
public override void OnCustomInspectorGUI()
{
PropertyField("m_HeatmapType");
PropertyField("m_Ignore");
PropertyField("m_IgnoreValue");

View File

@@ -31,9 +31,7 @@ namespace XCharts.Runtime
else
{
var splitNum = axis.splitNumber <= 0 ? GetSplitNumber(axis, 0, null) : axis.splitNumber;
return axis.minorTick.show ?
splitNum * axis.minorTick.splitNumber :
splitNum;
return splitNum * axis.minorTick.splitNumber;
}
}

View File

@@ -286,11 +286,19 @@ namespace XCharts.Runtime
var xAxisIndex = AxisHelper.GetAxisValueSplitIndex(xAxis, xAxis.context.pointerValue);
var yAxisIndex = AxisHelper.GetAxisValueSplitIndex(yAxis, yAxis.context.pointerValue);
serie.context.pointerItemDataIndex = -1;
if (serie is Heatmap)
{
var heatmap = serie as Heatmap;
if (heatmap.heatmapType == HeatmapType.Count)
{
serie.context.pointerItemDataIndex = HeatmapHandler.GetGridKey(xAxisIndex, yAxisIndex);
return;
}
}
foreach (var serieData in serie.data)
{
var x = AxisHelper.GetAxisValueSplitIndex(xAxis,serieData.GetData(0));
var y = AxisHelper.GetAxisValueSplitIndex(yAxis,serieData.GetData(1));
var x = AxisHelper.GetAxisValueSplitIndex(xAxis, serieData.GetData(0));
var y = AxisHelper.GetAxisValueSplitIndex(yAxis, serieData.GetData(1));
if (xAxisIndex == x && y == yAxisIndex)
{
serie.context.pointerItemDataIndex = serieData.index;

View File

@@ -2,6 +2,24 @@ using UnityEngine;
namespace XCharts.Runtime
{
/// <summary>
/// The mapping type of heatmap.
/// |热力图类型。通过颜色映射划分。
/// </summary>
public enum HeatmapType
{
/// <summary>
/// Data mapping type.By default, the second dimension data is used as the color map.
/// |数据映射型。默认用第2维数据作为颜色映射。要求数据至少有3个维度数据。
/// </summary>
Data,
/// <summary>
/// Number mapping type.The number of occurrences of a statistic in a divided grid, as a color map.
/// |个数映射型。统计数据在划分的格子中出现的次数作为颜色映射。要求数据至少有2个维度数据。
/// </summary>
Count
}
[System.Serializable]
[SerieHandler(typeof(HeatmapHandler), true)]
[DefaultAnimation(AnimationType.LeftToRight)]
@@ -11,8 +29,20 @@ namespace XCharts.Runtime
[SerieDataExtraField()]
public class Heatmap : Serie, INeedSerieContainer
{
[SerializeField][Since("3.3.0")] private HeatmapType m_HeatmapType = HeatmapType.Data;
/// <summary>
/// The mapping type of heatmap.
/// |热力图类型。通过颜色映射划分。
/// </summary>
public HeatmapType heatmapType
{
get { return m_HeatmapType; }
set { if (PropertyUtil.SetStruct(ref m_HeatmapType, value)) { SetVerticesDirty(); } }
}
public int containerIndex { get; internal set; }
public int containterInstanceId { get; internal set; }
public static Serie AddDefaultSerie(BaseChart chart, string serieName)
{
var serie = chart.AddSerie<Heatmap>(serieName);

View File

@@ -9,9 +9,21 @@ namespace XCharts.Runtime
internal sealed class HeatmapHandler : SerieHandler<Heatmap>
{
private GridCoord m_SerieGrid;
private Dictionary<int, int> m_CountDict = new Dictionary<int, int>();
public override int defaultDimension { get { return 2; } }
public static int GetGridKey(int x, int y)
{
return x * 100000 + y;
}
public static void GetGridXYByKey(int key, out int x, out int y)
{
x = key / 100000;
y = key % 100000;
}
public override void Update()
{
base.Update();
@@ -20,7 +32,10 @@ namespace XCharts.Runtime
public override void DrawSerie(VertexHelper vh)
{
DrawHeatmapSerie(vh, serie);
if (serie.heatmapType == HeatmapType.Count)
DrawCountHeatmapSerie(vh, serie);
else
DrawDataHeatmapSerie(vh, serie);
}
public override void UpdateTooltipSerieParams(int dataIndex, bool showCategory, string category,
@@ -28,40 +43,70 @@ namespace XCharts.Runtime
ref List<SerieParams> paramList, ref string title)
{
dataIndex = serie.context.pointerItemDataIndex;
if (dataIndex < 0)
return;
var serieData = serie.GetSerieData(dataIndex);
if (serieData == null)
return;
var visualMap = chart.GetVisualMapOfSerie(serie);
var dimension = VisualMapHelper.GetDimension(visualMap, defaultDimension);
if (string.IsNullOrEmpty(category))
if (serie.heatmapType == HeatmapType.Count)
{
var xAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex);
if (xAxis != null)
category = xAxis.GetData((int) serieData.GetData(0));
int value;
if (!m_CountDict.TryGetValue(dataIndex, out value)) return;
var visualMap = chart.GetVisualMapOfSerie(serie);
var dimension = VisualMapHelper.GetDimension(visualMap, defaultDimension);
title = serie.serieName;
var param = serie.context.param;
param.serieName = serie.serieName;
param.serieIndex = serie.index;
param.dimension = dimension;
param.dataCount = serie.dataCount;
param.serieData = null;
param.color = visualMap.GetColor(value);
param.marker = SerieHelper.GetItemMarker(serie, null, marker);
param.itemFormatter = SerieHelper.GetItemFormatter(serie, null, itemFormatter);
param.numericFormatter = SerieHelper.GetNumericFormatter(serie, null, numericFormatter);
param.columns.Clear();
param.columns.Add(param.marker);
param.columns.Add("count");
param.columns.Add(ChartCached.NumberToStr(value, param.numericFormatter));
paramList.Add(param);
}
title = serie.serieName;
else
{
if (dataIndex < 0)
return;
var param = serie.context.param;
param.serieName = serie.serieName;
param.serieIndex = serie.index;
param.dimension = dimension;
param.dataCount = serie.dataCount;
param.serieData = serieData;
param.color = serieData.context.color;
param.marker = SerieHelper.GetItemMarker(serie, serieData, marker);
param.itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter);
param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter);
param.columns.Clear();
var serieData = serie.GetSerieData(dataIndex);
if (serieData == null)
return;
var visualMap = chart.GetVisualMapOfSerie(serie);
var dimension = VisualMapHelper.GetDimension(visualMap, defaultDimension);
param.columns.Add(param.marker);
param.columns.Add(category);
param.columns.Add(ChartCached.NumberToStr(serieData.GetData(dimension), param.numericFormatter));
if (string.IsNullOrEmpty(category))
{
var xAxis = chart.GetChartComponent<XAxis>(serie.xAxisIndex);
if (xAxis != null)
category = xAxis.GetData((int) serieData.GetData(0));
}
title = serie.serieName;
paramList.Add(param);
var param = serie.context.param;
param.serieName = serie.serieName;
param.serieIndex = serie.index;
param.dimension = dimension;
param.dataCount = serie.dataCount;
param.serieData = serieData;
param.color = serieData.context.color;
param.marker = SerieHelper.GetItemMarker(serie, serieData, marker);
param.itemFormatter = SerieHelper.GetItemFormatter(serie, serieData, itemFormatter);
param.numericFormatter = SerieHelper.GetNumericFormatter(serie, serieData, numericFormatter);
param.columns.Clear();
param.columns.Add(param.marker);
param.columns.Add(category);
param.columns.Add(ChartCached.NumberToStr(serieData.GetData(dimension), param.numericFormatter));
paramList.Add(param);
}
}
private void UpdateSerieContext()
@@ -86,6 +131,8 @@ namespace XCharts.Runtime
}
return;
}
if (serie.heatmapType == HeatmapType.Count)
return;
m_LastCheckContextFlag = needCheck;
if (m_LegendEnter)
{
@@ -120,7 +167,7 @@ namespace XCharts.Runtime
}
}
private void DrawHeatmapSerie(VertexHelper vh, Heatmap serie)
private void DrawDataHeatmapSerie(VertexHelper vh, Heatmap serie)
{
if (!serie.show || serie.animation.HasFadeOut()) return;
XAxis xAxis;
@@ -212,7 +259,6 @@ namespace XCharts.Runtime
var highlight = (serieData.context.highlight) ||
visualMap.context.pointerIndex > 0;
//UGL.DrawRectangle(vh, pos, rectWid / 2, rectHig / 2, color);
UGL.DrawRectangle(vh, serieData.context.rect, color);
if (borderWidth > 0 && !ChartHelper.IsClearColor(borderColor))
@@ -243,5 +289,143 @@ namespace XCharts.Runtime
chart.RefreshPainter(serie);
}
}
private void DrawCountHeatmapSerie(VertexHelper vh, Heatmap serie)
{
if (!serie.show || serie.animation.HasFadeOut()) return;
XAxis xAxis;
YAxis yAxis;
if (!chart.TryGetChartComponent<XAxis>(out xAxis, serie.xAxisIndex)) return;
if (!chart.TryGetChartComponent<YAxis>(out yAxis, serie.yAxisIndex)) return;
m_SerieGrid = chart.GetChartComponent<GridCoord>(xAxis.gridIndex);
xAxis.boundaryGap = true;
yAxis.boundaryGap = true;
var visualMap = chart.GetVisualMapOfSerie(serie);
var emphasisStyle = serie.emphasisStyle;
var xCount = AxisHelper.GetTotalSplitGridNum(xAxis);
var yCount = AxisHelper.GetTotalSplitGridNum(yAxis);
var xWidth = m_SerieGrid.context.width / xCount;
var yWidth = m_SerieGrid.context.height / yCount;
var zeroX = m_SerieGrid.context.x;
var zeroY = m_SerieGrid.context.y;
var color = chart.theme.GetColor(serie.index);
var borderWidth = serie.itemStyle.show ? serie.itemStyle.borderWidth : 0;
var rectWid = xWidth - 2 * borderWidth;
var rectHig = yWidth - 2 * borderWidth;
var borderColor = serie.itemStyle.opacity > 0 ?
serie.itemStyle.borderColor :
ChartConst.clearColor32;
borderColor.a = (byte) (borderColor.a * serie.itemStyle.opacity);
var borderToColor = serie.itemStyle.opacity > 0 ?
serie.itemStyle.borderToColor :
ChartConst.clearColor32;
borderToColor.a = (byte) (borderToColor.a * serie.itemStyle.opacity);
serie.animation.InitProgress(0, xCount);
var animationIndex = serie.animation.GetCurrIndex();
var dataChanging = false;
serie.containerIndex = m_SerieGrid.index;
serie.containterInstanceId = m_SerieGrid.instanceId;
m_CountDict.Clear();
double minCount = 0, maxCount = 0;
foreach (var serieData in serie.data)
{
var xValue = serieData.GetData(0);
var yValue = serieData.GetData(1);
var i = AxisHelper.GetAxisValueSplitIndex(xAxis, xValue, xCount);
var j = AxisHelper.GetAxisValueSplitIndex(yAxis, yValue, yCount);
var key = GetGridKey(i, j);
var count = 0;
if (!m_CountDict.TryGetValue(key, out count))
count = 1;
else
count++;
if (count > maxCount)
maxCount = count;
m_CountDict[key] = count;
}
if (visualMap.autoMinMax)
{
VisualMapHelper.SetMinMax(visualMap, minCount, maxCount);
}
var rangeMin = visualMap.rangeMin;
var rangeMax = visualMap.rangeMax;
int highlightX = -1;
int highlightY = -1;
if (serie.context.pointerItemDataIndex > 0)
{
if (m_CountDict.ContainsKey(serie.context.pointerItemDataIndex))
{
GetGridXYByKey(serie.context.pointerItemDataIndex, out highlightX, out highlightY);
}
}
foreach (var kv in m_CountDict)
{
int i, j;
GetGridXYByKey(kv.Key, out i, out j);
var value = kv.Value;
if (serie.IsIgnoreValue(value))
{
continue;
}
if ((value < rangeMin && rangeMin != visualMap.min) ||
(value > rangeMax && rangeMax != visualMap.max))
{
continue;
}
if (!visualMap.IsInSelectedValue(value))
continue;
if (animationIndex >= 0 && i > animationIndex)
continue;
var highlight = i == highlightX && j == highlightY;
color = visualMap.GetColor(value);
if (highlight)
color = ChartHelper.GetHighlightColor(color);
var pos = new Vector3(zeroX + (i + 0.5f) * xWidth,
zeroY + (j + 0.5f) * yWidth);
var rect = new Rect(pos.x - rectWid / 2, pos.y - rectHig / 2, rectWid, rectHig);
UGL.DrawRectangle(vh, rect, color);
if (borderWidth > 0 && !ChartHelper.IsClearColor(borderColor))
{
UGL.DrawBorder(vh, pos, rectWid, rectHig, borderWidth, borderColor, borderToColor);
}
if (visualMap.hoverLink && highlight && emphasisStyle != null &&
emphasisStyle.itemStyle.borderWidth > 0)
{
var emphasisItemStyle = emphasisStyle.itemStyle;
var emphasisBorderWidth = emphasisItemStyle.borderWidth;
var emphasisBorderColor = emphasisItemStyle.opacity > 0 ?
emphasisItemStyle.borderColor : ChartConst.clearColor32;
var emphasisBorderToColor = emphasisItemStyle.opacity > 0 ?
emphasisItemStyle.borderToColor : ChartConst.clearColor32;
UGL.DrawBorder(vh, pos, rectWid, rectHig, emphasisBorderWidth, emphasisBorderColor,
emphasisBorderToColor);
}
}
if (!serie.animation.IsFinish())
{
serie.animation.CheckProgress(xCount);
chart.RefreshPainter(serie);
}
if (dataChanging)
{
chart.RefreshPainter(serie);
}
}
}
}