Apex chart doesn't display immediately

Viewed 1717

I have the following code for a apex chart to be displayed based on value

import React, { Component, Fragment,useState } from "react";

import RestAPI from "services/api";
import axios from "axios";
import Select from 'react-select';
import "d3-transition";
import "tippy.js/dist/tippy.css";
import "tippy.js/animations/scale.css";


/* Chart code */
// Themes begin
// Themes end
import {
    Button,
    Label,
    FormGroup,
    Form,
   
  } from "reactstrap";
import ReactApexChart from "react-apexcharts";
import Loader from "react-loader-spinner";

class BarChart extends Component {
  constructor(props){
    super(props);
    this.selectValue=this.selectValue.bind(this)
    this.state = {
        selectValue:"",
        items:[],
        weights:[],
        isLoaded:true,
        showViz:false,
          
        series: [],
        options: "",
      
      
      };
    }

 
   
    
 
  selectValue (e) {
    var selectValue=this.state.selectValue;
    selectValue=e.value;
    fetch("http://127.0.0.1:8000/api/values/"+selectValue)
    .then(response =>  response.json())
    .then(json => {
        this.state.series=[]
        var {items,weights}=this.state;
        this.setState({
          isLoaded:true,
          items:json.keywords,
          weights:json.weights,
          
          series: [{ name: "Keywords", data: weights }],
          options:{
            chart: {
              type: 'bar',
              
            },
            title:{
                text:"Top 10 values"
            },
            plotOptions: {
                bar: {
                  horizontal: true,
                }
              },
              xaxis:{
                categories: items
              },
              grid: {
                xaxis: {
                  show:false,
                  lines: {
                    show: false
                  },
                  axisTicks:{
                      show:false,
                      offsetX: 0,
                      offsetY: 0
                  },
                  axisBorder:{
                      show:false
                  }
                }
              },
              yaxis: {
                reversed: false,
                axisTicks: {
                  show: false
                }
              }
          },
          
          
          
        })            
    });
    this.state.showViz=true;
  }
  
     
 
      render() {

        var {selectValue,items,weights,isLoaded,options,series,showViz}=this.state;
        
        
        const yeardata = [
            {
              value: "1",
              label: "1"
            },
            {
              value: "2",
              label: "2"
            },
            {
              value: "3",
              label: "3"
            },
            {
              value: "4",
              label: "4"
            },
            {
              value: "5",
              label: "5"
            },
            {
              value: "6",
              label: "6"
            },
            {
              value: "7",
              label: "7"
            },
            {
              value: "8",
              label: "8"
            },
            {
              value: "9",
              label: "9"
            },
            {
              value: "10",
              label: "10"
            }
          ];
       
        
        
        
        
        //var{items,arr_keys,arr_vals}=this.state;
        


        
        
        
    if(isLoaded){   
        
          return (
            <>
          
           { console.log("the values are:",items)}
           { console.log("the values are:",weights)}
           { console.log("the values are:",options)}
           { console.log("the values are:",series)}
            <Form role="form" >
                        
                        
                        <FormGroup>
                        <h2>Top 10 values</h2>
                        <Label>Select an Value</Label>
                        <Select  placeholder="Select Option" options={yeardata}  value={yeardata.find(obj => obj.value === selectValue)} 
                         onChange={this.selectValue}
                         />
        
                            <br></br>
                        {this.state.showViz?(
                        <ReactApexChart options={this.state.options} series={this.state.series} type="bar" height={250} />):
                        (<Loader type="Puff">
                          </Loader>)}
                        </FormGroup>
              </Form>
 
                
              
            </>
          );
          
      
          }   
        else{
            return(
               <>
            
               </> 
            )
        }
       
      }
}

export default BarChart;

I want to display the chart when I select a value,but it is not displaying.Instead if I select another value,the previous value is displayed.Also,initially a blank plot is rendered which I don't want.Also,the loader is displayed as soon as the page is loaded which I want to avoid too.How could I resolve this? Screenshot of rendered image: Empty Chart

