HelloCharts 图表控件¶
HelloCharts 是一套功能丰富的图表控件集合,为 SOUI 提供了多种类型的图表展示功能,包括折线图、柱状图、饼图、气泡图、雷达图和组合图等。
概述¶
HelloCharts 图表控件基于 Android 版本的 HelloCharts 库移植而来,提供了丰富的图表展示功能和良好的交互体验。控件支持动画效果、数据选择、缩放、滚动等特性,可以满足大部分数据可视化需求。
支持的图表类型¶
HelloCharts 提供了以下几种图表类型:
- SLineChartView - 折线图
- SColumnChartView - 柱状图
- SPieChartView - 饼图
- SBubbleChartView - 气泡图
- SRadarChartView - 雷达图
- SComboChartView - 组合图(折线图+柱状图)
控件注册¶
在使用 HelloCharts 控件之前,需要先注册控件类:
#include "SHelloCharts.h"
// 在应用程序初始化时注册控件
SHelloChartsRegister::RegisterControls(&app);
或者手动注册各个控件:
app.RegisterWindowClass<SLineChartView>();
app.RegisterWindowClass<SColumnChartView>();
app.RegisterWindowClass<SPieChartView>();
app.RegisterWindowClass<SBubbleChartView>();
app.RegisterWindowClass<SRadarChartView>();
app.RegisterWindowClass<SComboChartView>();
基本用法¶
在 XML 中声明图表控件¶
<!-- 折线图 -->
<lineChart name="line_chart" interactive="1" zoomEnabled="1" scrollEnabled="1" />
<!-- 柱状图 -->
<columnChart name="column_chart" interactive="1" stacked="0" fillRatio="0.75" />
<!-- 饼图 -->
<pieChart name="pie_chart" />
<!-- 气泡图 -->
<bubbleChart name="bubble_chart" />
<!-- 雷达图 -->
<radarChart name="radar_chart" />
<!-- 组合图 -->
<comboChart name="combo_chart" />
在代码中初始化图表控件¶
// 获取图表控件
SLineChartView* pLineChart = FindChildByName2<SLineChartView>(L"line_chart");
SColumnChartView* pColumnChart = FindChildByName2<SColumnChartView>(L"column_chart");
SPieChartView* pPieChart = FindChildByName2<SPieChartView>(L"pie_chart");
// 设置值选择监听器(可选)
CLineChartValueSelectListener* pListener = new CLineChartValueSelectListener(this);
pLineChart->SetOnValueSelectListener(pListener);
折线图 (SLineChartView)¶
折线图用于显示数据随时间或其他连续变量的变化趋势。
创建折线图数据¶
// 创建折线图数据对象
SLineChartData* pData = new SLineChartData();
// 配置 X 轴
SAxis* pAxisX = new SAxis();
pAxisX->SetName(_T("时间 (小时)"));
pAxisX->SetTextColor(RGBA(100, 100, 100, 255));
// 添加轴标签
for (int i = 0; i <= 8; i += 2) {
SStringT label;
label.Format(_T("%dh"), i);
SAxisValue* pValue = new SAxisValue((float)i, label);
pAxisX->AddValue(pValue);
}
pData->SetAxisX(pAxisX);
// 配置 Y 轴
SAxis* pAxisY = new SAxis();
pAxisY->SetName(_T("数值"));
// 添加轴标签
for (int i = 0; i <= 10; i += 2) {
SStringT label;
label.Format(_T("%.0f"), (float)i);
SAxisValue* pValue = new SAxisValue((float)i, label);
pAxisY->AddValue(pValue);
}
pData->SetAxisY(pAxisY);
// 启用坐标轴显示
pData->SetAxesEnabled(TRUE);
// 创建折线数据
std::vector<SPointValue*> values;
for (int i = 0; i < 10; ++i) {
float x = (float)i;
float y = 1.0f + (float)(rand() % 900) / 100.0f;
SPointValue* pValue = new SPointValue(x, y);
values.push_back(pValue);
}
// 创建折线
SLine* pLine = new SLine(values);
pLine->SetColor(RGBA(51, 181, 229, 255)); // 蓝色
pLine->SetHasPoints(TRUE);
pLine->SetStrokeWidth(3);
pLine->SetPointRadius(4);
pData->AddLine(pLine);
// 设置图表数据
pLineChart->SetLineChartData(pData);
折线图属性¶
| 属性 | 描述 |
|---|---|
| interactive | 是否启用交互 |
| zoomEnabled | 是否启用缩放 |
| scrollEnabled | 是否启用滚动 |
柱状图 (SColumnChartView)¶
柱状图用于比较不同类别的数据。
创建柱状图数据¶
// 创建柱状图数据对象
SColumnChartData* pData = new SColumnChartData();
// 配置坐标轴
SAxis* pAxisX = new SAxis();
pAxisX->SetName(_T("类别"));
// 添加类别标签
SStringT categories[] = {_T("A"), _T("B"), _T("C"), _T("D"), _T("E"), _T("F")};
for (int i = 0; i < 6; ++i) {
SAxisValue* pValue = new SAxisValue((float)i, categories[i]);
pAxisX->AddValue(pValue);
}
pData->SetAxisX(pAxisX);
SAxis* pAxisY = new SAxis();
pAxisY->SetName(_T("数值"));
pData->SetAxisY(pAxisY);
pData->SetAxesEnabled(TRUE);
// 创建柱状数据
for (int i = 0; i < 6; ++i) {
std::vector<SSubcolumnValue*> values;
float value = 20.0f + (float)(rand() % 8000) / 100.0f;
SSubcolumnValue* pValue = new SSubcolumnValue(value);
values.push_back(pValue);
SColumn* pColumn = new SColumn(values);
COLORREF colors[] = {
RGBA(51, 181, 229, 255), // 蓝色
RGBA(255, 87, 87, 255), // 红色
RGBA(76, 175, 80, 255), // 绿色
RGBA(255, 193, 7, 255), // 黄色
RGBA(156, 39, 176, 255), // 紫色
RGBA(255, 152, 0, 255) // 橙色
};
pColumn->SetColor(colors[i % 6]);
pColumn->SetHasLabels(TRUE);
pData->AddColumn(pColumn);
}
// 设置填充比例
pData->SetFillRatio(0.75f);
// 设置图表数据
pColumnChart->SetColumnChartData(pData);
柱状图属性¶
| 属性 | 描述 |
|---|---|
| stacked | 是否堆叠显示 |
| fillRatio | 填充比例 |
饼图 (SPieChartView)¶
饼图用于显示各部分占总体的比例关系。
创建饼图数据¶
// 创建饼图数据对象
SPieChartData* pData = new SPieChartData();
// 添加扇形数据
struct SliceData {
SStringT label;
float value;
COLORREF color;
};
SliceData slices[] = {
{_T("技术"), 30.0f, RGBA(51, 181, 229, 255)},
{_T("医疗"), 25.0f, RGBA(255, 87, 87, 255)},
{_T("金融"), 20.0f, RGBA(76, 175, 80, 255)},
{_T("教育"), 15.0f, RGBA(255, 193, 7, 255)},
{_T("零售"), 10.0f, RGBA(156, 39, 176, 255)}
};
for (int i = 0; i < 5; ++i) {
SSliceValue* pValue = new SSliceValue(slices[i].value, slices[i].color, slices[i].label);
pData->AddValue(pValue);
}
// 配置饼图属性
pData->SetHasLabels(TRUE);
pData->SetHasLabelLines(TRUE);
pData->SetCenterCircleRatio(0.0f); // 0表示完整饼图,>0表示环形图
// 设置图表数据
pPieChart->SetPieChartData(pData);
饼图属性¶
| 属性 | 描述 |
|---|---|
| circleFillRatio | 圆形填充比例(用于环形图) |
| labelsEnabled | 是否启用标签 |
| labelLinesEnabled | 是否启用标签连线 |
气泡图 (SBubbleChartView)¶
气泡图用于显示三个维度的数据(X、Y坐标和气泡大小)。
创建气泡图数据¶
// 创建气泡图数据对象
SBubbleChartData* pData = new SBubbleChartData();
// 添加气泡数据
struct BubbleInfo {
SStringT label;
float x; // X坐标
float y; // Y坐标
float z; // 气泡大小
COLORREF color;
};
BubbleInfo bubbles[] = {
{_T("公司A"), 100.0f, 25.0f, 2000.0f, RGBA(51, 181, 229, 255)},
{_T("公司B"), 200.0f, 30.0f, 1500.0f, RGBA(255, 87, 87, 255)},
{_T("公司C"), 150.0f, 20.0f, 1000.0f, RGBA(76, 175, 80, 255)}
};
for (int i = 0; i < 3; ++i) {
SBubbleValue* pValue = new SBubbleValue(
bubbles[i].x, bubbles[i].y, bubbles[i].z,
bubbles[i].color, bubbles[i].label);
pData->AddValue(pValue);
}
// 配置气泡图属性
pData->SetHasBubbleLabels(TRUE);
pData->SetMinBubbleRadius(8);
pData->SetMaxBubbleRadius(60);
pData->SetBubbleScale(1); // 面积缩放
// 设置坐标轴
SAxis* pAxisX = new SAxis();
pAxisX->SetName(_T("收入 (百万)"));
pData->SetAxisX(pAxisX);
SAxis* pAxisY = new SAxis();
pAxisY->SetName(_T("利润率 (%)"));
pData->SetAxisY(pAxisY);
pData->SetAxesEnabled(TRUE);
// 设置图表数据
pBubbleChart->SetBubbleChartData(pData);
气泡图属性¶
| 属性 | 描述 |
|---|---|
| bubbleLabelsEnabled | 是否启用气泡标签 |
| minBubbleRadius | 最小气泡半径 |
| maxBubbleRadius | 最大气泡半径 |
| bubbleScale | 气泡缩放类型 |
雷达图 (SRadarChartView)¶
雷达图用于显示多维数据的对比。
创建雷达图数据¶
// 创建雷达图数据对象
SRadarChartData* pData = new SRadarChartData();
// 添加轴标签
pData->AddAxisLabel(_T("速度"));
pData->AddAxisLabel(_T("力量"));
pData->AddAxisLabel(_T("智力"));
pData->AddAxisLabel(_T("耐力"));
pData->AddAxisLabel(_T("敏捷"));
pData->AddAxisLabel(_T("准确"));
// 添加数据系列
struct CharacterProfile {
SStringT name;
float values[6];
COLORREF color;
};
CharacterProfile profiles[] = {
{_T("战士"), {60.0f, 95.0f, 40.0f, 90.0f, 55.0f, 70.0f}, RGBA(255, 87, 87, 255)},
{_T("法师"), {45.0f, 30.0f, 98.0f, 50.0f, 60.0f, 85.0f}, RGBA(51, 181, 229, 255)}
};
for (int i = 0; i < 2; ++i) {
SRadarValue* pValue = new SRadarValue(profiles[i].name, profiles[i].color);
for (int j = 0; j < 6; ++j) {
pValue->AddAxisValue(profiles[i].values[j]);
}
pData->AddValue(pValue);
}
// 配置雷达图属性
pData->SetHasRadarLabels(TRUE);
pData->SetHasWebLines(TRUE);
pData->SetWebRings(5);
pData->SetMaxValue(100.0f);
// 设置图表数据
pRadarChart->SetRadarChartData(pData);
雷达图属性¶
| 属性 | 描述 |
|---|---|
| radarLabelsEnabled | 是否启用雷达标签 |
| webLinesEnabled | 是否启用网格线 |
| webRings | 网格环数 |
| maxValue | 最大值 |
组合图 (SComboChartView)¶
组合图可以同时显示多种类型的图表,如折线图和柱状图的组合。
创建组合图数据¶
// 创建组合图数据对象
SComboChartData* pData = new SComboChartData();
// 创建折线图数据(温度)
SLineChartData* pLineData = new SLineChartData();
std::vector<SPointValue*> lineValues;
float temperatures[] = {-2.0f, 1.0f, 8.0f, 15.0f, 22.0f, 28.0f,
32.0f, 30.0f, 25.0f, 18.0f, 10.0f, 3.0f};
for (int i = 0; i < 12; ++i) {
SPointValue* pPoint = new SPointValue((float)i, temperatures[i]);
lineValues.push_back(pPoint);
}
SLine* pTempLine = new SLine(lineValues);
pTempLine->SetColor(RGBA(255, 87, 87, 255));
pLineData->AddLine(pTempLine);
pData->SetLineChartData(pLineData);
// 创建柱状图数据(降雨量)
SColumnChartData* pColumnData = new SColumnChartData();
float rainfall[] = {45.0f, 38.0f, 52.0f, 68.0f, 85.0f, 120.0f,
135.0f, 128.0f, 95.0f, 72.0f, 58.0f, 48.0f};
for (int i = 0; i < 12; ++i) {
std::vector<SSubcolumnValue*> values;
SSubcolumnValue* pValue = new SSubcolumnValue(rainfall[i]);
pValue->SetColor(RGBA(51, 181, 229, 200));
values.push_back(pValue);
SColumn* pColumn = new SColumn(values);
pColumnData->AddColumn(pColumn);
}
pData->SetColumnChartData(pColumnData);
// 配置组合图属性
pData->SetComboType(0); // 0=柱状图在后,1=折线图在后
pData->SetUseSeparateYAxes(TRUE);
pData->SetSecondaryAxisOnRight(TRUE);
// 设置图表数据
pComboChart->SetComboChartData(pData);
组合图属性¶
| 属性 | 描述 |
|---|---|
| comboType | 组合类型 |
| useSeparateYAxes | 是否使用独立Y轴 |
| secondaryAxisOnRight | 次级Y轴是否在右侧 |
| lineChartAlpha | 折线图透明度 |
| columnChartAlpha | 柱状图透明度 |
动画支持¶
所有图表控件都支持动画效果:
// 启动数据动画
pLineChart->StartDataAnimation(500); // 500ms 动画时长
// 取消动画
pLineChart->CancelDataAnimation();
// 检查动画是否正在运行
BOOL isRunning = pLineChart->IsDataAnimationRunning();
交互功能¶
图表控件支持多种交互功能:
值选择监听器¶
// 折线图值选择监听器
struct ILineChartOnValueSelectListener
{
virtual void OnValueSelected(int lineIndex, int pointIndex, SPointValue* pValue) = 0;
virtual void OnValueDeselected() = 0;
};
// 柱状图值选择监听器
struct IColumnChartOnValueSelectListener
{
virtual void OnValueSelected(int columnIndex, int subcolumnIndex, SSubcolumnValue* pValue) = 0;
virtual void OnValueDeselected() = 0;
};
// 设置监听器
pLineChart->SetOnValueSelectListener(pListener);
缩放和滚动¶
// 启用/禁用缩放
pLineChart->SetZoomEnabled(TRUE);
// 启用/禁用滚动
pLineChart->SetScrollEnabled(TRUE);
// 启用/禁用交互
pLineChart->SetInteractive(TRUE);
最佳实践¶
- 性能优化:
- 对于大量数据,考虑分批加载或使用虚拟化技术
-
合理设置动画时长,避免过长的动画影响用户体验
-
用户体验:
- 为不同类型的图表选择合适的颜色搭配
- 合理使用标签和图例,确保信息清晰可读
-
提供值选择反馈,增强交互体验
-
数据处理:
- 对输入数据进行验证,避免无效数据导致显示异常
-
根据数据特点选择合适的图表类型
-
响应式设计:
- 考虑不同屏幕尺寸下的显示效果
- 合理设置图表尺寸和元素大小
常见问题¶
- 图表不显示:检查是否已正确注册控件类
- 数据不更新:确保调用了相应的 SetChartData 方法
- 动画不播放:检查是否启用了动画并设置了合适的时长
- 交互无响应:确认是否设置了 interactive="1" 属性