Dash 2.0 Sparkline

@thebaldgeek Regarding the units not showing, since you have a v-if="npm"you need to have that variable declared in the return section, or just remove the v-if="mpm" in that case the units will always show. Something like this:

<template>
  <v-card color="surface-light" max-width="600">
    <template v-slot:title>
      <div class="text-caption text-grey text-uppercase">
        EGGD VDL2
      </div>
      <span
        class="text-h3 font-weight-black"
        v-text="value[1]"
      ></span>
      <small v-if="mpm">mpm</small>
    </template>
    <v-sheet color="transparent">
      <v-sparkline :key="String(mom)" :gradient="['#f72047', '#ffd200', '#1feaea']" :line-width="3"
        :model-value="value" :smooth="16" stroke-linecap="round" auto-draw></v-sparkline>
    </v-sheet>
  </v-card>
</template>

<script>
  export default {
    data: function () {
      return {
        gradient: ['#f72047', '#ffd200', '#1feaea'],
        value: [0, 2, 5, 9, 5, 10, 3, 5, 0, 0, 1, 8, 2, 9, 0],
        mpm: true
      }
    },
    watch: {
      msg: function () {
        this.value.push(this.msg.payload)
          // Change the number to limit the array size
          while (this.value.length > 50) {
          this.value = this.value.slice(1)
        }
      }
    }
  }
</script>

<style>
.nrdb-ui-sparkline path {
  stroke-dasharray: 0 !important;
}
</style>

Regarding the errors and crash, it is a bit frustrating, the way I use it, is to use vuetify play you can have the full template code there such as example.
It is a fast way to check for errors, it happens to me all the time to forgot that in same places i need to use value: 55, instead of value = 55; or vice-versa for example.

It is not possible to simulate "msg" and we cannot also use the this.send to simulate messages, normally I use console.log or alert to simulate messages being sent from the template to NodeRed to validate stuff. Regarding msg sometimes just define a timeout to run every second and a function to emulate "data".

Thanks for the fix @arturv2000

As I mentioned in the post with the code snip I also find the Vuetify play area, as you said, its a quick pain free way to break and fix quicky.
The lack of msg.payload inputs is very limiting. The weird thing is that I got the mpm working in the play area, but not in my template, so clearly my cut/paste skills are as lacking as my 'low code' skills < grin >

My next two goals for the sparkline is to make it smaller. Its just huge and I miss the whole compact aspect of the sparkline.
The second is to get it working in a table.
I'd like to see 4-5 in a single table with the data values.
I see the example here: https://flowfuse.com/blog/2024/04/dashboard-milestones-pwa-new-components/#sparkline-(docs) But am unable to get it working.

HI
Regarding the playground, sometimes the rendering is not exactly the same also because off css styles defined in dashboard that change some components behaviours .

I used that example as base for my project, remenber that there where some issue, don't remenber exactly which one.

Don't have access to the work pc at the moment, will try to post an example when arrive at work.

Here a small example of a table with the sparklines.

The handling of the array is done externally, since for my use want to preserve the history even upon page reloading and wasn't happening with the template.

