mirror of
https://github.com/XCharts-Team/XCharts.git
synced 2026-05-22 08:50:10 +00:00
[feature][heatmap] support heatmapType
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user