1 Answers
  1. You never set isLoaded false, so it's always true. You need to set isLoaded to false in constructor and after you receive response - true:

  2. React state is async, you can't set a value just like this this.state.showViz=true; , you need to use this.setState each time you want to change your state and don't forget to put all other state data

    this.setState({...this.state, showViz: true});

And as I've understood your logic correctly you need to put this code inside last .then:

this.setState({
  isLoaded:true,
  items:json.keywords,
  weights:json.weights,
  showViz: true,
  ...
  1. You never set selectValue, so you don't need this code var selectValue=this.state.selectValue

Final code:

import React, { Component, Fragment, useState } from "react";

import RestAPI from "services/api";
import axios from "axios";
import Select from "react-select";
import "d3-transition";
import "tippy.js/dist/tippy.css";
import "tippy.js/animations/scale.css";

/* Chart code */
// Themes begin
// Themes end
import { Button, Label, FormGroup, Form } from "reactstrap";
import ReactApexChart from "react-apexcharts";
import Loader from "react-loader-spinner";

class BarChart extends Component {
  constructor(props) {
    super(props);
    this.selectValue = this.selectValue.bind(this);
    this.state = {
      selectValue: "",
      items: [],
      weights: [],
      isLoaded: true,
      showViz: false,

      series: [],
      options: "",
    };
  }

  selectValue(e) {
    var selectValue = this.state.selectValue;
    selectValue = e.value;
    fetch("http://127.0.0.1:8000/api/values/" + selectValue)
      .then((response) => response.json())
      .then((json) => {
        var { items, weights } = this.state;

        this.setState({
          isLoaded: true,
          items: json.keywords,
          weights: json.weights,
          showViz: true,
          series: [
            {
              name: "Keywords",
              data: weights,
            },
          ],
          options: {
            chart: {
              type: "bar",
            },
            title: {
              text: "Top 10 values",
            },
            plotOptions: {
              bar: {
                horizontal: true,
              },
            },
            xaxis: {
              categories: items,
            },
            grid: {
              xaxis: {
                show: false,
                lines: {
                  show: false,
                },
                axisTicks: {
                  show: false,
                  offsetX: 0,
                  offsetY: 0,
                },
                axisBorder: {
                  show: false,
                },
              },
            },
            yaxis: {
              reversed: false,
              axisTicks: {
                show: false,
              },
            },
          },
        });
      });
  }

  render() {
    var {
      selectValue,
      items,
      weights,
      isLoaded,
      options,
      series,
      showViz,
    } = this.state;

    const yeardata = [
      {
        value: "1",
        label: "1",
      },
      {
        value: "2",
        label: "2",
      },
      {
        value: "3",
        label: "3",
      },
      {
        value: "4",
        label: "4",
      },
      {
        value: "5",
        label: "5",
      },
      {
        value: "6",
        label: "6",
      },
      {
        value: "7",
        label: "7",
      },
      {
        value: "8",
        label: "8",
      },
      {
        value: "9",
        label: "9",
      },
      {
        value: "10",
        label: "10",
      },
    ];

    if (isLoaded) {
      return (
        <>
          {console.log("the values are:", items)}
          {console.log("the values are:", weights)}
          {console.log("the values are:", options)}
          {console.log("the values are:", series)}
          <Form role="form">
            <FormGroup>
              <h2> Top 10 values </h2> <Label> Select an Value </Label>
              <Select
                placeholder="Select Option"
                options={yeardata}
                value={yeardata.find((obj) => obj.value === selectValue)}
                onChange={this.selectValue}
              />
               </br>
              {this.state.showViz ? (
                <ReactApexChart
                  options={this.state.options}
                  series={this.state.series}
                  type="bar"
                  height={250}
                />
              ) : (
                <Loader type="Puff"></Loader>
              )}
            </FormGroup>
          </Form>
        </>
      );
    } else {
      return <></>;
    }
  }
}
Related