Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8457819
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T12:54:33+00:00 2026-06-10T12:54:33+00:00

Background : Working with MediaWiki 1.19.1, Graphviz 2.28.0, Extension:GraphViz 0.9 on WAMP stack (Server

  • 0

Background: Working with MediaWiki 1.19.1, Graphviz 2.28.0, Extension:GraphViz 0.9 on WAMP stack (Server 2008, Apache 2.4.2, MySQL 5.5.27, PHP 5.4.5). Everything is working great and as expected for the basic functionality of rendering a clickable image from a Graphviz diagram using the GraphViz extension in MediaWiki.

Problem: The links in the image map are not added to the MediaWiki pagelinks table. I get why they aren’t added but it becomes an issue if there is no way to follow the links back with the ‘What links here’ functionality.

Desired solution: During the processing of the diagram in the GraphViz extension, I would like to use the generated .map file to then create a list of wikilinks to add on the page to get picked up by MediaWiki and added to the pagelinks table.

Details:
This GraphViz extension code:

<graphviz border='frame' format='png'>
digraph example1 {
  // define nodes
  nodeHello [
    label="I say Hello", 
    URL="Hello"
  ]
  nodeWorld [
    label="You say World!",
    URL="World"
  ]
  // link nodes
  nodeHello -> nodeWorld!
}
</graphviz>

Generates this image:

hello world graphviz diagram

And this image map code in a corresponding .map file on the server:

<map id="example1" name="example1">
<area shape="poly" id="node1" href="Hello" title="I say Hello" alt="" coords="164,29,161,22,151,15,137,10,118,7,97,5,77,7,58,10,43,15,34,22,31,29,34,37,43,43,58,49,77,52,97,53,118,52,137,49,151,43,161,37"/>
<area shape="poly" id="node2" href="World" title="You say World!" alt="" coords="190,125,186,118,172,111,152,106,126,103,97,101,69,103,43,106,22,111,9,118,5,125,9,133,22,139,43,145,69,148,97,149,126,148,152,145,172,139,186,133"/>
</map>

From that image map file, I would like to be able to extract the href and title to build wikilinks like so:

[[Hello|I say Hello]]
[[World|You say World!]]

I’m guessing that since that .map file is essentially XML that I could just use XPATH to query the file, but that is just a guess. PHP is not my strongest area and I don’t know the best approach to going about the XML/XPATH option or if that is even the best approach to pull that info from the file.

Once I got that collection/array of wikilinks from the .map file, I’m sure I can hack up the GraphViz.php extension file to add it to the contents of the page to get it added to the pagelinks table.

Progress: I had a bit of an Rubber Duck Problem Solving moment right as I submitted the question. I realized that since I had well formed data in the image map, that XPATH was probably the way to go. It was fairly trivial to be able to pull the data I needed, especially since I found that the map file contents was stilled stored in a local string variable.

$xml = new SimpleXMLElement( $map );
foreach($xml->area as $item) {
  $links .= "[[" . $item->attributes()->href . "|" . $item->attributes()->title . "]]";
}

Final Solution: See my accepted answer below.
Thanks for taking a look. I appreciate any assistance or direction you can offer.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T12:54:34+00:00Added an answer on June 10, 2026 at 12:54 pm

    I finally worked through all of the issues and now have a fairly decent solution to render the graph nicely, provide a list of links, and register the links with wiki. My solution doesn’t fully support all of the capabilities of the current GraphViz extension as it is written as there is functionality we do not need and I do not want to support. Here are the assumptions / limitations of this solution:

    • Does not support MscGen: We only have a need for Graphviz.
    • Does not support imageAtrributes: We wanted to control the format and presentation and it seemed like there were inconsistencies in the imageAttributes implementation that would then cause further support issues.
    • Does not support wikilinks: While it would be nice to provide consistent link usage through wiki and the Graphviz extension, the reality is that Graphviz is a completely different markup environment. While the current extension ‘supports’ wikilinks, the implementation is a little weak and leaves areas for confusion. Example: Wikilinks support giving the link an optional description but Graphviz already uses the node label for the description. So then you end up ignoring the wikilink description and telling users that ‘Yes, we support wikilinks but don’t use the description part’ So since we aren’t really using wikilinks correctly, just implement a regular link implementation and try to avoid the confusion entirely.

    Here is what the output looks like:
    Wiki Graphviz enhancements

    Here are the changes that were made

    Comment out this line:

    // We don't want to support wikilinks so don't replace them
    //$timelinesrc = rewriteWikiUrls( $timelinesrc ); // if we use wiki-links we transform them to real urls
    

    Replace this block of code:

    // clean up map-name
    $map  = preg_replace( '#<ma(.*)>#', ' ', $map );
    $map  = str_replace( '</map>', '', $map );
    if ( $renderer == 'mscgen' ) {
        $mapbefore = $map;
        $map = preg_replace( '/(\w+)\s([_:%#/\w]+)\s(\d+,\d+)\s(\d+,\d+)/',
       '<area shape="$1" href="$2" title="$2" alt="$2" coords="$3,$4" />',
        $map );
    }
    
    /* Procduce html
     */
    if ( $wgGraphVizSettings->imageFormatting )
    {
        $txt = imageAtrributes( $args, $storagename, $map, $outputType, $wgUploadPath ); // if we want borders/position/...
    } else {
        $txt  = '<map name="' . $storagename . '">' . $map . '</map>' .
             '<img src="' . $wgUploadPath . '/graphviz/' . $storagename . '.' . $outputType . '"' .
                       ' usemap="#' . $storagename . '" />';
    }
    

    With this code:

    $intHtml = '';
    $extHtml = '';
    $badHtml = '';
    
    // Wrap the map/area info with top level nodes and load into xml object
    $xmlObj = new SimpleXMLElement( $map );
    
    // What does map look like before we start working with it?
    wfDebugLog( 'graphviz', 'map before: ' . $map . "\n" );
    
    // loop through each of the <area> nodes
    foreach($xmlObj->area as $areaNode) {
    
        wfDebugLog( 'graphviz', "areaNode: " . $areaNode->asXML() . "\n" );
    
        // Get the data from the XML attributes
        $hrefValue = (string)$areaNode->attributes()->href;
        $textValue = (string)$areaNode->attributes()->title;
    
        wfDebugLog( 'graphviz', '$hrefValue before: ' . $hrefValue . "\n" );
        wfDebugLog( 'graphviz', '$textValue before: ' . $textValue . "\n" );
    
        // For the text fields, multiple spaces ("   ") in the Graphviz source (label)
        // turns into a regular space followed by encoded representations of
        // non-breaking spaces (" &#xA0;&#xA0;") in the .map file which then turns
        // into the following in the local variables: ("   ").
        // The following two options appear to convert/decode the characters
        // appropriately. Leaving the lines commented out for now, as we have
        // not seen a graph in the wild with multiple spaces in the label -
        // just happened to stumble on the scenario.
        // See http://www.php.net/manual/en/simplexmlelement.asxml.php
        // and http://stackoverflow.com/questions/2050723/how-can-i-preg-replace-special-character-like-pret-a-porter
        //$textValue = iconv("UTF-8", "ASCII//TRANSLIT", $textValue);
        //$textValue = html_entity_decode($textValue, ENT_NOQUOTES, 'UTF-8');
    
        // Now we need to deal with the whitespace characters like tabs and newlines
        // and also deal with them correctly to replace multiple occurences.
        // Unfortunately, the \n and \t values in the variable aren't actually
        // tab or newline characters but literal characters '\' + 't' or '\' + 'n'.
        // So the normally recommended regex '/\s+/u' to replace the whitespace 
        // characters does not work.
        // See http://stackoverflow.com/questions/6579636/preg-replace-n-in-string
        $hrefValue = preg_replace("/( |\\\\n|\\\\t)+/", ' ', $hrefValue);
        $textValue = preg_replace("/( |\\\\n|\\\\t)+/", ' ', $textValue);
    
        // check to see if the url matches any of the
        // allowed protocols for external links
        if ( preg_match( '/^(?:' . wfUrlProtocols() . ')/', $hrefValue ) ) {
            // external link
            $parser->mOutput->addExternalLink( $hrefValue );
            $extHtml .= Linker::makeExternalLink( $hrefValue, $textValue ) . ', ';
        }
        else {
            $first = substr( $hrefValue, 0, 1 );
            if ( $first == '\\' || $first == '[' || $first == '/' ) {
                // potential UNC path, wikilink, absolute or relative path
                $hrefValue = '#InvalidLink';
                $badHtml .= Linker::makeExternalLink( $hrefValue, $textValue ) . ', ';
                $textValue = 'Invalid link. Check Graphviz source.';
            }
            else {
                $title = Title::newFromText( $hrefValue );
                if ( is_null( $title ) ) {
                    // invalid link
                    $hrefValue = '#InvalidLink';
                    $badHtml .= Linker::makeExternalLink( $hrefValue, $textValue ) . ', ';
                    $textValue = 'Invalid link. Check Graphviz source.';
                }
                else {
                    // internal link
                    $parser->mOutput->addLink( $title );
                    $intHtml .= Linker::link( $title, $textValue ) . ', ';
                    $hrefValue = $title->getFullURL();
                }
            }
        }
    
        $areaNode->attributes()->href = $hrefValue;
        $areaNode->attributes()->title = $textValue;
    
    }
    
    $map = $xmlObj->asXML();
    
    // The contents of $map, which is now XML, gets embedded
    // in the HTML sent to the browser so we need to strip
    // the XML version tag and we also strip the <map> because
    // it will get replaced with a new one with the correct name.
    $map = str_replace( '<?xml version="1.0"?>', '', $map );
    $map = preg_replace( '#<ma(.*)>#', ' ', $map );
    $map = str_replace( '</map>', '', $map );
    
    // Let's see what it looks like now that we are done with it.
    wfDebugLog( 'graphviz', 'map after: ' . $map . "\n" );
    
    $txt = '' .
        '<table style="background-color:#f9f9f9;border:1px solid #ddd;">' .
            '<tr>' .
                '<td style="border:1px solid #ddd;text-align:center;">' .
                    '<map name="' . $storagename . '">' . $map . '</map>' .
                    '<img src="' . $wgUploadPath . '/graphviz/' . $storagename . '.' . $outputType . '"' . ' usemap="#' . $storagename . '" />' .
                '</td>' .
            '</tr>' .
            '<tr>' .
                '<td style="font:10px verdana;">' .
                    'This Graphviz diagram links to the following pages:' .
                    '<br /><strong>Internal</strong>: ' . ( $intHtml != '' ?  rtrim( $intHtml, ' ,' ) : '<em>none</em>' ) .
                    '<br /><strong>External</strong>: ' . ( $extHtml != '' ?  rtrim( $extHtml, ' ,' ) : '<em>none</em>' ) .
                    ( $badHtml != '' ? '<br /><strong>Invalid</strong>: ' . rtrim($badHtml, ' ,') .
                    '<br /><em>Tip: Do not use wikilinks ([]), UNC paths (\\) or relative links (/) when creating links in Graphviz diagrams.</em>' : '' ) .
                '</td>' .
            '</tr>' .
        '</table>';
    

    Possible enhancements:

    • It would be nice if the list of links below the graph were sorted and de-duped.
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Background I am working with a monad built of a stack of transformers one
Background: I'm working on a single page web app that loads everything through AJAX
Background: I am working on a proposal for a PHP/web-based P2P replication layer for
I have background service which access my SQL Server database. My background service working
Background: I'm working on migrating from SQL Server 2000 to SQL Server 2005. This
Background: working a user q&a site where users logged,etc. What user/visitor data should be
BACKGROUND: I am working with large geometries that will be meshed or broken down
Background: I'm working on a project that's starting out with a large SQL dump
Background: Trevor was working on a test project solely for the purpose of trying
First some background: I'm working on an application and I'm trying to follow MVVM

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.