跳转至

HelloCharts 图表控件

HelloCharts 是一套功能丰富的图表控件集合,为 SOUI 提供了多种类型的图表展示功能,包括折线图、柱状图、饼图、气泡图、雷达图和组合图等。

概述

HelloCharts 图表控件基于 Android 版本的 HelloCharts 库移植而来,提供了丰富的图表展示功能和良好的交互体验。控件支持动画效果、数据选择、缩放、滚动等特性,可以满足大部分数据可视化需求。

支持的图表类型

HelloCharts 提供了以下几种图表类型:

  1. SLineChartView - 折线图
  2. SColumnChartView - 柱状图
  3. SPieChartView - 饼图
  4. SBubbleChartView - 气泡图
  5. SRadarChartView - 雷达图
  6. 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);

最佳实践

  1. 性能优化
  2. 对于大量数据,考虑分批加载或使用虚拟化技术
  3. 合理设置动画时长,避免过长的动画影响用户体验

  4. 用户体验

  5. 为不同类型的图表选择合适的颜色搭配
  6. 合理使用标签和图例,确保信息清晰可读
  7. 提供值选择反馈,增强交互体验

  8. 数据处理

  9. 对输入数据进行验证,避免无效数据导致显示异常
  10. 根据数据特点选择合适的图表类型

  11. 响应式设计

  12. 考虑不同屏幕尺寸下的显示效果
  13. 合理设置图表尺寸和元素大小

常见问题

  1. 图表不显示:检查是否已正确注册控件类
  2. 数据不更新:确保调用了相应的 SetChartData 方法
  3. 动画不播放:检查是否启用了动画并设置了合适的时长
  4. 交互无响应:确认是否设置了 interactive="1" 属性