[{"id":"ead3ae3670afa3c8","type":"inject","z":"33f272716c862133","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"0.5","crontab":"","once":true,"onceDelay":0.1,"topic":"newValue","payload":"","payloadType":"date","x":560,"y":4440,"wires":[["9765f18dec0445ea"]]},{"id":"9765f18dec0445ea","type":"function","z":"33f272716c862133","name":"Parse WideBands","func":"if(msg.topic != 'clear' && msg.topic != 'newValue'){\n    return null;\n}\n\nlet _oldData = context.get('data') ?? undefined;\n\nlet _value = [Math.floor(Math.random() * 100), Math.floor(Math.random() * 100)];\n\n\nif(_oldData == undefined || msg.topic == 'clear'){\n    _oldData = [];\n    _oldData.push({ channel: 1, name: 'EGT1', value: (_value[0]), arrayvalues: [(_value[0])], unit: 'ÂșC'});\n    _oldData.push({ channel: 2, name: 'EGT2', value: (_value[0]), arrayvalues: [(_value[0])], unit: 'ÂșC' });\n}else{\n    for(let i = 0; i < 2; i++){\n        _oldData[i].value = (_value[i]);\n        _oldData[i].arrayvalues.push(_value[i]);\n        if (_oldData[i].arrayvalues.length > 50) {\n            _oldData[i].arrayvalues.shift();\n        }\n    }\n}\n\ncontext.set('data', _oldData);\n\nreturn {topic: 'data', payload: _oldData};\n\n\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":830,"y":4440,"wires":[["7af90e299d5aee5e","62c16319ce066dd8"]]},{"id":"62c16319ce066dd8","type":"ui-template","z":"33f272716c862133","group":"acbbafbfc6d6007a","name":"Table Test","order":3,"width":0,"height":0,"head":"","format":"<template>\n  <!-- Provide an input text box to search the content -->\n    <div class=\"d-flex\" style=\"font-weight: bold; font-size: 1.3rem\">\n    <span class=\"text-center\" style=\"width: 100%\"> Generic Temperatures </span>\n    <v-spacer></v-spacer\n    ><v-btn color=\"#D2691E\" @click=\"this.send({topic: 'clear'})\">\n      <strong style=\"color: white\">Clear</strong>\n    </v-btn>\n  </div>\n  <v-data-table class=\"myDataTable\" :items=\"msg?.payload\" :headers=\"headers\" hide-details=\"auto\" density=\"compact\" items-per-page=20>\n    <template #bottom>\n      <!-- Leave this slot empty to hide pagination controls -->\n      <!-- <hr> -->\n    </template>\n    <template v-slot:item.value=\"{ item }\">\n      <v-progress-linear :model-value=\"getValue(item.value)\" max=\"100\" height=\"40\" :color=\"getColor(item)\">\n        <template v-slot:default=\"{ value }\">\n          <strong>{{ Math.ceil(item.value) }}{{item.unit}}</strong>\n        </template>\n      </v-progress-linear>\n    </template>\n    <template v-slot:item.arrayvalues=\"{ item }\">\n      <v-sparkline v-model=\"item.arrayvalues\" :gradient=\"['#FF0000', '#5525FF']\" :line-width=\"1\" gradientDirection=\"top\"\n        :smooth=\"true\" :fill=\"false\" height=\"45\">\n    </template>\n\n  </v-data-table>\n</template>\n\n<script>\n  export default {\n  data () {\n    return {\n      progressBar_Max: 100,\n      progressBar_Min: 0,\n      headers: [\n        { key: 'name', title: 'Name', width: '15%'},\n        { key: 'value', title: 'Value', width: '45%', align: 'center' },\n        { key: 'arrayvalues', title: 'History',align: 'center' }\n      ]\n    }\n  },\n  methods: {\n    getColor: function (item) {\n      if (item.value > 80) {\n        return 'red'\n      } else {\n        return 'green'\n      }\n    },\n    // add a function to determine the color of the progress bar given the row's item\n    getValue: function (value) {\n      let val = Math.ceil(this.map(value, this.progressBar_Min, this.progressBar_Max, 0, 100));\n      return val;\n    },\n    map: function (current, in_min, in_max, out_min, out_max){\n      let mapped = ((current - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min;\n      return this.clamp(mapped, out_min, out_max);\n    },\n    clamp: function (input, min, max) {\n      return input < min ? min : input > max ? max : input;\n    }\n  }\n}\n</script>\n<style>\n  .v-progress-linear__determinate {\n    transition: none !important\n  }\n\n  .myDataTable .v-data-table-header__content {\n    font-weight: bold;\n }\n</style>","storeOutMessages":true,"passthru":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":1060,"y":4440,"wires":[["a375d22722bd6d24","9765f18dec0445ea"]]},{"id":"acbbafbfc6d6007a","type":"ui-group","name":"WideBand Probe","page":"3cdf194d3e1f3330","width":"6","height":"1","order":6,"showTitle":true,"className":"","visible":"true","disabled":"false"},{"id":"3cdf194d3e1f3330","type":"ui-page","name":"Values Visualization","ui":"9df4836d2f5c3db3","path":"/values_view","icon":"chart-timeline","layout":"grid","theme":"6abc079232f2e7a5","order":6,"className":"","visible":"true","disabled":"false"},{"id":"9df4836d2f5c3db3","type":"ui-base","name":"My Dashboard","path":"/dashboard","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control"],"showPathInSidebar":false,"navigationStyle":"default"},{"id":"6abc079232f2e7a5","type":"ui-theme","name":"Default Theme","colors":{"surface":"#097479","primary":"#097479","bgPage":"#111111","groupBg":"#333333","groupOutline":"#cccccc"},"sizes":{"pagePadding":"6px","groupGap":"6px","groupBorderRadius":"4px","widgetGap":"6px"}}]

It is still a work in progress...

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.