javascriptamcharts

Amcharts v3 multiple inline JSON data for one chart


I measure amount of coal in a stack of my automatic coal boiler. Measurements does OrangePI with ultrasonic sensor, and it sends data to MYSQL server. There I have a webpage, which shows me chart with 14 days history. Here I can see, how much coal I have in stack and how fast it wanes.

Chart is done by Amchart serial chart. It works nicely. Data are inline in page in JSON:

var chartdataNasypka = [{"datumcas":"2022-12-04 00:00","vyskauhli":"41"},{"datumcas":"2022-12-04 01:00","vyskauhli":"43"},.........]

(measures once an hour)

Now I had an idea, that it will be nice to see a curve of outdoor temperature-in a same chart, both values combined in one chart. I have a weather station on Raspberry PI, sending data again to MYSQL, but to another table. I tuned out a SELECT command, so I have same datetime format:

var chartdataMeteostanice = [{"datumcas":"2022-12-04 00:00","teplota":"-0.2"},{"datumcas":"2022-12-04 01:00","teplota":"0.0"},.........]

The trouble is, that both values (coal height in stack and outdoor temperature) cannot be visualised at once in one chart. It shows data from one database only, depends which from the following lines are last:

                chart.dataProvider = chartdataMeteostanice;
                chart.dataProvider = chartdataNasypka;

I don't know, how to specify data provider for valueAxisY2. I googled for a few hours, but found only switching charts by data sets, but this is not my case, I want to see everything without switching.

I would like to avoid merging both JSON data into one, as there may be outage of one sensor/data and it may be merged/visualised incorrectly.

So is there a way, how to solve it? I have Amcharts v3, but I can update it to the current v5, if needed.

Thank you

Code I have now:

            AmCharts.ready(function () {

                // SERIAL CHART
                chart = new AmCharts.AmSerialChart();
                chart.pathToImages = "amcharts/images/";
                chart.borderColor = "#000000";
                chart.borderAlpha = 0.15;
                chart.zoomOutText = "Ukaž vše";              
                chart.dataProvider = chartdataMeteostanice;
                chart.dataProvider = chartdataNasypka;
                
                chart.categoryField = "datumcas";
                chart.dataDateFormat = "YYYY-MM-DD JJ:NN";
                chart.numberFormatter = {precision:-1,decimalSeparator:"."};                 
                
                var balloon = chart.balloon;
                balloon.fillAlpha = 1;
                balloon.cornerRadius = 2;
                balloon.showBullet = true;

                // AXES
                // DATUM
                var categoryAxis = chart.categoryAxis;
                categoryAxis.parseDates = true;
                categoryAxis.minPeriod = "hh"; 
                categoryAxis.gridAlpha = 0.2;
                categoryAxis.axisColor = "#DADADA";
                categoryAxis.autoGridCount = true;
                categoryAxis.equalSpacing = false;
                categoryAxis.startOnAxis = true;
                categoryAxis.centerLabels=false;

                // VÝŠKA UHLÍ
                var valueAxis = new AmCharts.ValueAxis();
                valueAxis.axisAlpha = 1;                
                valueAxis.gridCount = 12;
                valueAxis.autoGridCount = false;
                valueAxis.gridAlpha = 0.2;
                valueAxis.minimum = 0;
                valueAxis.maximum = 120;
                valueAxis.unit = "cm";
                valueAxis.title = "Výška uhlí";
                valueAxis.position = "left";
                chart.addValueAxis(valueAxis);
                
                // TEPLOTA                
                var valueAxisY2 = new AmCharts.ValueAxis();
                valueAxisY2.axisAlpha = 1;
                valueAxisY2.gridCount = 10;
                valueAxisY2.gridAlpha = 0;
                valueAxisY2.minimum = -20;
                valueAxisY2.maximum = 20;                              
                valueAxisY2.unit = "°C";
                valueAxisY2.title = "Teplota";
                valueAxisY2.autoGridCount = false;
                valueAxisY2.position = "right";
                chart.addValueAxis(valueAxisY2);
                

                // GRAPH - VÝŠKA UHLÍ
                var graphu = new AmCharts.AmGraph();
                graphu.type = "line";
                graphu.title = "Výška uhlí";
                graphu.valueField = "vyskauhli";
                graphu.lineAlpha = 1;
                graphu.lineColor = "#502000";
                graphu.fillAlphas = 0.7; // setting fillAlphas to > 0 value makes it area graph
                graphu.connect = false;  // když chybí hodnoty, nenapojuje
                chart.addGraph(graphu);

                // GRAPH - TEPLOTA
                var grapht = new AmCharts.AmGraph();
                grapht.type = "line";
                grapht.title = "Teplota";
                grapht.valueField = "teplota";
                grapht.lineAlpha = 1;
                grapht.lineColor = "#FF0000";
                grapht.negativeLineColor = "#0080FF";
                grapht.fillAlphas = 0; // setting fillAlphas to > 0 value makes it area graph
                grapht.connect = false;  // když chybí hodnoty, nenapojuje
                grapht.bullet = "round";
                grapht.bulletBorderColor = "#FFFFFF";
                grapht.bulletBorderThickness = 2;
                grapht.bulletBorderAlpha = 1;
                grapht.lineThickness = 3;
                grapht.balloonText = "<b><span style='font-size:11px;'>teplota: [[value]]°C</span></b>";
                grapht.balloonAlpha = 1;                
                grapht.hideBulletsCount = 20; // this makes the chart to hide bullets when there are more than 50 series in selection
                chart.addGraph(grapht);
                

                // CURSOR
                var chartCursor = new AmCharts.ChartCursor();
                chartCursor.cursorPosition = "mouse";
                chartCursor.categoryBalloonDateFormat = "JJ:NN, DD.MM.YYYY";
                chart.addChartCursor(chartCursor);

                // SCROLLBAR
                var chartScrollbar = new AmCharts.ChartScrollbar();
                chart.addChartScrollbar(chartScrollbar);

                // WRITE
                chart.write("chartdiv");
            });

webpage screenshot


Solution

  • So, it seems that the best option is to merge both JSONs into one, then sort it.
    Described here

    Then the part of that code is:

    var uhliateplota = <?
    $merged_array = array_merge($datauhli, $datateplota);
    // $datauhli and $datateplota holds values from SQL requests
    echo json_encode($merged_array);
    ?>
    
    // Sort:
    uhliateplota.sort((a, b) => new Date(a.datumcas) - new Date(b.datumcas))
    // datumcas means datetime
    
    var chartdataSPOJENA = []
    uhliateplota.forEach(function(e) {
      if(!this[e.datumcas]) {
        this[e.datumcas] = {datumcas: e.datumcas, vyskauhli: null, teplota: null}
        chartdataSPOJENA.push(this[e.datumcas])                                             
      }
      this[e.datumcas] = Object.assign(this[e.datumcas], e)
    })
    
    var JSONdata = (JSON.stringify(chartdataSPOJENA, 0, 4))
    // document.write(JSONdata)
    
    
    
    
                AmCharts.ready(function () {
    
                    // SERIAL CHART
                    chart = new AmCharts.AmSerialChart();
                    chart.pathToImages = "amcharts/images/";
                    chart.borderColor = "#000000";
                    chart.borderAlpha = 0.15;
                    chart.zoomOutText = "Show All";              
                    chart.dataProvider = chartdataSPOJENA;