2

I am trying to use this 3D gio visualization into my ReactJs application. The code is written in vanilla JavaScript. I have also found wrapper for React and tried it but I am not able to pick the selected country(onCountryPicked()) as it is shown on their demo. That is the main reason I go ahead with the vanilla JavaScript implementation instead of wrapper. However, I find the vanilla JavaScript implementation difficult to integrate with my ReactJs application.

I have looked around to solve the issue but the resources I have found did not help me. The bellow are some of the places I have visited.

helloworld.js

var container = document.getElementById("globalArea");

var controller = new GIO.Controller(container, {
  color: {...},
  brightness: {...},
});

controller.onCountryPicked(callback);
controller.setInitCountry("FR");
controller.showOutOnly(false);
controller.showInOnly(false);

function callback(selectedCountry) {
  $("#countryArea").text(selectedCountry.name + " picked!");
  $("#infoBoard").fadeIn(300);
  setTimeout(function () {
    $("#infoBoard").fadeOut(1000);
  }, 3000);
}

axios
  .get("./test_data.json")
  .then(function (response) {
    controller.addData(response.data);
  })
  .catch(function (error) {
    console.log(error);
  })
  .then(function () {
    controller.init();
  });

var d3Graphs = {
  tiltBtnInterval: -1,
};

function showHud() {
  $("#hudButtons").show();
  $(".tiltBtn").on("mousedown touchstart", d3Graphs.tiltBtnClick);
  $(".tiltBtn").on("mouseup touchend touchcancel", d3Graphs.tiltBtnMouseup);
}

function tiltBtnClick() {
  var delta;
  if ($(this).hasClass("sideViewBtn")) {
    delta = 10;
  } else {
    delta = -10;
  }
  d3Graphs.doTilt(delta);
  d3Graphs.tiltBtnInterval = setInterval(d3Graphs.doTilt, 50, delta);
}

function doTilt(delta) {
  tilt += delta * 0.01;
  tilt = constrain(tilt, 0, Math.PI / 2);
  camera.position.y = 300 * Math.sin(-tilt);
  camera.position.z = 100 + 300 * Math.cos(-tilt);
  camera.lookAt(new THREE.Vector3(0, 0, 300));
  tiltTarget = undefined;
}

............

home.html

<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <script src="./lib/jquery-3.3.1.min.js"></script>
    <script src="./lib/three.min.js"></script>
    <script src="./lib/gio.min.js"></script>
    <script src="./lib/axios.min.js"></script>
    <script src="https://d3js.org/d3.v5.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
    <link rel="stylesheet" href="helloworld.css" />
  </head>

  <body>
    <div class="b">
      <div id="infoBoard">
        <div id="countryArea"></div>
        <div id="explanation">Infos here</div>
      </div>
      <script src="helloworld.js"></script>
    </div>
  </body>
</html>

................

Sample.js

export class Sample extends React.Component {
  componentDidMount() {
  
  }

  render() {
    return (
      <div className="App">
         ...
      </div>
    );
  }
}

2 Answers 2

4
+50

Here's a starting point. I've annotated the parts where React interacts with Gio.js.

const Globe = () => {
  // use a React ref whenever you need to directly target a DOM element
  // - this is required as an argument to the GIO.Controller constructor
  const ref = useRef(null);
  const [country, setCountry] = useState(initCountry);

  useEffect(() => {
    // useEffect with empty dependency array
    // - this will run once when the component mounts
    const controller = new GIO.Controller(ref.current, {
      control: {
        initCountry
      }
    });

    // import and add data here if you want the glowing lines
    controller.addData([]);

    controller.init();

    // here's the callback for when the user clicks a country
    // we can use the React setState hook inside the callback
    controller.onCountryPicked((country) => {
      setCountry(country.ISOCode);
    });
  }, []);

  return (
    <>
      <div>
        <strong>Selected country: {displayName.of(country)}</strong>
      </div>
      <div style={{ height: 500 }} ref={ref}></div>
    </>
  );
};

CodeSandbox demo

Sign up to request clarification or add additional context in comments.

2 Comments

Let's say I have this button<Button color="primary"onClick={() => {..}}>Show Lines</Button>I want to show the glowing lines only when this button is pressed. How that can be achieved?...It would also be great if you could show how to customize the color of the glowing lines
I've updated the CodeSandbox with a demo for toggling lines. The colors blue vs. orange/red correspond to the directionality of the data (see giojs.org/html/docs/dataAdd.html), and as for changing colors in general, you can start with giojs.org/html/docs/colorIntro.html
0

If you put your vanilla javascript file on the same hierarchical level as your index.html and link it normally you should be able to implement your vanilla javascript without interfering with your react javascript. Just link it down at the bottom like normal with a <script> tag.

Alternatively, to use useState in you react code:

import React, {useState} from "react";
import ReactDOM from "react-dom";

const Country = () => {
  const [country, setCountry] = useState('');

  ///your javascript here

  setCountry(//return from javascript function// );

  return (
     <h1>{country}</h1>
  )
}

ReactDOM.render(<Country/>, document.getElementById("countryArea"));

You will need to import any additional dependencies for your vanilla javascript (ex. axios) into this file.

6 Comments

I want to pass data from vanilla Javascript to ReactJs. For example, when ever the user clicks specific country on 3D map, I would like to pass the name of the selected country to ReactJs component. Any idea how can I achieve that?
Well you can use vanilla javascript in your react js file. Sounds like a case for useState in functional component react, otherwise you'd have to use a constructor function (since you are using class components) to set the state.
Can you show with example how it can be used in state or useState?
Updated my answer
Do I have to wrap the entire vanilla JavaScript code as it contains multiple functions as well as the promise, axions ? How do I use Gio.Controller in your proposed solution?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.