neuhausi / canvasxpress-react

React package to run CanvasXpress
https://www.canvasxpress.org
2 stars 4 forks source link

Unable to specify position of Plot component. #7

Closed SunnyMug closed 1 month ago

SunnyMug commented 1 month ago

Hi there, I am trying to display a TPMplot.jsx generated by CanvasXpress onto a webpage. It is displayed correctly but I cannot seem to change its positioning in relation with other components on the page with CSS. When wrapping the plot component in a \

with borders and the text "Hello", this is what is displays: image_2024-07-16_214711506 The plot does not appear to be affected by any sort of styling or HTML tags around it. In addition, when the window is minimised, the plot is moved to its own newline instead of staying in place. image

TPMplot.jsx is currently implemented using the scaffold provided in the documentation of canvasxpress-react. This is the return statement for it: image

I have had a further look into the documentation on CanvasXpress.org but it only seems to have information on how to display and position a plot in a DOM context instead of utilising React. Upon attempting to change my implementation using that information, I received a "TypeError: canvasxpressWEBPACK_IMPORTED_MODULE1default(...) is not a constructor" at line 122 of this code snippet: image

What is the correct way of displaying a CanvasXpress plot on a webpage, where it is constrained within \

and its position can be specified? I do not have much experience in frontend development so it I apologise if I get any concepts or code wrong.

Thank you so much for your time and effort in advance!

neuhausi commented 1 month ago

Can you upload the complete web page so I can recreate it Thank you

SunnyMug commented 1 month ago

Hi!

I've forked the repo and added you as a collaborator. The main branch should contain the app where the plot is displayed but its position is not able to be specified or enclosed in a div. The Branch 'SC-layout' contains the attempted solution that throws the "TypeError: canvasxpressWEBPACK_IMPORTED_MODULE1default(...) is not a constructor" error. The code snippets are from frontend/components/Tpm.jsx and this component is called in App.js.

Thank you so much!

neuhausi commented 1 month ago

I clone the repo and followed the instructions but I don't know how to see the page in question

SunnyMug commented 1 month ago

Apologies for that! I have updated the instructions to guide you on how to display the plot on the question.

neuhausi commented 1 month ago

The CanvasXpress object is being inserted in the body and not in the target container. Also the is a warning in the console saying "React does not recognize the data-aspectRatio prop on a DOM element" which maybe the reason this is happening? I will disable that in the new version so we can test. Unfortunately I don't know React so I don't know how else to help since the CanvasXpress library is working correctly.

neuhausi commented 1 month ago

Here is the whole code for the React component. Is there anything wrong?

var React = require('react');
var CanvasXpress = require('canvasxpress');
require('canvasxpress/src/canvasXpress.css');

class CanvasXpressReact extends React.Component {

  constructor(props) {
    super(props);
    this.target = props.target ? props.target : false;
    this.data   = props.data ? props.data : false;
    this.config = props.config ? props.config : false;
    this.events = props.events ? props.events : false;
    this.width  = props.width ? props.width : 500;
    this.height = props.height ? props.height : 500;
    this.responsive = props.responsive ? props.responsive : false;
    this.aspectRatio = props.aspectratio ? props.aspectratio : "1:1";
  }

  componentDidMount() {
    //Create graph and render
    this.graph = new CanvasXpress.init(this.target, this.data, this.config, this.events);
    if (this.props.onRef) {
      this.props.onRef(this.graph);
    }
  }

  shouldComponentUpdate(nextProps, nextState){
    //Check if graph config and data has changed and determine if component has to be updated
    return !(nextProps.data === this.data && nextProps.config === this.config);
  }

  componentDidUpdate() {
    //Update Graph Options & Data
    this.graph.resetConfig();
    this.graph.updateConfig(this.props.config);
    this.graph.updateData(this.props.data);
  }

  componentWillUnmount() {
    //Destroy graph and remove reference
    this.graph.destroy();
    if (this.props.onRef) {
      this.props.onRef(undefined);
    }
  }

  render() {
    return React.createElement('canvas', { id: this.target, width: this.width, height: this.height, 'data-responsive': this.responsive, 'data-aspectratio': this.aspectratio});
  }

}

export default CanvasXpressReact;
neuhausi commented 1 month ago

I think the problem is that you are not including a target id for CanvasXpress to find the place where it will be inserted. I don't think there is anything wrong with the implementation

SunnyMug commented 1 month ago

Thanks for your help! Did it end up working correctly with the new version? It looks like to me that the code snippet you sent looks fine as well honestly i'm also not too familiar with React. In regards to me not including a target ID for CanvasXpress, I've attempted a solution in the branch 'SC-layout' which displayed a "TypeError: canvasxpressWEBPACK_IMPORTED_MODULE1default(...) is not a constructor" error. Could you see if I did not do the implementation correctly there?

neuhausi commented 1 month ago

Yes. I cloned the repo and worked correctly. I will take another look later today.

neuhausi commented 1 month ago

Try to include this in your App.js file which tells React where to insert the graph

import ReactDOM from 'react-dom';

....

var reactapp = document.createElement("div");
document.body.appendChild(reactapp);
ReactDOM.render(<Bar />, reactapp)
SunnyMug commented 1 month ago

Hey Issac! Thank you for all your help! It ended up working by replacing the default 'create-react-app' template in index.js with 'ReactDOM.render(, reactapp)' and changing the plot component into a class component. I'm now able to reposition the plot anywhere on the page with divs.

Just one more question though! I noticed that even when the plot is within a container, it can still be resized beyond the container. Is there a way to disable this feature or limit the resizing area?

Thank you so much again!