How to edit ui_chart to be without labels and have last value displayed

So i think this is the last challenge to my dashboard. I wnat a mini chart, like you can do in excel, without any labels (the display of x and y values) and have a big number in the center with the latest value of that chart something like this:
image

Pushing nr dashboard to the limits. And may be a little over. I'm not going to say it's impossible but can't see any easy way to achieve such thing also. I'm not smartest guy on topic anyway so just good luck. Going to follow up the solution if any.

Lmao, i know right. But that s the fun thing about NR Dash imo. It is quite simple to use, but at the same time, if you know how to, you can do amazing tricks.

BTW, I building a chart with ui_template is also ok. I just dom't really know how to do that, so if someone can give me some light.

If the line can be as value trail (no time component involved) then I can add option to https://flows.nodered.org/node/node-red-contrib-ui-value-trail

1 Like

As I found the idea reasonable enough, the option to show last value is added.
v0.2.0 published

1 Like

If only i could use stored data with it, it would be perfect. I query the values and the time, and then i plot a chart. In a aesthetic sense thats exactly what i'm looking for, but I need to show the last 24 hours of data.

But maybe this is an option for now

Yes, the value trail will never get the time scales.
You can show historical data by just feeding all data points in order but that's all. And if there will be too many data points, the older points will be removed. And you have very little control over it.
Tricky widget, more or less targeted for live data.

And many thanks, the idea was great.

I 'll try to see if there is any way to achieve something with the chartjs and ui_temple somehow

Well, i guess this will suffice. For now i'm reseting it all the time cause i'm still developing the dashboard, but at some point it will run without inturruptions for months. So i guess this will do the trick even tho it is not EXACTLY what I wanted. THANKS!!!

Ok, I just realized i can't have a label name or unit. Is there any way to edit it?

Not currently. May be added.

Ok! i will keep looking, then. For now I will just display last value. Thanks!

But I just did this :smiley:

image

[{"id":"821cef66.60aa8","type":"ui_template","z":"bf66f153.dd752","group":"195db59f.44875a","name":"Line Chart","order":4,"width":"8","height":"5","format":"","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":590,"y":420,"wires":[[]]},{"id":"e57aac9d.c6f3b","type":"inject","z":"bf66f153.dd752","name":"","topic":"","payload":"","payloadType":"date","repeat":"2","crontab":"","once":false,"onceDelay":"0.62","x":230,"y":370,"wires":[["96676de2.6bd3b"]]},{"id":"96676de2.6bd3b","type":"function","z":"bf66f153.dd752","name":"fake live data","func":"msg.payload = {}\nmsg.payload.first = Math.random() * 300\nmsg.payload.second = -2.5 + Math.random() * 5\nreturn msg;\n","outputs":1,"noerr":0,"x":390,"y":370,"wires":[["821cef66.60aa8"]]},{"id":"db64afe.49ae05","type":"template","z":"bf66f153.dd752","name":"","field":"template","fieldType":"msg","format":"html","syntax":"mustache","template":"<canvas id=\"myChart\"></canvas>\n<div id=\"myValue\"></div>\n<style>\n    #myValue{\n       position: absolute;\n        left: 125px;\n        top: 100px;\n        text-align: center;\n        font-size: 60px;\n        font-weight: bold;\n    }\n    #myChart{\n        position:absolute;\n        top:20px;\n    }\n    \n</style>\n<script>\n\nvar maxDataPoints = 20\n\nvar ctx = document.getElementById('myChart').getContext('2d');\nvar chart = new Chart(ctx, {\n    // The type of chart we want to create\n    type: 'line',\n\n    // The data for our dataset\n    data: {\n        labels: [],\n        datasets: [\n            {\n                label: 'first',\n                backgroundColor: '#00ff00',\n                borderColor: '#00ff00',\n                data: [],\n                yAxisID: 'left-y-axis',\n                steppedLine: false,\n                fill: false,\n                borderWidth: 1\n            }\n        ]\n    },\n\n    // Configuration options go here\n    options: {\n        scales: {\n            yAxes: [\n                {\n                    gridLines :{display:false,drawBorder:false},\n                    id: 'left-y-axis',\n                    type: 'linear',\n                    position: 'left',\n                    ticks: {\n                        display:false\n                    }\n                }\n            ],\n            xAxes: [\n                {\n                    gridLines :{display:false,drawBorder:false},\n                    type: 'time',\n                    distribution: 'series',\n                    ticks: {\n                         display:false\n                    }\n                }\n            ]\n        }\n    }\n});\nfunction showValue(v){\n    if(v){\n        document.getElementById('myValue').innerHTML = v.toFixed(2)\n    }\n    \n}\nfunction addData(chart, data, label) {\n    chart.data.datasets.forEach((dataset) => {\n        if(dataset.label == label){\n            dataset.data.push(data);\n        }\n        if(dataset.data.length > maxDataPoints){\n            dataset.data.shift()\n        }\n    });\n    chart.update(0);//0 means no animation\n}\n(function(scope) {\n  scope.$watch('msg', function(msg) {\n    if (msg) {\n      // Do something when msg arrives\n      addData(chart,{x:new Date(),y:msg.payload.first},\"first\")\n      showValue(msg.payload.first)\n\n    }\n  });\n})(scope);\n</script>\n","output":"str","x":380,"y":430,"wires":[["821cef66.60aa8"]]},{"id":"32f7132.f9080ec","type":"inject","z":"bf66f153.dd752","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":230,"y":430,"wires":[["db64afe.49ae05"]]},{"id":"195db59f.44875a","type":"ui_group","z":"","name":"Chart","tab":"29b0213a.62176e","order":3,"disp":true,"width":"8","collapse":false},{"id":"29b0213a.62176e","type":"ui_tab","z":"","name":"Ovens","icon":"dashboard","order":1,"disabled":false,"hidden":false}]
2 Likes

