Skip to content

Instantly share code, notes, and snippets.

@Weiyuan-Lane
Created May 17, 2024 04:58
Show Gist options
  • Save Weiyuan-Lane/20edf7750c921baaaf9f91c05cbee703 to your computer and use it in GitHub Desktop.
Save Weiyuan-Lane/20edf7750c921baaaf9f91c05cbee703 to your computer and use it in GitHub Desktop.

Revisions

  1. Weiyuan-Lane created this gist May 17, 2024.
    84 changes: 84 additions & 0 deletions json_to_graph.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    #!/usr/bin/ruby

    # To run in terminal:
    #
    # `ruby json_to_graph.rb <json_input_file_path> <output_path>`
    #
    #
    # Make sure you install the following gems:
    #
    # `gem install ruby-graphviz`
    #
    # You'll also need to install graphviz to use the gem - see instructions here: https://graphviz.org/download/
    # e.g. for installation in Mac
    #
    # `brew install graphviz`
    #

    require 'ruby-graphviz'
    require 'json'

    json_input_file_path = ARGV[0]
    output_path = ARGV[1]

    file = File.read(json_input_file_path)
    data = JSON.parse(file)

    ###############################################################################
    # CHANGE ITEMS START - Only change values within this area #
    ###############################################################################
    # Change the following to the array you want to convert to a graph
    data_array = data['tags']

    def get_id(single_entry)
    single_entry['tagId']
    end
    def get_parent_ids(single_entry)
    single_entry['parentTagIds']
    end
    def get_name(single_entry)
    single_entry['allNamesByLocale']['en'] # If name is the id and is used above, can return as empty string
    end
    ###############################################################################
    # CHANGE ITEMS END #
    ###############################################################################

    data_graph = GraphViz.new( :G, :type => :digraph )
    node_map = {}

    # Create nodes
    data_array.each do |single_entry|
    id = get_id(single_entry)
    name = get_name(single_entry)
    parent_ids = get_parent_ids(single_entry)

    puts "Creating node with id: #{id} and name: #{name}"
    node_map[id] = if name == '' || name.nil?
    data_graph.add_nodes("id:#{id}")
    else
    data_graph.add_nodes("id: #{id}, name: #{name}")
    end
    end

    # Create edges
    data_array.each do |single_entry|
    id = get_id(single_entry)
    parent_ids = get_parent_ids(single_entry)

    unless parent_ids.nil?
    puts "Creating edge with id: #{id}"
    parent_ids.each do |parent_id|
    if node_map.key?(parent_id)
    data_graph.add_edges(node_map[parent_id], node_map[id])
    end
    end
    end
    end


    # If your graph ends up cropped or too pixelated, you can try to output it as svg
    data_graph.output(path: output_path, png: 'graph.png' )
    puts "Graph created at #{output_path}/graph.png"

    # data_graph.output(path: output_path, svg: 'graph.svg' )
    # puts "Graph created at #{output_path}/graph.svg"