0

私はこのデータセットを取得するのに苦労しており、複数のコンポーネントにまたがって表示できるようにしています。現在、React アプリケーションで Chart.js から折れ線グラフを生成する 6 つの異なるコンポーネントがあります。QuickBase RESTful API から API 呼び出しを完了して 2 つの異なるテーブルを呼び出し、各テーブルからフィールドのリストを取得しようとしています。したがって、構造内に、これらの 2 つの異なる API 呼び出しを格納する 2 つのファイルが各テーブルにあります。これらの API 呼び出しを正常に完了し、必要に応じてデータを実際にレンダリングして、これらすべてのチャートで使用できるようになることを願っています。これで私を助けることができる人はいますか?しばらくこれに固執しています...これまでのAPI呼び出しの内容は次のとおりです。

import React, { Component } from 'react'

let headers = {
  'QB-Realm-Hostname': 'XXXXXXXXXX.quickbase.com',
  'User-Agent': 'FileService_Integration_V2.1',
  'Authorization': 'QB-USER-TOKEN XXXX_XXXX_XXXXXXXXXXXXXX',
  'Content-Type': 'application/json'
};

class JobsTableApi extends Component {
  state = {
    data: [],
  }

  componentDidMount() {
    this.fetchData();
  }    

  fetchData = () => {    
    let body = {"from":"bpz99ram7","select":[3,6,80,81,82,83,86,84,88,89,90,91,92,93,94,95,96,97,98,99,101,103,104,105,106,107,109,111,113,115,120,123,224,225,226,227,228,229,230,231,477,479,480,481],"sortBy":[{"fieldId":6,"order":"ASC"}],"groupBy":[{"fieldId":40,"grouping":"equal-values"}],"options":{"skip":0,"top":0,"compareWithAppLocalTime":false}}

    fetch('https://api.quickbase.com/v1/records/query', {
      method: 'POST',
      headers: headers,
      body: JSON.stringify(body)
    }).then(response => {
      if (response.ok) {
        return response.json().then(res => {
          this.setState({
            data: [],
          })
        });
      }

      return response.json().then(resBody => Promise.reject({status: response.status, ...resBody}));
    }).catch(err => console.log(err))
  }

  render() {
    const { data } = this.state;

    if (data === null) return 'Loading...';

    return (
      <div>
        {data.jobname}
      </div>
    );
  }
}

export default JobsTableApi;

したがって、最終的には、必要に応じて折れ線グラフに割り当てることができるように、「選択」セクションに記載されているすべてのフィールドを選択しようとしています。レンダリングするものを何も取得できない場合、ここで何が間違っていますか?? アイデアは、私たちのクイックベースはプロジェクト管理用であるため、ページ上の 1 つの折れ線グラフは「合計」であり、他のものはそのジョブに含まれる部門のものであり、それらはすべて関連しており、データはすべてクイックベースにあり、私のコンソールでは、しかし、これをすべて適切にレンダリングする方法がわからないので、折れ線グラフを作成し、ジョブ名に基づいて結果を循環させることができます。

jsonが次のようにやってくるので、各フィールド名を呼び出す方法もわかりません: data: 0, 3, 18

0 = そのジョブのすべての情報、3 = ジョブ名を持つ実際のフィールド、18 = 部署名など。

私のアイデアは、これらすべての折れ線グラフを 1 つのページに表示して、ジョブの合計と各部門の合計を表示し、タイマーを設定して、スライダー ライブラリなどを使用してすべてのジョブを循環させることでした。

だから今のところ、特定のフィールドを選択して折れ線グラフコンポーネントで使用できるようにコードを書く方法を見つけようとしています。

どんな助けでも大歓迎です!

ありがとう!

更新 ジョブ名と ID を循環させる App.js の最初の API 呼び出しに基づいて、必要な各 ID を選択できるようになりました。そのため、現在表示されている ID は、props として送信され、QuickBase から返されるものを決定する QuickBase API 呼び出しで使用されます。

