January 5, 2021
Pfmindmap – Resolving a Fundamental Issue of Discussion Interfaces

Article updated Nov 2, 2021

The Problem

Discussions are exponential, but discussion interfaces are linear. Anything you say can elicit multiple responses to it. Let’s say the average point elicits 3 responses. 5 levels in, we are at 243 branches of subject matter. This is how discussions break down. Does this sound familiar? Think about debates you’ve had. Many branches of subject matter arise. It’s hard to tend after them all. It’s hard to be clear about which one is being addressed. It’s hard to review what has been addressed and what hasn’t.

Typical discussion interfaces are a vertical stack of posts. Platforms try to accomodate the perpetually-diverging nature of discussion as well as they can, with various user interface components, such as navigation buttons and expand/collapse controls. But, in the end, you’re looking at a vertical stack of posts, and only a few posts are on-screen at a time. The user is made to keep track of the overall structure, themselves, mentally.


Pfmindmap is a JavaScript module that visualizes a discussion as a “mind map,” the kind of diagram that draws links between items that are arranged and organized in 2D space. Pfmindmap produces a natural-looking tree that makes good use of screen real estate, by employing a force-directed layout.

The interface is navigated like a map interface: zoom & pan.

It is helpful to to see the entire structure of the conversation. The user can spot where discussion is happening, then zoom in to read it. Pfmindmap helps people review, present, and understand information.


One website that uses pfmindmap is Twidgel. Twidgel is toolkit website for tools that interface with the Twitter API. The Twidgel Tweet Reply Map visualizes Twitter conversations as mind map diagrams. Twitter data is well-suited to being visualized as a tree, because replies can, themselves, be replied to, and there is no limit to the number reply levels. There are often lengthy discussions happening within the replies of a Tweet.

The Twidgel “Tweet Reply Map” tool continues populating, in real time, as new content is added to the conversation, and you can click on a Tweet, to open it in a new tab, in Twitter. In this way, it functions as a new kind of discussion interface for Twitter content.


The pfmindmap interface is easy to install in a webpage. The implementing webpage provides:

  • A container element for the visualization to go in
  • An element creator function, to create an HTML element for each diagram item

You can send whatever data you want, and make your items look however you want. The module just needs unique IDs for each item, and the reply-to IDs, and it needs to know which item is the root node.

Here’s a complete example, using the bundle (alternately, you can use npm install and bundle it with your app).

        .item-to-clone { cursor: default; }
        .item-to-clone:active { cursor: grabbing; }
    <div id="container-div" style="min-height:100vh;"></div>

    <div style="display:none;">
        <div class="item-to-clone" style="border: 1px solid black; background: white; border-radius: 5px; min-height: 50px; padding: 10px;"></div>

    <script type="module">
        import pfmindmap from './path/to/pfmindmap_bundle.js';
        var data = [
            { 'id': '8843784378', 'reply_to_id': '', 'message': 'wazaaa', 'is_first': true },
            { 'id': '8064783478', 'reply_to_id': '8843784378', 'message': 'first level reply' },
            { 'id': '4785784534', 'reply_to_id': '8843784378', 'message': 'another first level reply' },
            { 'id': '4398489489', 'reply_to_id': '6734894923', 'message': 'some reply text' },
            { 'id': '6734894958', 'reply_to_id': '4785784534', 'message': 'another 2nd level reply' },
            { 'id': '6733494934', 'reply_to_id': '6734894958', 'message': 'a 3rd level reply' },
            { 'id': '6734894923', 'reply_to_id': '6734894958', 'message': 'another 3rd level reply' },
            { 'id': '6734894912', 'reply_to_id': '6734894923', 'message': '4th level reply' },
            { 'id': '4783489548', 'reply_to_id': '8843784378', 'message': 'this is another first level reply' }
        var itemElCreator = (data) => {
            const newEl = document.querySelector('.item-to-clone').cloneNode(true);
            newEl.innerHTML = data["message"];
            return newEl;
        var pfmm = new pfmindmap(document.querySelector("#container-div"), itemElCreator, { 'item_width': 300 });

Detailed docs are at the GitHub readme.


This module is powered by D3.js, a data visualization JavaScript library. It also utilizes the Observable runtime, which provides a data flow environment. I recommend visiting ObservableHQ, a website for sharing D3 and other visualizations.


Pfmindmap is free, open source, and has a permissive license (BSD 2 clause).


  • This article refers to pfmindmap v1.8.1


Share this page