当我将内联代码放入外部子例程时,相关区域的图像地图突出显示停止工作

Posted

技术标签:

【中文标题】当我将内联代码放入外部子例程时,相关区域的图像地图突出显示停止工作【英文标题】:image map highlighting of associated areas stops working when I take inline code into an external subroutine 【发布时间】:2021-01-12 19:14:09 【问题描述】:

我有 4 个动态生成 PNG 彩色图像映射的模块。所有 4 项都按设计工作,包括突出显示其价值/比率测量数据按四分位数组织的颜色图区域集(例如州县)。

所有 4 人共享一个内联代码块。该块产生一个由 4 个元素组成的数组(将其命名为“rels”)。每个元素可能包含一串以逗号分隔的区域名称。元素的区域名称对应于其价值/比率测量数据落在范围四分位数结构的该四分位数的区域。

当我将共享内联代码块放入外部子程序时,上面提到的突出显示在 4 个模块中的 3 个模块中停止工作。使用我正在构建的 1 个浏览器的“检查元素”,我已经验证了内联代码和子例程在所有四个模块中产生相同的结果,并且使用了 rels 数组的 4 个元素的标签(rel='rels[0]') 在相应的 rels 元素中具有正确的内容。

我使用 mapper.js 来突出显示单个区域和区域集。它总是工作得很好。当我将代码块放入子例程时,单个区域突出显示在所有 4 个模块中继续工作,但正如我上面所说,在 4 个模块中的 3 个模块中停止突出显示区域集。我将我放入子程序的块放回内联,突出显示再次起作用。我把代码块放回外部子程序,4组区域的高亮再次停止工作。

就像标签一样,使用rels数组的地方,从子程序返回时就再也看不到它了,即使它在那里。我实际上返回了一个指针并使用它来获取数组,并且按预期工作。颜色图区域的 4 个元素的数组在所有 4 个模块中正确地从子程序返回,并且 4 个元素中的每个元素中的区域与代码块内联时相同。

我想更好地理解这一点。我不确定如何进行。我为这个应用程序编写了很多外部子例程,它们返回在图像映射代码中使用的数组和散列,没有任何问题。我现在感觉有点卡在这个上。任何建议表示赞赏。感谢您的宝贵时间。

克雷格

以下是来自模块 1 的内联块、子例程调用、子例程和使用 rels 数组的图像映射过程。语言是 Perl。

内联块:

@rels = ();
  $rels[0] = '';$rels[1] = '';$rels[2] = '';$rels[3] = '';
  $lowqtile = '';   
  foreach $key (@counties) 

    $keyhld = $key;
    $key = lc($key);
    $dval = $cdvals$key;

    if (defined $cdvals$key)  # Has a value.

      if ($direct eq 'i')         

        if ($dval <= $q1) 
          $rels[0] .= $key . ','; # List of areas in this quartile.
          $lowqtile .= $keyhld . ':';
          $ccolors$key=$colors2[3];
         elsif ($dval > $q1 && $dval <= $q2) 
            $rels[1] .= $key . ',';
            $ccolors$key=$colors2[2];
           elsif ($dval > $q2 && $dval <= $q3) 
              $rels[2] .= $key . ',';
              $ccolors$key=$colors2[1];
             else 
                $rels[3] .= $key . ',';
                $ccolors$key=$colors2[0]; # > $q3 - best.
                             

       elsif ($direct eq 'd')           

          if ($dval >= $q1) 
            $rels[0] .= $key . ',';
            $lowqtile .= $keyhld . ':';
            $ccolors$key=$colors2[3];
           elsif ($dval >= $q2 && $dval < $q1) 
              $rels[1] .= $key . ',';
              $ccolors$key=$colors2[2];
             elsif ($dval >= $q3 && $dval < $q2) 
                $rels[2] .= $key . ',';
                $ccolors$key=$colors2[1];
               else 
                  $rels[3] .= $key . ',';
                  $ccolors$key=$colors2[0]; # < $q3 - best.
                          

         else             
           
            if ($dval >= $q3 || $dval < -$q3) 
              $rels[0] .= $key . ',';
              $lowqtile .= $keyhld . ':';
              $ccolors$key=$colors2[3];
             elsif (($dval>=$q2 && $dval<$q3)||($dval<=-$q2 && $dval>-$q3)) 
                $rels[1] .= $key . ',';
                $ccolors$key=$colors2[2];
               elsif (($dval>=$q1 && $dval<$q2)||($dval<=-$q1 && $dval>-$q2)) 
                  $rels[2] .= $key . ',';
                  $ccolors$key=$colors2[1];
                 else 
                    $rels[3] .= $key . ',';
                    $ccolors$key=$colors2[0]; # < $q1 || > -$q1 - best.
                               

           # Goal. 

     else 
        $ccolors$key = 'white'; # NA.
      

   # foreach.

  $i = 0;
  foreach $key (@rels)     
    if (index($key,',') > -1) 
      $rels[$i] = substr($rels[$i],0,length($rels[$i])-1);
         
    $i++;
  

  $lowqtile = substr($lowqtile,0,length($lowqtile)-1); # Strip last colon.

