Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
April 17, 2021 05:37 pm GMT

Data visualization: Using amCharts in React.js with Mojo

In my previous article, I talked about using amCharts library with Perl Mojolicious. Today we will looking at creating the similar chart with React.js instead of plain JavaScript. I will keep it short since we already talked about it previously and will be reusing most of the code.

There are 2 ways we can use the react.js -

  1. Without JSX (using tag)
  2. With JSX
  3. JSX stand for JavaScript XML. It allow you to easily write HTML in react.
    For now we will take the baby step and start without JSX.

    Creating the data config

    We will use the exact same example as in previous article and try to create a multi line chart.

    {    "title": "Number of automobiles sold per day by manufacturer",    "label": {        "domainAxis": "Date",        "rangeAxis": "Numbers of automobiles sold"    },    "data": [        {            "Date": "2020-04-15",            "Honda": 10,            "Toyota": 20,            "Ford": 6,            "Renault": 16        },        {            "Date": "2020-04-16",            "Honda": 3,            "Toyota": 15,            "Ford": 19,            "Renault": 10        },        {            "Date": "2020-04-17",            "Honda": 5,            "Toyota": 8,            "Ford": 12,            "Renault": 6        },        {            "Date": "2020-04-18",            "Honda": 9,            "Toyota": 10,            "Ford": 4,            "Renault": 12        }    ]}

    Creating the mojo app

    The version I am using for this article is 9.14.

    $  mojo generate app MojoReactApp

    This command will generate a example application with proper directory structure for a MVC application and mentioned previously.

    Now go inside the dir and try to run this app.

    $ morbo ./script/mojo_appWeb application available at http://127.0.0.1:3000

    Open the browser and hit http://localhost:3000/ and you can see the welcome page.

    The rest of step is exact similar to mention in 'Creating the mojo app' section in previous article. So I will not board you by repeating it again. We will directly see the react part.

    Adding React.js to app

    We will update the default.html.ep to include the react.js

    <!DOCTYPE html><html>    <head>        <meta charset="utf-8" />        <title><%= title %></title>        %= content 'head'    </head>    <body>        <div>            %= content        </div>        <script src="https://unpkg.com/react@17/umd/react.production.min.js" crossorigin></script>        <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js" crossorigin></script>        %= content 'end'    </body></html>

    We are using the production minified version. You can also use the development version also for debugging purpose.
    I have added react.js on layout template as we will be using it all our web pages.

    In multi_line_chart.html.ep

    % layout 'default';% title 'Charts';% content_for 'head' => begin    <link rel="stylesheet" type="text/css" href="css/charts.css">% end<div id="root"></div>% content_for 'end' => begin    %= javascript "https://cdn.amcharts.com/lib/4/core.js"    %= javascript "https://cdn.amcharts.com/lib/4/charts.js"    %= javascript "https://cdn.amcharts.com/lib/4/themes/animated.js"    %= javascript "js/multi_line_chart.js"    %= javascript begin         var domContainer = document.getElementById("root");        createMultiLineChart(domContainer, <%== $chart_data %>);    % end% end

    We are geeting the $chart_data form create_multi_line_chart in lib\MojoReactApp\Controller\Charts.pm when the template get rendered.
    Lets update the public/js/multi_line_chart.js to make it a React Component.

    "use strict";// React without JSXconst e = React.createElement;class MultiLineChart extends React.Component {    constructor(props) {        super(props);        this.state = {            chartId: this.props.chartId,            chartData: this.props.data,        };    }    createSeries = (chart, axis, field, name) => {        // Create series        var series = chart.series.push(new am4charts.LineSeries());        series.dataFields.dateX = "Date";        series.dataFields.valueY = field;        //series.dataFields.categoryX = "Date";        series.strokeWidth = 2;        series.xAxis = axis;        series.name = name;        series.tooltipText = "{name}: [bold]{valueY}[/]";        //series.fillOpacity = 0.8;        // For curvey lines        series.tensionX = 0.8;        series.tensionY = 1;        // Multiple bullet options - circle, triangle, rectangle etc.        var bullet = series.bullets.push(new am4charts.CircleBullet());        bullet.fill = new am4core.InterfaceColorSet().getFor("background");        bullet.fillOpacity = 1;        bullet.strokeWidth = 2;        bullet.circle.radius = 4;        return series;    };    createChart = (chart) => {        // Increase contrast by taking evey fouth color        chart.colors.step = 4;        //chart.hiddenState.properties.opacity = 0;             // this creates initial fade-in        // Add title to chart        var title = chart.titles.create();        title.text = this.state.chartData["title"];        title.fontSize = 25;        title.marginBottom = 15;        chart.data = this.state.chartData["data"];        // Create axes - for normal Axis        // var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());        // categoryAxis.dataFields.category = "Date";        // categoryAxis.renderer.grid.template.location = 0;        // Create axes - for Date Axis        var dateAxis = chart.xAxes.push(new am4charts.DateAxis());        //dateAxis.dataFields.category = "Date";        dateAxis.renderer.grid.template.location = 0;        dateAxis.renderer.minGridDistance = 50;        dateAxis.title.text = this.state.chartData["label"]["domainAxis"];        var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());        //valueAxis.renderer.line.strokeOpacity = 1;        //valueAxis.renderer.line.strokeWidth = 2;        valueAxis.title.text = this.state.chartData["label"]["rangeAxis"];        //var single_data_item = this.state.chartData["data"][0];        var series1 = this.createSeries(chart, dateAxis, "Toyota", "Toyota");        var series2 = this.createSeries(chart, dateAxis, "Ford", "Ford");        var series3 = this.createSeries(chart, dateAxis, "Honda", "Honda");        var series4 = this.createSeries(chart, dateAxis, "Renault", "Renault");        // Add legend        chart.legend = new am4charts.Legend();        // Add cursor        chart.cursor = new am4charts.XYCursor();        chart.cursor.xAxis = dateAxis;        // Add scrollbar        chart.scrollbarX = new am4core.Scrollbar();        // Add export menu        chart.exporting.menu = new am4core.ExportMenu();    };    componentDidMount() {        am4core.useTheme(am4themes_animated);        const chart = am4core.create(this.state.chartId, am4charts.XYChart);        this.createChart(chart);        this.chart = chart;    }    componentWillUnmount() {        if (this.chart) {            this.chart.dispose();        }    }    render() {        return e("div", { id: this.state.chartId }, null);    }}function createMultiLineChart(domContainer, chartData) {    ReactDOM.render(        e(MultiLineChart, { chartId: "chartdiv", data: chartData }, null),        domContainer    );}

    We are calling the createMultiLineChart function from our template with parameters. The main point to know here is the state and lifecycle functions - componentDidMount and componentWillUnmount.
    Since there are already plenty of documentation available, I encourage you to look into it. One of the place to learn the concept is react official docs- State and Lifecycle

    If you look closely the rest of function definition is not much changes from the previous used javascript. We just wrapped it in react.

    The final directory structure is -

    mojo_react_app
    etc
    input_data.json
    lib
    MojoReactApp
    Controller
    Charts.pm
    Model
    Data.pm
    MojoReactApp.pm
    public
    css
    charts.css
    js
    multi_line_chart.js
    script
    mojo_react_app
    t
    basic.t
    templates
    charts
    multi_line_chart.html.ep
    layouts
    default.html.ep
    mojo_react_app.yml
    README.md

    Save it and try to hit 'http://localhost:3000' again. From the user perspective side nothing has changed, you will see the same output as before.
    fi7og88vjcasg4ishx45

    As I mentioned before we will starting with baby step.
    The usage of the above mentioned way is very limited. You can use the react.js without jsx when your scope is small - where you have to make a website of few pages because here we are not using the full power of react.
    To use the react.js with full potential and unleash its power you have to use jsx. We will be looking in to it our next article.

    The above example is available at github.

    Perl onion logo taken from here
    Mojolicious logo taken from here
    React logo taken from here
    amCharts logo taken form here


Original Link: https://dev.to/raigaurav/data-visualization-using-amcharts-in-react-js-with-mojo-29mh

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To