Dynamic Styling for CyFHIR - Optum/CyFHIR GitHub Wiki

Dynamic Styling for CyFHIR using Neo4j .grass File

The code below helps do the impossible: Dynamically Style Neo4j browser renderings! I've only tested it in google chrome and I'm pretty sure that is the only place it will work.

To use it:

  1. Have Neo4j running and navigate to Neo4j browser
  2. Load up your data, whether with CyFHIR or anything else
  3. In the Dev Tools of chrome, navigate to the console
  4. Copy and paste the code below into the console (Please inspect it yourself before running, don't trust random code on the internet)
  5. After running the code, the neo4j.grass query will be saved to your clipboard, paste it into the neo4j query editor
  6. Hit enter/run the query it should look like this :style {"node":{... and a large JSON containing all your styling

This has some specific's regarding how CyFHIR works, but you can edit those out pretty easily or just work around them they are mainly with the node.reference, node.entry, and relationship.reference hard coded bits.

function getRandomArbitrary(min, max) {
  return Math.random() * (max - min) + min;
}

function numToHex(num) {
  return num.toString(16).padStart(2, '0');
}

function shuffleArray(array) {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
}

function decimalToRGBHex(value) {
  var r = Math.floor(value / (256 * 256));
  var g = (Math.floor(value / 256) % 256);
  var b = (value % 256);
  const hex = ("#" + numToHex(r) + numToHex(g) + numToHex(b)).toUpperCase();

  font = "#FFFFFF"
  if ((r * 0.299 + g * 0.587 + b * 0.114) > 186) {
    font = "#000000";
  }
  return {
    hex,
    font
  };
}

function style() {
  let newGrassFile = {};
  const colors = 16777215;
  if ($x("//*[contains(text(), 'Show all')]").length == 0) {
    $x("//button[contains(@Name, 'DBMS')]")[0].click();
  }
  if ($x("//*[contains(text(), 'Show all')]").length == 3) {
    $x("//*[contains(text(), 'Show all')]")[0].click();
  }
  let grassFile = JSON.parse(localStorage["neo4j.grass"]);
  newGrassFile["node"] = grassFile["node"];
  newGrassFile["node.*"] = grassFile["node.*"];
  newGrassFile["relationship"] = grassFile["relationship"];

  let divs = $x("//*[contains(text(), 'Labels')]/../div/div");
  divs.shift();
  let increment = Math.floor(16777215 / divs.length);
  shuffleArray(divs)
  let labels = divs.forEach((div, i) => {
    let obj = {};

    if (div.textContent == 'resource') {
      obj["color"] = "#FF0000"
      obj["text-color-internal"] = "#FFFFFF";
      obj["diameter"] = "85px"
      obj["caption"] = "{resourceType}"
      obj["font-size"] = "16px"
    } else if (div.textContent == 'entry') {
      obj["color"] = "#0000FF"
      obj["text-color-internal"] = "#FFFFFF";
      obj["diameter"] = "60px"
      obj["caption"] = "{_resourceId}"
      obj["font-size"] = "12px"
    } else {
      let min = i * increment;
      let max = (i + 1) * increment;
      let rand = Math.floor(getRandomArbitrary(min, max));
      let color = decimalToRGBHex(rand);
      obj["color"] = color.hex;
      obj["text-color-internal"] = color.font;
    }

    obj["border-color"] = "#000000"
    newGrassFile[`node.${div.textContent}`] = obj;
  })

  newGrassFile["relationship.reference"] = {
    "color": "#FFDD33",
    "shaft-width": "5px",
    "font-size": "10px",
    "padding": "3px",
    "text-color-external": "#000000",
    "text-color-internal": "#FFFFFF",
    "caption": "<type>"
  }

  localStorage.setItem("neo4j.grass", newGrassFile);
  return ":style " + JSON.stringify(newGrassFile);
}

copy(style())

Outcome of this CyFHIR specific script:

graph

⚠️ **GitHub.com Fallback** ⚠️