子程序调用:

# Set the base level rels array (used in quartile area coloring), the low quartile string of keys in that quartile used to color colormap data, and color code by key.

($lowqtile, $relsPtr, $cclrPtr) = gtclrStf($direct, $q1, $q2, $q3, $q4, \@counties, \%cdvals, \@colors2); # Preferred behavior, quartile bounds, and county, data, quartile colors in.
@rels = @$relsPtr; # Get array/hash from references.
%ccolors = %$cclrPtr; # Color codes by area. 

子程序:

sub gtclrStf 

  my ($lowqtilex, $keyx, $keyhldx, $directx, $areasPtr, $avalsPtr, $qclrsPtr); # Scalars.

  my ($dvalx, $q1x, $q2x, $q3x, $q4x, $ix); # Numerics.

  my (@relsx, %aClrs, @areas, %avals, @qClrs); # Arrays/hashes.

  ($directx, $q1x, $q2x, $q3x, $q4x, $areasPtr, $avalsPtr, $qclrsPtr) = @_;
  @areas = @$areasPtr; # Get arrays from references.
  %avals = %$avalsPtr; 
  @qClrs = @$qclrsPtr;
  

  @relsx = ();
  $relsx[0] = '';$relsx[1] = '';$relsx[2] = '';$relsx[3] = '';
  $lowqtilex = '';   
  foreach $keyx (@areas) 

    $keyhldx = $keyx;
    $keyx = lc($keyx);
    $dvalx = $avals$keyx;

    if (defined $avals$keyx)  # Has a value.

      if ($directx eq 'i')         

        if ($dvalx <= $q1x) 
          $relsx[0] .= $keyx . ','; # List of areas in this quartile - used in area grouping.  
          $lowqtilex .= $keyhldx . ':'; # Used in colormap data highlighting.
          $aClrs$keyx=$qClrs[3];
         elsif ($dvalx > $q1x && $dvalx <= $q2x) 
            $relsx[1] .= $keyx . ',';
            $aClrs$keyx=$qClrs[2];
           elsif ($dvalx > $q2x && $dvalx <= $q3x) 
              $relsx[2] .= $keyx . ',';
              $aClrs$keyx=$qClrs[1];
             else 
                $relsx[3] .= $keyx . ',';
                $aClrs$keyx=$qClrs[0]; # > $q3x - best.
                             

       elsif ($directx eq 'd')           

          if ($dvalx >= $q1x) 
            $relsx[0] .= $keyx . ',';
            $lowqtilex .= $keyhldx . ':';
            $aClrs$keyx=$qClrs[3];
           elsif ($dvalx >= $q2x && $dvalx < $q1x) 
              $relsx[1] .= $keyx . ',';
              $aClrs$keyx=$qClrs[2];
             elsif ($dvalx >= $q3x && $dvalx < $q2x) 
                $relsx[2] .= $keyx . ',';
                $aClrs$keyx=$qClrs[1];
               else 
                  $relsx[3] .= $keyx . ',';
                  $aClrs$keyx=$qClrs[0]; # < $q3x - best.
                          

         else             
           
            if ($dvalx >= $q3x || $dvalx < -$q3x) 
              $relsx[0] .= $keyx . ',';
              $lowqtilex .= $keyhldx . ':';
              $aClrs$keyx=$qClrs[3];
             elsif (($dvalx >= $q2x && $dvalx < $q3x) || ($dvalx <= -$q2x && $dvalx > -$q3x)) 
                $relsx[1] .= $keyx . ',';
                $aClrs$keyx=$qClrs[2];
               elsif (($dvalx >= $q1x && $dvalx < $q2x) || ($dvalx <= -$q1x && $dvalx > -$q2x)) 
                  $relsx[2] .= $keyx . ',';
                  $aClrs$keyx=$qClrs[1];
                 else 
                    $relsx[3] .= $keyx . ',';
                    $aClrs$keyx=$qClrs[0]; # < $q1 || > -$q1 - best.
                               

           # Goal. 

     else 
        $aClrs$keyx = 'white'; # NA.
      

   # foreach.

  $ix = 0;
  foreach $keyx (@relsx)  # Eliminate trailing comma if there.    
    if (index($keyx,',') > -1) 
      $relsx[$ix] = substr($relsx[$ix],0,length($relsx[$ix])-1);
       
    $ix++;
    

  $lowqtilex = substr($lowqtilex,0,length($lowqtilex)-1); # Strip last colon.

  return $lowqtilex, \@relsx, \%aClrs; # Return array of keys in each quartile pointer, low quartile keys string, and colors array by area pointer.


