HarmonyOS鸿蒙Next中flutter鸿蒙化,使用什么插件可以实现下面的圆环带有标注的

HarmonyOS鸿蒙Next中flutter鸿蒙化,使用什么插件可以实现下面的圆环带有标注的 最好是带有代码的demo,就是使用他怎么实现

cke_135.jpeg


更多关于HarmonyOS鸿蒙Next中flutter鸿蒙化,使用什么插件可以实现下面的圆环带有标注的的实战教程也可以访问 https://www.itying.com/category-92-b0.html

11 回复

Flutter Charts 库已经适配HarmonyOS了。

Flutter Charts 包是一个用 Dart 原生编写的数据可视化库,用于创建美观、动画和高性能的图表,用于使用 Flutter 制作高质量的移动应用程序用户界面。

图表类型 - 提供渲染 30+ 种图表类型的功能,即折线、样条、柱形、条形、面积、气泡、箱须、散点、阶梯线、快速线、范围列、范围区域、蜡烛、hilo、ohlc、直方图、步长区域、样条区域、样条曲线范围区域、堆叠区域、堆叠条形图、堆叠列、堆叠线、100% 堆叠区域、100% 堆叠条形图、100% 堆叠列、100% 堆叠线、瀑布、饼图、甜甜圈、径向条形图、金字塔、漏斗。每种图表类型都可以轻松配置和自定义,并具有内置功能,可创建令人惊叹的视觉效果。

如何demo案例中有实现圆环带有标注的:Flutter Charts

更多关于HarmonyOS鸿蒙Next中flutter鸿蒙化,使用什么插件可以实现下面的圆环带有标注的的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


我试了很多,但是和我想要的都相差甚远,不是没有标注,就是块区域没有间隔,要不就是不能点击突出了,

import 'dart:math';
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Charts Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: DataStatistics2(param: {}),
    );
  }
}

class DataStatistics2 extends StatefulWidget {
  final Map param;

  DataStatistics2({required this.param});

  @override
  _DataStatisticsState createState() => _DataStatisticsState();
}