holy $h1t. you're an angel and i owe you my life! Thanks!!! with that exemple, i can also try and learn how to manipulate it myself in the future

Well the chart does not play nice so the tweaking is may be quite of challenge but seems nearly possible.

1 Like

image This looks amazing. Thanks again!

1 Like

ok i'm a bit lost. Ifyou're so kind can you lend me a hand? If i want to add 2 of those charts in 1 tab, which variables should a change i tried changing a lot of em but it just pushes the data to the same chart or it just doesn't push the data at all

If you look at ui_template node's info page, there is an example how to make template content unique.

<div id="{{'my_'+$id}}" style="{{'color:'+theme.base_color}}">Some text</div>
<script>
(function(scope) {
  scope.$watch('msg', function(msg) {
    if (msg) {
      // Do something when msg arrives
      $("#my_"+scope.$id).html(msg.payload);
    }
  });
})(scope);
</script>

Use this same strategy.

It didn't work... what did i do wrong?

<div id="{{'myLabel'+$id}}">1Âş Terno</div>
<div id="{{'myValue'+$id}}"></div>
<div id="{{'myUnit'+$id}}">%</div>
<style>
md-card.nr-dashboard-template.ng-scope._md.visible{
    overflow: hidden
}
    #myValue{
       position: absolute;
        left: 30px;
        top: 50px;
        text-align: center;
        font-size: 50px;
        font-weight: bold;
        color: #FFAB0B;
        overflow: hidden;
    }
    #myUnit{
       position: absolute;
        left: 140px;
        top: 90px;
        text-align: center;
        font-size: 15px;
        font-weight: bold;
        overflow: hidden;
    }
    #myChart{
        position:absolute;
        top:20px;
        overflow: hidden;
    }
    #myLabel{
       position: absolute;
        left: 63px;
        top: 5px;
        text-align: center;
        font-size: 15px;
        font-weight: bold;
        overflow: hidden;
    }
    div {
        overflow: hidden;    
    }
</style>
<script>

var maxDataPoints = 20

var ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx, {
    // The type of chart we want to create
    type: 'line',

    // The data for our dataset
    data: {
        labels: [],
        datasets: [
            {
                label: 'first',
                backgroundColor: '#00ff00',
                borderColor: '#00ff00',
                data: [],
                yAxisID: 'left-y-axis',
                steppedLine: false,
                fill: false,
                borderWidth: 2
            }
        ]
    },

    // Configuration options go here
    options: {
        elements: {
            point:{
                radius: 0
            }
        },
        scales: {
            yAxes: [
                {
                    gridLines :{display:false,drawBorder:false},
                    id: 'left-y-axis',
                    type: 'linear',
                    position: 'left',
                    ticks: {
                        display:false,
                        maxTicksLimit: 24,
                        suggestedMax: 100,
                        suggestedMin: 0
                    }
                }
            ],
            xAxes: [
                {
                    gridLines :{display:false,drawBorder:false},
                    type: 'time',
                    distribution: 'series',
                    ticks: {
                         display:false
                    }
                }
            ]
        }
    }
});
function showValue(v){
    if(v){
        document.getElementById('myValue').innerHTML = v.toFixed(1)
    }
    
}
function addData(chart, data, label) {
    chart.data.datasets.forEach((dataset) => {
        if(dataset.label == label){
            dataset.data.push(data);
        }
        if(dataset.data.length > maxDataPoints){
            dataset.data.shift()
        }
    });
    chart.update(1);//0 means no animation
}
(function(scope) {
  scope.$watch('msg', function(msg) {
    if (msg) {
      // Do something when msg arrives
      addData(chart,{x:new Date(),y:msg.payload.first},"first")
      showValue(msg.payload.first)
      $("#myCanvas"+scope.$id).html(msg.payload);
      $("#myLabel"+scope.$id).html(msg.payload);
      $("#myValue"+scope.$id).html(msg.payload);
      $("#myUnit"+scope.$id).html(msg.payload);

    }
  });
})(scope);
</script>```

Sorry, first time messing with stuff like this...

Multiple charts example

Classes for elements should not be in those templates but somewhere in common place

[{"id":"821cef66.60aa8","type":"ui_template","z":"bf66f153.dd752","group":"195db59f.44875a","name":"Line Chart","order":4,"width":"8","height":"5","format":"","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":590,"y":440,"wires":[[]]},{"id":"e57aac9d.c6f3b","type":"inject","z":"bf66f153.dd752","name":"","topic":"","payload":"","payloadType":"date","repeat":"1","crontab":"","once":false,"onceDelay":"0.62","x":210,"y":380,"wires":[["96676de2.6bd3b"]]},{"id":"96676de2.6bd3b","type":"function","z":"bf66f153.dd752","name":"fake live data","func":"msg.payload = {}\nmsg.payload.first = Math.random() * 300\nmsg.payload.second = Math.random() * 5\nreturn msg;\n","outputs":1,"noerr":0,"x":370,"y":380,"wires":[["821cef66.60aa8","41e61bf9.187f94"]]},{"id":"db64afe.49ae05","type":"template","z":"bf66f153.dd752","name":"","field":"template","fieldType":"msg","format":"html","syntax":"plain","template":"<canvas class=\"myChart\" id=\"{{'myChart'+$id}}\"></canvas>\n<div class=\"myValue\" id=\"{{'myValue'+$id}}\"></div>\n<style>\n    .myValue{\n       position: absolute;\n        left: 125px;\n        top: 100px;\n        text-align: center;\n        font-size: 60px;\n        font-weight: bold;\n    }\n    .myChart{\n        position:absolute;\n        top:20px;\n    }\n    \n</style>\n\n<script>\n\n(function($scope) {\n    setTimeout(function() {\n        //debugger\n        $scope.init();\n    },100);\n    \n    $scope.init = function () {\n        var maxDataPoints = 20\n        var ctx = document.getElementById('myChart'+$scope.$id).getContext('2d');\n        $scope.chart = new Chart(ctx, {\n            // The type of chart we want to create\n            type: 'line',\n        \n            // The data for our dataset\n            data: {\n                labels: [],\n                datasets: [\n                    {\n                        label: 'first',\n                        backgroundColor: '#00ff0022',\n                        borderColor: '#00ff00',\n                        data: [],\n                        yAxisID: 'left-y-axis',\n                        steppedLine: false,\n                        fill: true,\n                        borderWidth: 1\n                    }\n                ]\n            },\n        \n            // Configuration options go here\n            options: {\n                scales: {\n                    yAxes: [\n                        {\n                            gridLines :{display:false,drawBorder:false},\n                            id: 'left-y-axis',\n                            type: 'linear',\n                            position: 'left',\n                            ticks: {\n                                display:false\n                            }\n                        }\n                    ],\n                    xAxes: [\n                        {\n                            gridLines :{display:false,drawBorder:false},\n                            type: 'time',\n                            distribution: 'series',\n                            ticks: {\n                                 display:false\n                            }\n                        }\n                    ]\n                }\n            }\n        });\n        function showValue(v){\n            if(v){\n                document.getElementById('myValue'+$scope.$id).innerHTML = v.toFixed(2)\n            }\n        }\n        function addData(chart, data, label) {\n            chart.data.datasets.forEach((dataset) => {\n                if(dataset.label == label){\n                    dataset.data.push(data);\n                }\n                if(dataset.data.length > maxDataPoints){\n                    dataset.data.shift()\n                }\n            });\n            chart.update(200);//0 means no animation\n        }\n        $scope.$watch('msg', function(msg) {\n            if (msg) {\n                // Do something when msg arrives\n                addData($scope.chart,{x:new Date(),y:msg.payload.first},\"first\")\n                showValue(msg.payload.first)\n        \n            }\n        });\n    }\n})(scope);\n</script>\n\n\n","output":"str","x":380,"y":440,"wires":[["821cef66.60aa8"]]},{"id":"32f7132.f9080ec","type":"inject","z":"bf66f153.dd752","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":190,"y":440,"wires":[["db64afe.49ae05","e71370f9.bd593"]]},{"id":"e71370f9.bd593","type":"template","z":"bf66f153.dd752","name":"","field":"template","fieldType":"msg","format":"html","syntax":"plain","template":"<canvas class=\"myChart\" id=\"{{'myChart'+$id}}\"></canvas>\n<div class=\"myValue\" id=\"{{'myValue'+$id}}\"></div>\n<style>\n    .myValue{\n       position: absolute;\n        left: 125px;\n        top: 100px;\n        text-align: center;\n        font-size: 60px;\n        font-weight: bold;\n    }\n    .myChart{\n        position:absolute;\n        top:20px;\n    }\n    \n</style>\n\n<script>\n\n(function($scope) {\n    setTimeout(function() {\n        //debugger\n        $scope.init();\n    },100);\n    \n    $scope.init = function () {\n        var maxDataPoints = 20\n        var ctx = document.getElementById('myChart'+$scope.$id).getContext('2d');\n        $scope.chart = new Chart(ctx, {\n            // The type of chart we want to create\n            type: 'line',\n        \n            // The data for our dataset\n            data: {\n                labels: [],\n                datasets: [\n                    {\n                        label: 'first',\n                        backgroundColor: '#00ff0022',\n                        borderColor: '#00ff00',\n                        data: [],\n                        yAxisID: 'left-y-axis',\n                        steppedLine: false,\n                        fill: true,\n                        borderWidth: 1\n                    }\n                ]\n            },\n        \n            // Configuration options go here\n            options: {\n                scales: {\n                    yAxes: [\n                        {\n                            gridLines :{display:false,drawBorder:false},\n                            id: 'left-y-axis',\n                            type: 'linear',\n                            position: 'left',\n                            ticks: {\n                                display:false\n                            }\n                        }\n                    ],\n                    xAxes: [\n                        {\n                            gridLines :{display:false,drawBorder:false},\n                            type: 'time',\n                            distribution: 'series',\n                            ticks: {\n                                 display:false\n                            }\n                        }\n                    ]\n                }\n            }\n        });\n        function showValue(v){\n            if(v){\n                document.getElementById('myValue'+$scope.$id).innerHTML = v.toFixed(2)\n            }\n        }\n        function addData(chart, data, label) {\n            chart.data.datasets.forEach((dataset) => {\n                if(dataset.label == label){\n                    dataset.data.push(data);\n                }\n                if(dataset.data.length > maxDataPoints){\n                    dataset.data.shift()\n                }\n            });\n            chart.update(200);//0 means no animation\n        }\n        $scope.$watch('msg', function(msg) {\n            if (msg) {\n                // Do something when msg arrives\n                addData($scope.chart,{x:new Date(),y:msg.payload.second},\"first\")\n                showValue(msg.payload.second)\n        \n            }\n        });\n    }\n})(scope);\n</script>\n\n\n","output":"str","x":380,"y":480,"wires":[["41e61bf9.187f94"]]},{"id":"41e61bf9.187f94","type":"ui_template","z":"bf66f153.dd752","group":"195db59f.44875a","name":"Line Chart","order":4,"width":"8","height":"5","format":"","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":590,"y":480,"wires":[[]]},{"id":"195db59f.44875a","type":"ui_group","z":"","name":"Chart","tab":"29b0213a.62176e","order":3,"disp":true,"width":"8","collapse":false},{"id":"29b0213a.62176e","type":"ui_tab","z":"","name":"Ovens","icon":"dashboard","order":1,"disabled":false,"hidden":false}]
1 Like