使用 rels 数组的图像映射过程(第一个 4 个区域标签)。

print"<DIV STYLE='POSITION:absolute;LEFT:$rpos;'><IMG SRC='$filex' WIDTH='600' HEIGHT='265' USEMAP='#cmap' STYLE='POSITION:absolute;LEFT:$rpos;' CLASS='mapper $cmabrdr iopacity$colrmapcolr9 icolor$colrmapcolr8'></DIV>\n";
  print"<MAP NAME='cmap'>\n";

  if (!$simflg)         
    print"<AREA shape='circle' CLASS='$cmabrdr iopacity$colrmapcolr9 icolor$colrmapcolr1' ID='q1' rel='$rels[3]' TITLE='quartile 1' HREF='#' coords='555,50,8'>
          <AREA shape='circle' CLASS='$cmabrdr iopacity$colrmapcolr9 icolor$colrmapcolr2' ID='q2' rel='$rels[2]' TITLE='quartile 2' HREF='#' coords='565,70,8'>
          <AREA shape='circle' CLASS='$cmabrdr iopacity$colrmapcolr9 icolor$colrmapcolr3' ID='q3' rel='$rels[1]' TITLE='quartile 3' HREF='#' coords='575,90,8'>
          <AREA shape='circle' CLASS='$cmabrdr iopacity$colrmapcolr9 icolor$colrmapcolr4' ID='q4' rel='$rels[0]' TITLE='quartile 4' HREF='#' coords='585,110,8'>
          \n";
    
  
  $gstr = '';
  foreach $key ( @counties ) 

    $keylc = lc($key);
    $surtok = 'x' . $keylc;
    $surtok =~ s/ +//g;
    $uckey = $key;
    $uckey =~ s/\b(\w)(\w*)/uc($1).lc($2)/ge; # Uppercase 1st word letters.   

    if (!$simflg) 
      if (defined $cdvals$keylc)  
        print"<AREA ID='$key' HREF='$curls$keylc' SHAPE='POLY' COORDS='$ccoords$keylc' TITLE='$keystr$keylc -\r\nClick For The $uckey $blev $dcname Trend' ONMOUSEOVER=\"showIt('$surtok');setStatus(' ');\" ONMOUSEOUT=\"hideIt('$surtok');setStatus(' ');\">\n";   
       else 
          print"<AREA ID='$key' SHAPE='POLY' COORDS='$ccoords$keylc' TITLE='$keystr$keylc' ONMOUSEOVER=\"setStatus(' ');\" ONMOUSEOUT=\"setStatus(' ');\">\n";
        
     else 
        print"<AREA ID='$key' SHAPE='POLY' COORDS='$ccoords$keylc' TITLE='$keystr$keylc' ONMOUSEOVER=\"setStatus(' ');\" ONMOUSEOUT=\"setStatus(' ');\">\n";   
      
    
    if (!$simflg && defined $cdvals$keylc)     
      $j = allSame(1, $vlus$surtok);        
      $k = allSame(2, $rts$surtok);         
      
      if (exists($vlus$surtok)) 
        $gstr .= "<DIV ID='$surtok'><A ONMOUSEOVER=\"setStatus('Value and Rate Trends');\" ONMOUSEOUT=\"setStatus('  ');\"><SPAN ID='slhdr$surtok' STYLE='POSITION:absolute;TOP:28.5%;LEFT:$lpos;FONT-SIZE:9px;BACKGROUND-COLOR:#$ltappbgcolr;FONT-FAMILY:arial;'>$uckey v/r Trends<BR></SPAN><SPAN ID='slx$surtok' STYLE='POSITION:absolute;TOP:$tpos;LEFT:$lpos;BACKGROUND-COLOR:#$ltappbgcolr;BORDER:1px dashed lightgray;PADDING-TOP:$tpads;'>&nbsp;<SPAN CLASS='inlinesparkline$j' TITLE='Value Trend' ONMOUSEOVER=\"setStatus('Value Trend');\" ONMOUSEOUT=\"setStatus(' ');\">$vlus$surtok</SPAN>&nbsp;&nbsp;<SPAN CLASS='inlinesparkline$k' TITLE='Rate Trend' ONMOUSEOVER=\"setStatus('Rate Trend');\" ONMOUSEOUT=\"setStatus(' ');\">$rts$surtok</SPAN>&nbsp;</SPAN></A></DIV><SCRIPT>hideIt('$surtok');</SCRIPT>";              
      
         

   

  print"</MAP>\n";

