0

このAPI呼び出しでデータポイントを呼び出す方法について何か助けが得られるかどうかを知りたかったのですが、これは数値の配列であるため、フィールド値は6になる可能性があります.しかし、画面に何もロードすることはできません. Loading... when null を取得しているため、呼び出しは機能していますが、その後は消えて何も表示されません。Number をデータに割り当てようとすると、認識されないと表示されます。

import React, { Component } from 'react'

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

class JobsTableApi extends Component {
  state = {
    data: null,
  }

  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["3"]}</div>
    )
  }
}

export default JobsTableApi;

API データ 例:

{
    "data": [
        {
            "3": {
                "value": 43
            },
            "18": {
                "value": "Radiant"
            },
            "20": {
                "value": null
            },
            "144": {
                "value": null
            },
            "145": {
                "value": 33230
            },
            "171": {
                "value": 8
            },
            "172": {
                "value": 228
            },
            "174": {
                "value": 270
            },
            "212": {
                "value": 0
            },
            "215": {
                "value": 8.34487776140499
            },
            "216": {
                "value": 16.34487776140499
            },
            "217": {
                "value": 244.344877761405
            },
            "218": {
                "value": 572.3449342166289
            },
            "219": {
                "value": 842.3449342166289
            },
            "220": {
                "value": 861.8163156599072
            },
            "221": {
                "value": 877.8106647026001
            },
            "222": {
                "value": 0
            },
            "223": {
                "value": 239.256
            },
            "227": {
                "value": 5050.96
            },
            "230": {
                "value": 239.256
            },
            "231": {
                "value": 239.256
            },
            "232": {
                "value": 17339.414
            },
            "233": {
                "value": 26743.504
            },
            "234": {
                "value": 22390.374
            },
            "235": {
                "value": 22948.638
            },
            "236": {
                "value": 23407.212
            },
            "244": {
                "value": 0
            },
            "249": {
                "value": 0
            },
            "322": {
                "value": 870.6260000000001
            },
            "325": {
                "value": 17100.158
            },
            "338": {
                "value": ""
            },
            "349": {
                "value": 8
            },
            "350": {
                "value": 0
            },
            "351": {
                "value": 220
            },
            "366": {
                "value": 0
            },
            "438": {
                "value": null
            },
            "513": {
                "value": 278
            },
            "516": {
                "value": 23261
            },
            "517": {
                "value": 17339.414
            }
        }

更新: {jobId} を App.js のプロップとして設定できます。これは折れ線グラフの親であるため、ここに真実が必要です。次に、これを各折れ線グラフに送信してプルベースにすることができますAPI 呼び出しの結果を決定するタイトル (および ID) が表示されます。

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": "XXXXXX.quickbase.com",
  "User-Agent": "FileService_Integration_V2.1",
  "Authorization": "QB-USER-TOKEN XXXXXXX",
  "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": "XXXXXXXXXX.quickbase.com",
      "User-Agent": "FileService_Integration_V2.1",
      "Authorization": "QB-USER-TOKEN XXXXXXXXXXX",
      "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;

ご覧のとおり、API は App.js から取得された {jobId} の「#」ID を取得しています。これは、API 本体でも確認できます。

4

0 に答える 0