class _DataStatisticsState extends State<DataStatistics2> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('统计图表'),
      ),
      body: Container(
        color: Colors.white,
        margin: EdgeInsets.all(20.0),
        child: SingleChildScrollView(
          child: Column(
            children: [
              Container(height: 180, width: double.infinity, child: _lineChart()),
              Container(height: 180, width: double.infinity, child: _barChart()),
              Container(height: 180, width: double.infinity, child: _pieChart()),
              Container(height: 180, width: double.infinity, child: _pieChart1()),
            ],
          ),
        ),
      ),
    );
  }

  Widget _lineChart() {
    List _list = ['1', '2', '3', '4'];
    var serial1data = [
      new SeriesData(0, 10),
      new SeriesData(1, 3),
      new SeriesData(2, 2),
      new SeriesData(3, 1),
    ];
    //自定义x轴
    final ticks = [
      charts.TickSpec(0, label: _list[0]),
      charts.TickSpec(1, label: _list[1]),
      charts.TickSpec(2, label: _list[2]),
      charts.TickSpec(3, label: _list[3]),
    ];
    var seriesList = [
      charts.Series<SeriesData, int>(
        id: '登录次数',
        colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
        domainFn: (SeriesData sales, _) => sales.day,
        measureFn: (SeriesData sales, _) => sales.count,
        data: serial1data,
      ),
    ];
    return charts.LineChart(
      seriesList,
      animate: true,
      domainAxis: new charts.NumericAxisSpec(
        tickProviderSpec: new charts.StaticNumericTickProviderSpec(ticks),
        tickFormatterSpec: charts.BasicNumericTickFormatterSpec(
              (measure) => exp(measure as num).round().toString(),
        ),
      ),
    );
  }

  //柱形图
  Widget _barChart() {
    var data = [
      PieSales(0, 10, 'item1', charts.ColorUtil.fromDartColor(Color(0xFF265AFD))),
      PieSales(1, 3, 'item2', charts.ColorUtil.fromDartColor(Color(0xFF265AFD))),
      PieSales(2, 2, 'item3', charts.ColorUtil.fromDartColor(Color(0xFF265AFD))),
      PieSales(3, 1, 'item4', charts.ColorUtil.fromDartColor(Color(0xFF265AFD))),
    ];

    int num = 10 + 3 + 2 + 1;

    var seriesList = [
      charts.Series<PieSales, String>(
        id: 'Sales',
        colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
        domainFn: (PieSales sales, _) => sales.name,
        measureFn: (PieSales sales, _) => sales.sales,
        fillColorFn: (PieSales sales, _) => sales.color,
        data: data,
        labelAccessorFn: (PieSales sales, _) =>
        '${sales.sales}人,${(sales.sales / num * 100).toStringAsFixed(0)}%',
      )
    ];

    return charts.BarChart(
      seriesList,
      animate: false,
      barGroupingType: charts.BarGroupingType.stacked,
      barRendererDecorator: new charts.BarLabelDecorator<String>(),
    );
  }

  //饼图
  Widget _pieChart() {
    var data = [
      PieSales(0, 10, 'item1', charts.ColorUtil.fromDartColor(Color(0xFF58A3FF))),
      PieSales(1, 3, 'item2', charts.ColorUtil.fromDartColor(Color(0xFF51DBB6))),
      PieSales(2, 2, 'item3', charts.ColorUtil.fromDartColor(Color(0xFF58A3FF))),
      PieSales(3, 1, 'item4', charts.ColorUtil.fromDartColor(Color(0xFF51DBB6))),
    ];

    int num = 10 + 3 + 2 + 1;

    var seriesList = [
      charts.Series<PieSales, int>(
        id: 'Sales',
        domainFn: (PieSales sales, _) => sales.domain,
        measureFn: (PieSales sales, _) => sales.sales,
        colorFn: (PieSales sales, _) => sales.color,
        data: data,
        displayName: '57',
        labelAccessorFn: (PieSales row, _) =>
        '${row.name}${row.sales}人\n ${(row.sales / num * 100).toStringAsFixed(0)}%',
      )
    ];

    return Stack(
      children: [
        charts.PieChart(seriesList,
            animate: false,
            defaultRenderer: new charts.ArcRendererConfig(
                arcRendererDecorators: [
                  new charts.ArcLabelDecorator(
                    labelPosition: charts.ArcLabelPosition.outside,
                  )
                ]))
      ],
    );
  }

  //环形图(修复pieList泛型和累加问题)
// 修复后的饼图方法
  // 修复后的环形图方法
  Widget _pieChart1() {
    // 已修复:泛型问题
    List<int> pieList = [10, 3, 2, 1];
    var data = [
      PieSales(0, pieList[0], 'item1', charts.ColorUtil.fromDartColor(Color(0xFF58A3FF))),
      PieSales(1, pieList[1], 'item2', charts.ColorUtil.fromDartColor(Color(0xFF51DBB6))),
      PieSales(2, pieList[2], 'item3', charts.ColorUtil.fromDartColor(Color(0xFF58A3FF))),
      PieSales(3, pieList[3], 'item4', charts.ColorUtil.fromDartColor(Color(0xFF51DBB6))),
    ];

    int personNum = 0;
    for (var element in pieList) {
      personNum += element;
    }

    var seriesList = [
      charts.Series<PieSales, int>(
        id: 'Sales',
        domainFn: (PieSales sales, _) => sales.domain,
        measureFn: (PieSales sales, _) => sales.sales,
        colorFn: (PieSales sales, _) => sales.color,
        data: data,
        labelAccessorFn: (PieSales row, _) =>
        "${row.name}\n${(row.sales / personNum * 100).toStringAsFixed(0)}%",
      )
    ];

    // 关键1:容器设固定宽高
    return Container(
      width: 300,
      height: 180,
      // 关键2:用Stack包裹图表和中心文字,给图表加Positioned.fill确保占满空间
      child: Stack(
        alignment: Alignment.center, // 中心文字居中
        children: [
          // 图表占满Stack
          Positioned.fill(
            child: charts.PieChart(
              seriesList,
              animate: true, // 触发渲染
              defaultRenderer: charts.ArcRendererConfig(
                arcWidth: 25, // 环形宽度(越大越粗)
                arcRatio: 50, // 环形半径(控制环形大小)
                arcRendererDecorators: [
                  charts.ArcLabelDecorator(
                    labelPosition: charts.ArcLabelPosition.outside,
                    outsideLabelStyleSpec: charts.TextStyleSpec(
                      fontSize: 11,
                      color: charts.Color.black,
                    ),
                  )
                ],
              ),
            ),
          ),
          // 中心文字(层级在图表之上,不会被遮挡)
          Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('$personNum', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
              Text('人员统计', style: TextStyle(fontSize: 14, color: Colors.grey)),
            ],
          ),
        ],
      ),
    );
  }
}

