bartbutenaers / node-red-contrib-ui-svg

A Node-RED widget node to show interactive SVG (vector graphics) in the dashboard
Apache License 2.0
94 stars 27 forks source link

Best way to add FontAwesome icons #6

Closed bartbutenaers closed 5 years ago

bartbutenaers commented 5 years ago

Currently the readme file contains a whole section about how to add a FontAwesome icon to the SVG drawing. Just wondering if we could simplify this process somehow?

One solution would be to allow the user to 'use' a 'definition' of an Fontawesome icon.

For example:

<svg>
  <defs>
    <!-- Automatically added Fontawesome icon -->
    <text id="svg_fa_video_camera" x="310" y="45" font-family="FontAwesome" fill="blue" stroke="black" font-size="35" text-anchor="middle" alignment-baseline="middle" stroke-width="1">&#xf03d;</text>
  </defs>

   <!-- Added by the user -->
  <use x="5" y="5" xlink:href="#svg_fa_video_camera" />
</svg>

So the user uses a FontAwesome icon, and this node automatically adds (text element) definitions for all used icons.

bartbutenaers commented 5 years ago

TODOs:

  1. In the svg_utils file, the switch statement should get an extra entry at the end:

    default:
      return null;
  2. At the end of the $scope.init function, the following code snippet should be added:

    var textElements = $scope.svg.getElementsByTagName("text");
    
    // Replace all FontAwesome icon names by their uniCode values                         
    for (var i = 0; i < textElements.length; i++) {
      var textElement = textElements[i];
      var textContent = textElement.textContent.trim();
    
      if (textContent.startsWith("fa-")) {
         var uniCode = getUnicode(textContent);
    
         if (uniCode) {
            textElement.textContent = "&#x" + uniCode + ";";
         }
         else {
            console.log("FontAwesome icon " + textContent + " is not supported by this node");
         }       
      }
    } 
  3. The $scope.init function is being called at client-side (i.e. inside the dashboard), so we need to load the svg_utils.js file (containing the getUnicode function) from the server . So probably:

    • Load the script in the generated HTML raw string:
      var html = String.raw`
       <script type="text/javascript" src="svg_utils.js"></script>
       <div id='tooltip_` + config.id + `' display='none' style='position: absolute; display: none; background: cornsilk; border: 1px solid black; border-radius: 5px; padding: 2px;'></div>
       <div id='svggraphics_` + config.id + `' ng-init='init(` + configAsJson + `)'>` + config.svgString + `</div>
      `;
    • Publish this script on the server, similar to my heatmap node code. Caution: I received an issue about that code snippet a few days ago, so we should implement that fix also here!

[EDIT]: The svg_utils.js file is quite large. So to avoid having to download it, it is better to do it like this:

  1. In the loop create a list of textContent strings.
  2. Do 1 call to the server to convert that list.
  3. Loop again over the same text elements and replace the results