Rule-Based Styles

Rule-based styles can be applied on any vertex or edge property values. You can define a rule-based styling using one or more defined properties. The set condition is verified and the vertices or edges are filtered based on whether the property value of the graph element matches the value given in the condition, based on the specified operator.

The following operators can be used to determine if the property value matches the set rule: =, CONTAINS, !=, >, <, >=, <=, ~ and CONTAINS_REGEX.

Equality operators = and != performs exact match between the value of vertex or edge properties and that in the condition. Supported combinations are:

Property value Condition value
string string
string array string array
number string holding a numeric value
boolean string holding a boolean value

Comparison operators >, <, >=, <= compares the property value against the condition value. Supported combinations are:

| Property value | Condition value |———-|———- | string | string | number | string holding a numeric value CONTAINS operator checks if any element in the property value array matches the value specified in the condition. Supported combinations are:

Property value Condition value
string array string
string array string array

~ operator checks if the property value of the vertex or edge satisfies the regular expression given in the condition value. Only the below combination is supported.

Property value Condition value
string string

CONTAINS_REGEX operator checks if any element in the property value array satisfies the regular expression given in the condition value. Only the below combination is supported.

Property value Condition value
string array string

Also, note the following:

Nested JSON properties can also be used in rule-based style conditions by referencing the property with a dotted path. For regular graph properties, use the path relative to the graph element’s properties object, for example profile.address.city or metrics.score.current. The optional properties. prefix is also supported and is mainly useful when a custom top-level property name overlaps with a reserved graph field such as id, source, or target.

When an entity has a structured backend identifier, the scalar id is the runtime identifier used for graph matching, selection, grouping, and rendering. The structured identifier is retained in original_id and can be filtered with an original_id. path, for example original_id.KEY_VALUE.COUNTRY_ID.

JSON paths must resolve to a supported leaf value type such as string, number, boolean, or string array. Pointing a condition at an entire JSON object is not supported; the path should end at a concrete nested value instead.

settings.ruleBasedStyles = [
  {
    target: 'vertex',
    component: 'vertex',
    conditions: {
      conditions: [
        { property: 'profile.address.city', operator: '=', value: 'Austin' },
        { property: 'metrics.score.current', operator: '>=', value: '90' },
        { property: 'profile.tags', operator: 'CONTAINS', value: 'vip' },
        { property: 'original_id.KEY_VALUE.COUNTRY_ID', operator: '=', value: 'AU' }
      ],
      operator: 'and'
    },
    legendTitle: 'Austin VIPs with high score',
    style: { color: '#0b6e4f' },
    stylingEnabled: true
  },
  {
    target: 'edge',
    component: 'edge',
    conditions: {
      conditions: [{ property: 'properties.id.raw', operator: '=', value: 'edge-42' }]
    },
    legendTitle: 'Reserved-name JSON path example',
    style: { color: '#d1495b' },
    stylingEnabled: true
  }
];

Consider the following example which describes a rule to color vertices with person label in blue and vertices having first_name = ‘John’ in red.

const vertices = [
  {
    id: 1,
    properties: {
      first_name: 'Angel',
      last_name: 'Rodriguez'
      age: 10
    }
    labels: ['person']
  },
  {
    id: 2,
    properties: {
      first_name: 'John',
      last_name: 'Anderson'
      age: 20
    },
    labels: ['person']
  },
  {
    id: 3,
    properties: {
      first_name: 'Matt',
      last_name: 'Judge'
      age: 30
    },
    labels: ['person']
  }
];

const edges = [
  {
    id: 1,
    source: 1,
    target: 2
  },
  {
    id: 2,
    source: 2,
    target: 3
  }
];

const settings = {};
settings.baseStyles = {
  vertex: {
    caption: { text: '${properties.name}' }
  }
};

settings.ruleBasedStyles = [
  {
    // Rule's target
    target: 'vertex',
    component: 'vertex',
    // The conditions on which the filter will be applied
    conditions: {
      conditions: [
        // This condition will apply to all the vertices that has 'person' on their labels
        {
          property: "labels",
          operator: "CONTAINS",
          value: "person"
        }
      ]
    },
    // The title for the filter that will show in the legend
    legendTitle: 'Rule by labels',
    // The colors to apply to the nodes that match the rule
    style: {
      color: 'blue'
    },
    stylingEnabled: true
  },
  {
    // Rule's target
    target: 'vertex',
    component: 'vertex',
    // The conditions on which the filter will be applied
    conditions: {
      conditions: [
        // This condition will verify if the property first_name on a vertex is equals to 'John'
        {
          property: "first_name",
          operator: "=",
          value: "John"
        }
      ]
    },
    // The title for the filter that will show in the legend
    legendTitle: 'Rule by property named first_name being equals to John',
    // The colors to apply to the nodes that match the rule
    style: {
      color: 'red'
    },
    stylingEnabled: true
  }
];

new GraphVisualization({
  target: document.body,
  props: { data: { vertices, edges }, settings }
});

Rule-based styles can also be applied to adjust the size of nodes. Also, you can define a rule to match multiple conditions simultaneously. These conditions can be configured using and or or operators. In such a case, filtering is applied only when all the specified conditions are met for the and operator, or when any one of the conditions is satisfied for the or operator.

// This import is not necessary if you are using Oracle JET.
import '@ovis/graph/alta.css';
import Visualization from '@gvt/graphviz';

const vertices = [
  {
    id: 1,
    properties: {
      first_name: 'Angel',
      last_name: 'Rodriguez'
      age: 10
    }
    labels: ['person']
  },
  {
    id: 2,
    properties: {
      first_name: 'John',
      last_name: 'Anderson'
      age: 20
    },
    labels: ['person']
  },
  {
    id: 3,
    properties: {
      first_name: 'Matt',
      last_name: 'Judge'
      age: 30
    },
    labels: ['person']
  }
];

const edges = [
  {
    id: 1,
    source: 1,
    target: 2
  },
  {
    id: 2,
    source: 2,
    target: 3
  }
];

const settings = {};
settings.baseStyles = {
  vertex: {
    caption: {text: '${properties.name}'}
  }
};

settings.ruleBasedStyles = [
  {
    // The target in the rule.
    target: 'vertex',
    component: 'vertex',
    // The conditions on which the rule will be applied.
    conditions: {
      operator: 'and',
      conditions: [
        // This condition will verify that the name contains the letter o.
        {
          property: "name",
          operator: "~",
          value: "o"
        },
        // This condition will verify that the name contains the letter l.
        {
          property: "name",
          operator: "~",
          value: "l"
        }
      ]
    },
    // The title for the filter that will show in the legend.
    legendTitle: 'Rule by name',
    // The colors to apply to the nodes that match the rule.
    style: {
      size: 15
    },
    stylingEnabled: true
  }
];

new GraphVisualization({
  target: document.body,
  props: { data: { vertices, edges }, settings }
});