App.js

import React, { useEffect, useState } from "react";
import './App.css'
import Title from './components/header/Title'
import TotalLineChart from './components/charts/TotalLineChart'
import RadiantLineChart from './components/charts/RadiantLineChart'
import PlumbingLineChart from './components/charts/PlumbingLineChart'
import SnowmeltLineChart from './components/charts/SnowmeltLineChart'
import HVACLineChart from './components/charts/HVACLineChart'
import GasPipeLineChart from './components/charts/GasPipeLineChart'
import FixturesLineChart from './components/charts/FixturesLineChart'
// import TitleCycle from './components/TitleCycle'
// import Logo from './components/Logo';

let headers = {
  "QB-Realm-Hostname": "XXXXXXXXX.quickbase.com",
  "User-Agent": "FileService_Integration_V2.1",
  "Authorization": "QB-USER-TOKEN XXXXXXXX",
  "Content-Type": "application/json",
  "Retry-After": 120000
};

function App() {
  const [allData, setAllData] = useState([]);
  const [index, setIndex] = useState(0);

  // Fetch all data, all jobs
  useEffect(() => {
      function fetchData() {
          let body = {
              from: "bpz99ram7",
              select: [3, 6, 40],
              where: "{40.CT. 'In Progress'}",
              sortBy: [{ fieldId: 6, order: "ASC" }],
              groupBy: [{ fieldId: 40, grouping: "equal-values" }],
              options: { skip: 0, top: 0, compareWithAppLocalTime: false },
          };
          fetch("https://api.quickbase.com/v1/records/query", {
            method: "POST",
            headers: headers,
            body: JSON.stringify(body),
        })
            .then((response) => response.json())
            .then(({ data }) => setAllData(data));
    }
    fetchData();
}, []);

// Cycle through the jobIds and indexes
useEffect(() => {
    const timerId = setInterval(
        () => setIndex((i) => (i + 1) % allData.length),
        5000 // 5 seconds.
    );
    return () => clearInterval(timerId);
}, [allData]);
// console.log(allData)
// console.log(index)
// Calculate info based on index
const jobId = allData[index]?.['3']?.value || '291'; // Default 291
const title = allData[index]?.['6']?.value || 'Default Title'; 
// console.log(jobId)
  return (
      <div>
        {/* <div className="flexbox-container">
          <div className="Logo">
          {/* <Logo /> */}
         {/* </div> */}
        <div className="App">
          <Title title = {title} />
        </div>
        <div className="TopChart">
          <TotalLineChart jobId = {jobId} />
        </div>
        <div className="FirstRowContainer">
          {/* <RadiantLineChart jobId = {jobId} /> */}
          <PlumbingLineChart jobId = {jobId} />
          <FixturesLineChart jobId = {jobId} />
        </div>
        <div className="SecondRowContainer">
          <SnowmeltLineChart jobId = {jobId} />
          <HVACLineChart jobId = {jobId} />
          <GasPipeLineChart jobId = {jobId} />
        </div> 
      </div>
  );
}

export default App;

LineChart.js

import React, { useState, useEffect } from "react";
import { Scatter } from "react-chartjs-2";
// import jobId from '../TitleCycle';
// import Title from '../header/Title';

