img

目录

  • 案例介绍
  • 代码实现
  • 1. 图表数据定义
  • 2. 图表卡片实现
  • 代码详解
  • 1. 柱状图实现
  • 2. 饼图实现
  • 3. 图例实现
  • 总结

案例介绍

本篇文章将介绍如何在GridRow组件构建的数据仪表盘中实现图表功能。通过基本组件模拟柱状图和饼图,展示销售趋势和用户分布等数据。

代码实现

1. 图表数据定义

@State cardList: DashboardCard[] = [
  {
    id: 5,
    title: '销售趋势',
    type: CardType.CHART,
    color: '#2196F3',
    span: 12,
    data: [30, 40, 35, 50, 49, 60, 70, 91, 125]
  },
  {
    id: 6,
    title: '用户分布',
    type: CardType.CHART,
    color: '#4CAF50',
    span: 6,
    data: [30, 25, 15, 30]
  }
];

2. 图表卡片实现

@Builder
renderChartCard(card: DashboardCard) {
  Column() {
    Row() {
      Text(card.title)
        .fontSize(16)
        .opacity(0.6)
      Blank()
      Text('查看详情')
        .fontSize(14)
        .fontColor(card.color)
    }
    .width('100%')
    
    // 根据图表类型渲染不同的图表
    if (card.title === '销售趋势') {
      this.renderBarChart(card)
    } else if (card.title === '用户分布') {
      this.renderPieChart(card)
    }
  }
  .width('100%')
  .padding(16)
  .backgroundColor(Color.White)
  .borderRadius(8)
}

// 渲染柱状图
@Builder
renderBarChart(card: DashboardCard) {
  Row() {
    ForEach(card.data, (value: number) => {
      Column() {
        Blank()
        Column()
          .width(16)
          .height(value)
          .backgroundColor(card.color)
          .borderRadius({ topLeft: 4, topRight: 4 })
      }
      .height(150)
      .layoutWeight(1)
      .justifyContent(FlexAlign.End)
    })
  }
  .width('100%')
  .height(180)
  .margin({ top: 16 })
}

// 渲染饼图
@Builder
renderPieChart(card: DashboardCard) {
  Row() {
    Stack() {
      // 背景圆
      Circle()
        .width(120)
        .height(120)
        .fill('#F5F5F5')
      
      // 数据扇形
      Circle()
        .width(120)
        .height(120)
        .fill(card.color)
        .opacity(0.8)
        .style({ clipPath: 'polygon(50% 50%, 50% 0%, 100% 0%, 100% 50%)' })
      
      Circle()
        .width(120)
        .height(120)
        .fill('#2196F3')
        .opacity(0.8)
        .style({ clipPath: 'polygon(50% 50%, 100% 50%, 100% 100%, 50% 100%)' })
      
      Circle()
        .width(120)
        .height(120)
        .fill('#FF9800')
        .opacity(0.8)
        .style({ clipPath: 'polygon(50% 50%, 50% 100%, 0% 100%, 0% 50%)' })
      
      Circle()
        .width(120)
        .height(120)
        .fill('#9C27B0')
        .opacity(0.8)
        .style({ clipPath: 'polygon(50% 50%, 0% 50%, 0% 0%, 50% 0%)' })
      
      // 中心白色圆
      Circle()
        .width(40)
        .height(40)
        .fill(Color.White)
    }
    .width(120)
    .height(120)
    
    // 图例
    Column({ space: 8 }) {
      Row() {
        Circle().width(12).height(12).fill(card.color)
        Text('新用户').fontSize(14).margin({ left: 8 })
      }
      
      Row() {
        Circle().width(12).height(12).fill('#2196F3')
        Text('老用户').fontSize(14).margin({ left: 8 })
      }
      
      Row() {
        Circle().width(12).height(12).fill('#FF9800')
        Text('访客').fontSize(14).margin({ left: 8 })
      }
      
      Row() {
        Circle().width(12).height(12).fill('#9C27B0')
        Text('其他').fontSize(14).margin({ left: 8 })
      }
    }
    .margin({ left: 16 })
    .alignItems(HorizontalAlign.Start)
  }
  .width('100%')
  .justifyContent(FlexAlign.Center)
  .margin({ top: 16 })
}

代码详解

1. 柱状图实现

柱状图的关键实现点:

  1. 使用Row布局横向排列柱子
  2. 每个柱子使用Column布局,通过height属性控制高度
  3. 使用layoutWeight(1)平均分配宽度
  4. 通过justifyContent(FlexAlign.End)实现底部对齐

2. 饼图实现

饼图的实现技巧:

  1. 使用Stack叠加多个Circle组件
  2. 通过clipPath属性裁剪出扇形
  3. 使用opacity设置透明度增加层次感
  4. 添加中心白色圆形营造环形效果

3. 图例实现

图例设计要点:

  1. 使用Column布局垂直排列图例项
  2. 每个图例项包含颜色圆点和文本
  3. 通过space属性控制图例项间距
  4. 使用alignItems控制对齐方式

总结

本篇文章展示了如何在数据仪表盘中实现简单的图表效果。通过基本组件的组合和样式设置,实现了柱状图和饼图的可视化效果。这种实现方式虽然简单,但能够满足基本的数据展示需求。在实际应用中,可以根据需要使用更专业的图表库来实现更复杂的图表效果。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