class SeriesData {
  final int day;
  final int count;

  SeriesData(this.day, this.count);
}

class PieSales {
  final int domain;
  final int sales;
  final String name;
  final charts.Color color;

  PieSales(this.domain, this.sales, this.name, this.color);
}

这个是我使用的插件进行的测试但是,折线图和柱状图可以实现,只有饼状图和圆环图是失败的显示不出来

可以参考下Flutter_chart其中有圆环添加标注的示例,主要功能如下:

1、支持line、bar、pie、progress、radar、scatter等常规图形

2、支持各种annotation,如ImageAnnotation、LabelAnnotation

3、DimensionsCoordinateRender坐标系x轴支持放大、缩小后动态设置

4、支持图表分层,分为弹框层、前景层、图表层。

这是别人写的适配鸿蒙的图表插件吗,

我这样写 flutter_chart: git: url: “https://gitcode.com/andyleftZJ/flutter_chart.git” 是不是有问题,为什么pub get 失败呢,

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17

因为楼主提供的Flutter_chart三方库还没适配HarmonyOS。 参考下这个已经适配HarmonyOS 的Flutter Charts 库 参考链接:https://gitcode.com/openharmony-sig/fluttertpc_syncfusion_flutter_charts/tree/master/packages/syncfusion_flutter_charts/

在HarmonyOS鸿蒙Next中实现带标注的圆环,可使用Flutter的custom_paint插件进行自定义绘制。通过CustomPainter类定义Canvas绘制逻辑,结合PathTextPainter分别绘制圆环及标注文本。需注意鸿蒙Next的Flutter环境适配,确保插件兼容性。

在HarmonyOS Next中实现圆环标注图表,推荐使用@ohos/charts组件库。以下是基于ETS的示例代码:

import { RingChart, RingChartData } from '@ohos/charts';

@Entry
@Component
struct RingChartExample {
  private chartData: RingChartData[] = [
    { value: 30, color: '#FF6B6B', label: '分类A' },
    { value: 25, color: '#4ECDC4', label: '分类B' },
    { value: 20, color: '#45B7D1', label: '分类C' },
    { value: 15, color: '#F9A602', label: '分类D' }
  ];

  build() {
    Column() {
      RingChart({
        data: this.chartData,
        strokeWidth: 20,
        radius: 100,
        showLabel: true, // 启用标注显示
        labelPosition: 'outside', // 标注位置
        labelStyle: {
          fontSize: 14,
          color: '#000000'
        }
      })
      .width(300)
      .height(300)
    }
  }
}

关键配置说明:

  • showLabel: true 启用环状标注
  • labelPosition 控制标注位置(outside/inside)
  • 通过labelStyle自定义标注文本样式

需要先在项目中安装charts依赖:

// package.json
"dependencies": {
  "@ohos/charts": "^1.0.0"
}
回到顶部