function TotalLineChart(props) {
  const { jobId } = props;
  // console.log(`${jobId}`)
  const [chartData, setChartData] = useState({});

  const chart = () => {
    let designHours = [];
    let designAmount = [];
    let subRoughHours = [];
    let subRoughAmount = [];
    let roughHours = [];
    let roughAmount = [];
    let finishHours = [];
    let finishAmount = [];
    let closeHours = [];
    let closeAmount = [];
    let actualHours = [];
    let actualAmount = [];

    let headers = {
      "QB-Realm-Hostname": "XXXXXXXX.quickbase.com",
      "User-Agent": "FileService_Integration_V2.1",
      "Authorization": "QB-USER-TOKEN XXXXXXX",
      "Content-Type": "application/json",
      "x-ratelimit-reset": 10000,
      "Retry-After": 30000
    };
    // useEffect(() => {
    //   function fetchData() {
      const body = {
        from: "bpz99ram7",
        select: [
          3,
          88,
          91,
          92,
          95,
          96,
          98,
          104,
          107,
          224,
          477,
          479,
          480,
        ],
        where: `{3.EX. ${ jobId }}`,
        sortBy: [{ fieldId: 6, order: "ASC" }],
        groupBy: [{ fieldId: 40, grouping: "equal-values" }],
        options: { skip: 0, compareWithAppLocalTime: false }
      };
      fetch("https://api.quickbase.com/v1/records/query", {
        method: "POST",
        headers: headers,
        body: JSON.stringify(body)
      })
    //   }
    //   fetchData();
    // }, [])

      .then((response) => response.json())
      .then((res) => {
        // console.log(res);
        Object.keys(res.data).map(jobId => {
          designHours = parseInt(res.data[jobId]['88'].value, 10);
          designAmount = parseInt(res.data[jobId]['91'].value, 10);
          subRoughHours = parseInt(res.data[jobId]['92'].value, 10);
          subRoughAmount = parseInt(res.data[jobId]['95'].value, 10);
          roughHours = parseInt(res.data[jobId]['96'].value, 10);
          roughAmount = parseInt(res.data[jobId]['98'].value, 10);
          finishHours = parseInt(res.data[jobId]['104'].value, 10);
          finishAmount = parseInt(res.data[jobId]['107'].value, 10);
          closeHours = parseInt(res.data[jobId]['477'].value, 10);
          closeAmount = parseInt(res.data[jobId]['480'].value, 10);
          actualHours = parseInt(res.data[jobId]['479'].value, 10);
          actualAmount = parseInt(res.data[jobId]['224'].value, 10);

          setChartData({
            type: 'scatter',
            redraw: true,
              datasets: [
                {
                label: 'TOTAL',
                data: [
                  { x: designHours, y: designAmount },
                  { x: subRoughHours, y: subRoughAmount },
                  { x: roughHours, y: roughAmount },
                  { x: finishHours, y: finishAmount },
                  { x: closeHours, y: closeAmount }
                ],
                borderWidth: 2,
                borderColor: '#4183c4',
                backgroundColor: '#4183c4',
                tension: 0.8,
                spanGaps: true,
                lineTension: 0.5,
                showLine: true,
                fill: false,
                showTooltip: false,
                pointBorderWidth: 1
              },
              {
                label: 'ACTUALS',
                data: [{ x: actualHours, y: actualAmount }],
                fill: false,
                borderColor: '#e34747',
                backgroundColor: '#e34747',
                borderWidth: 3,
                showTooltip: false
              }
            ],
            options: {
              showAllTooltips: true,
              enabled: true,
              maintainAspectRatio: false,
              legend: {  
                display: true
              }
            }
          })
        })
      })
      .catch((err) => {
        console.log(err);
      });
  };

  useEffect(() => {
    chart();
  }, []);

  return (
    <div className="App">
      <div>
        <Scatter 
        // ref={(reference) => this.chartReference = reference } 
          data={chartData}
          options={{
            title: { text: "Total Project", display: false },
            scales: {
              yAxes: [
                {
                  scaleLabel: {
                    display: true,
                    labelString: '$ AMOUNT'
                  },
                  ticks: {
                    autoSkip: true,
                    maxTicksLimit: 10,
                    beginAtZero: true
                  },
                  gridLines: {
                    display: true
                  }
                }
              ],
              xAxes: [
                {
                  scaleLabel: {
                    display: true,
                    labelString: 'HOURS'
                  },
                  gridLines: {
                    display: true
                  }
                }
              ],
            },
          }}
        />
      </div>
    </div>
  );
};

export default TotalLineChart;
4

0 に答える 0