正如我上面所说,我已经验证了 rels 数组的内容在所有 4 个模块中的内联代码块和子例程中使用数组的区域标记处是相同的。并且区域集的突出显示在所有 4 个模块中都使用内联块。我将内联块放入子例程并使用指针/引用将数组从例程中传递出去,区域集的突出显示在 4 个模块中的 3 个模块中不再起作用。

以下是在我家的服务器上运行的链接。它是与子程序中的代码一起工作的第一个模块。您可以通过将鼠标悬停在颜色图右侧的 4 个圆圈中的任何一个上来查看区域集突出显示。

colormap example with subroutine where highlighting works

所有数据仅用于测试目的。

更新:我很沮丧。我已经尝试了很多事情,但无法在这上面移动球。我已经比较了当 rels 数组来自外部子例程时区域设置突出显示工作的模块与不在该配置中的 3 个模块。我查看了 3 个模块,其中区域设置突出显示在 rels 数组从外部子例程中出来时退出工作,并在子例程内联时工作。我列出了我所知道的以下内容。

    尽管所有 4 个模块在许多方面都相似,但也存在显着差异。但我认为这些差异中的任何一个都不会影响此行为不起作用的 3 个模块中突出显示的区域集。

    不工作的 3 个模块可能还有 10 个其他子例程传递标量。数组,并散列进出该工作。

    对于区域设置突出显示的 3 个模块,当 rels 数组从外部子例程出来时退出工作,而在子例程内联时工作,rels 数组内容对于两种配置中的所有三个模块都是相同的。

    rels 数组在它从子程序(或内联代码)出现的位置和在图像映射的第 4 个区域标记集中使用的位置之间没有被触及。

    区域地图图像和区域html在子程序配置中的所有4个模块中完全相同,除了图像地图的名称,用户悬停查看区域设置突出显示的圆坐标,以及区域中的区域rels 数组元素对应的彩色四分位数。

    将鼠标悬停在区域集突出显示的链接(圆圈)上是子程序配置中所有3个模块中的所有活动链接,但是当我将鼠标悬停时,区域集没有突出显示。

    单个区域的悬停行为继续在子程序配置中的所有 3 个模块中起作用。

我想弄清楚这一点。我想我可以说至少它可以在内联配置中工作,但这不是应该的工作方式。我没有看到它,但我还在寻找。任何有关这方面的建议将不胜感激。

感谢您的宝贵时间。 克雷格

【问题讨论】:

请分享您的代码。 ***.com/help/minimal-reproducible-example kmoser,我无法添加代码。语言是 Perl。出于某种原因,它拆分了代码。它将一部分放在可滚动区域之前,一部分放在可滚动区域中,一部分放在之后。我已经尝试过 和
 和 cntl K 几次。我做错了什么?
为简单起见,输入一行开头三个反引号,然后在下一行粘贴您的代码,然后在下一行输入三个反引号。有关更多选项,请参阅meta.stackexchange.com/questions/22186/… 【参考方案1】:

我有一些其他的优先事项让我暂时远离这个问题,有一些可行的方法。我认为问题在 5 中一定是不正确的,其中突出显示的区域集不起作用,并且在 1 中确实可以正常工作。这里的问题是不匹配的哈希键。这个问题涉及的六个模块中的每一个模块都有 9 个哈希值。在突出显示的区域集起作用的 1 个模块中,所有键跨哈希匹配。其他 5 个模块有 1 个哈希键不匹配。我花了一段时间才看到它,我的问题描述反映了我缺乏理解。现在所有 6 个模块都可以正常工作。感谢所有看到这个的人。此问题已解决。

【讨论】:

以上是关于当我将内联代码放入外部子例程时,相关区域的图像地图突出显示停止工作的主要内容,如果未能解决你的问题,请参考以下文章

在不同的私有子例程中使用公共声明的数组时下标超出范围

使用 GCC 对模块内的 fortran 子例程进行外部命名

使用 GCC 对模块内的 fortran 子例程进行外部命名

使用OpenMP从Fortran子例程中导致错误的结果和崩溃

九十SAP中ALV事件之四,事件子例程的参数

模块化程序-子例程