🛰️

ここはどこ -flutter_echarts その2

2024/07/20に公開

複数の宇宙探査機の航跡を重ねる

今回、対象にしたい宇宙探査機は5機ある。
そのうち、パイオニア10号と11号は既に通信が途絶しているので、新しいデータは入ってこない。
ボイジャー1号と2号は、まだかろうじて位置を追跡できているが、
既に太陽圏を出ているので、航跡に大きな変化はないと思う。
データの更新があるのは、ニューホライズンズ。
データベースからの読み出しは少し節約したいので、
少なくとも前者4機については、jsonデータでアプリに入れてしまおうと思う。

一機ごとの航跡データをassetsに入れる

例えばボイジャー1号

 [
    {"value": [0, 0, 0], "name": "Sun", "itemStyle": {"color": "red"}},
    {"value": [14.5, -4.2, 0], "name": "-", "itemStyle": {"color": "#8069BF"}},

  //中略 

    {"value": [-329.5, -1049.3, 760.2], "name": "03", "itemStyle": {"color": "#8069BF"}},
    {"value": [-336.2, -1093.1, 791.8], "name": "04", "itemStyle": {"color": "#8069BF"}}
  ]

それをPageから呼び出す

もっとすっきり書けないんか・・・と思うが・・・とりあえず。
なんでいったんdecodeして、またencodeする? とか、悩みどころはいろいろ。

class PathsState extends State<Paths> {
  final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();

  List<dynamic>? voyager1;
  List<dynamic>? voyager2;
  List<dynamic>? pioneer10;
  List<dynamic>? interstellar 

  
  void initState() {
    super.initState();
    _loadData();
  }

  Future<void> _loadData() async {
    final voyager1Data = await rootBundle.loadString('assets/voyager1.json');
    final voyager2Data = await rootBundle.loadString('assets/voyager2.json');
    final pioneer10Data = await rootBundle.loadString('assets/pioneer10.json');
    setState(() {
      List<dynamic> combineData = [];
      combineData.addAll(json.decode(voyager1Data));
      combineData.addAll(json.decode(voyager2Data));
      combineData.addAll(json.decode(pioneer10Data));

      interstellar = combineData;
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldKey,
      appBar: AppBar(
        title: const Text('3D Scatter Chart Example'),
      ),
      body: Center(
        child: SizedBox(
          width: 1200,
          height: 1000,
          child: interstellar == null
            ? const CircularProgressIndicator()
            : Echarts(
                  extensions: const [glScript],
                  option: '''
        {
          grid3D: {
            viewControl: {
              alpha: 40,
              beta: -60
            }
          },
          xAxis3D: {
            type: 'value',
            min: -500,
            max: 500,
            splitLine: {show: false},
            name: 'Pisces-Virgo',
            axisLine: {
              lineStyle: {color: '#E6E1E6'}
            }
          },

  //中略
          series: [
            {
            type: 'scatter3D',
            symbolSize: 5,
            data: 
                ${json.encode(interstellar)},
            label: {
              show: true,
              textStyle: {
              fontSize: 12,
              borderWidth: 1
              },
              formatter: function(param) {
                return param.data.name;
              }
            },
            itemStyle: {opacity: 0.8}    
            },

   //後略

とりあえず三機

せっかくだから惑星軌道のcodeも統合しよう

まず惑星軌道のための関数をoptionのてっぺんに設定。
それから、各軌道半径を引数にして描画。

Echarts(
  extensions: const [glScript],
  option: '''
    (function() {
      function generateOrbitData(radius, interval) {
        var data = [];
        for (var t = 0; t < 2 * Math.PI; t += interval) {
          var x = radius * Math.cos(t);
          var y = radius * Math.sin(t);
          var z = 0;  // z軸は0で固定
          data.push([x, y, z]);
        }
        return data;
      }

      return {
        grid3D: {
          viewControl: {
            alpha: 40,
            beta: -60
          }
        },
  //中略

 {
            type: 'scatter3D',
            symbolSize: 2,
            data: generateOrbitData(14.96, 0.1), // 地球
            itemStyle: { color: '#FF6347' } 
          },
          {
            type: 'scatter3D',
            symbolSize: 2,
            data: generateOrbitData(22.8, 0.1), // 火星
            itemStyle: { color: '#FF6347' } 
          },
          {
            type: 'scatter3D',
            symbolSize: 2,
            data: generateOrbitData(77.85, 0.05), // 木星
            itemStyle: { color: '#FF6347' } 
          }, 
          {
            type: 'scatter3D',
            symbolSize: 2,
            data: generateOrbitData(143.20, 0.05), // 土星
            itemStyle: { color: '#FF6347' }
          }, 
          {
            type: 'scatter3D',
            symbolSize: 2,
            data: generateOrbitData(286.7, 0.01), // 天王星
            itemStyle: { color: '#FF6347' }
          }, 
          {
            type: 'scatter3D',
            symbolSize: 2,
            data: generateOrbitData(451.5, 0.01), // 海王星
            itemStyle: { color: '#FF6347' }       
          }
        ]
      };
    })()
    ''',
          ),

なんかよくわからない行もあるが・・・
毎回for文を書いていたので、だいぶ節約。
200行を割ったので、許容範囲ということにしよう。

あと2機分、データ整形がんばろう\(^O^)/

四次元年表
https://app.laporte.academy
三次元・四次元表示
https://tempo-spaco.web.app
四次元年表の使い方
https://www.youtube.com/@laporte_academy

四次元年表for Mobile
https://apps.apple.com/jp/app/四次元年表for-mobile/id6502634868

https://play.google.com/store/apps/details?id=academy.laporte.chronomapMobile.chronomap_mobile&hl=ja

Flutter大学

Discussion