自定义 parcats plotly.js 图表的悬停

Posted

技术标签:

【中文标题】自定义 parcats plotly.js 图表的悬停【英文标题】:Customise hover of parcats plotly.js chart 【发布时间】:2021-08-28 05:45:11 【问题描述】:

我使用了一个 plotly.js parcats 图表来制作一个连续的 sankey(例如https://github.com/EE2dev/sequence-explorer)。以下是显示测验之间成绩变化的 Parcats 示例:

var trace1 = 
  type: 'parcats',
  hoveron: 'color',
  dimensions: [
    
      label: 'Quiz 1',
      values: ['Black', 'Black', 'Black', 'Brown', 'Brown', 'Brown', 'Red', 'Brown'],
    ,
    
      label: 'Quiz 2',
      values: ['Brown', 'Brown', 'Brown', 'Brown', 'Brown', 'Blue', 'Blue', 'Blue'],
    ,
    
      label: 'Quiz 3',
      values: ['Female', 'Female', 'Female', 'Male', 'Female', 'Male', 'Male', 'Male'],
    ,
  ],
;

var data = [ trace1 ];

var layout = width: 600;

Plotly.newPlot('myDiv', data, layout);

当我将鼠标悬停在一条路径上时,从“测验 1”到“测验 3”的完整路径会突出显示,但我只想突出显示“测验 1”到“测验 2”之间的路径。我尝试将鼠标悬停在上面,但没有任何改变。

这是fiddle

var trace1 = 
  type: 'parcats',
  hoveron: 'color',
  dimensions: [
    
      label: 'Quiz 1',
      values: ['Black', 'Black', 'Black', 'Brown', 'Brown', 'Brown', 'Red', 'Brown'],
    ,
    
      label: 'Quiz 2',
      values: ['Brown', 'Brown', 'Brown', 'Brown', 'Brown', 'Blue', 'Blue', 'Blue'],
    ,
    
      label: 'Quiz 3',
      values: ['Female', 'Female', 'Female', 'Male', 'Female', 'Male', 'Male', 'Male'],
    ,
  ],
;

var data = [ trace1 ];

var layout = width: 600;

Plotly.newPlot('myDiv', data, layout);
<head>
  <!-- Plotly.js -->
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>

<body>
  <div id="myDiv"></div>
</body>

有没有办法自定义悬停功能?

【问题讨论】:

看来你需要一个分割部分的情节,每个部分都有自己的悬停状态。 【参考方案1】:

不幸的是,我认为这在这个特定的 Parcats 图表上是不可能的。

创建此 Parcats 图表时,它会为每个“ROW”生成一个 svg path,当我说“ROW”时,您可以理解它是这样的:

第 1 行:黑色 - 棕色 - 女性 第 2 行:棕色 - 棕色 - 女性 第 3 行:棕色 - 棕色 - 男性 第 4 行:棕色 - 蓝色 - 男性 第 5 行:红色 - 蓝色 - 男性

这样,我们可以说您的图表有 5 个“ROWS”。

正如我之前所说,每个“ROW”都是一个 SVG 路径,如下所示:

<path class="path" stroke-opacity="1" fill="#1f77b4" fill-opacity="0.6"
stroke="lightgray" stroke- d="M 40,0l16,0 C56,0 544,4 544,
4l16,0 C560,4 1048,4 1048,4l16,0 l0,95.25 l -16,0 C1048,99.25 560,
99.25 560,99.25l-16,0 C544,99.25 56,95.25 56,95.25l-16,0 Z"></path>

因此,当您悬停此路径时,它会更改 fill-opacitystrokestroke-width,如下所示:

<path class="path" stroke-opacity="1" fill="#1f77b4" fill-opacity="0.8"
stroke="white" stroke- d="M 40,0l16,0 C56,0 544,4 544,
4l16,0 C560,4 1048,4 1048,4l16,0 l0,95.25 l -16,0 C1048,99.25 560,
99.25 560,99.25l-16,0 C544,99.25 56,95.25 56,95.25l-16,0 Z"></path>

因此,当您将鼠标悬停时,无法仅突出显示“测验 1”到“测验 2”的路径。

您可以在此处使用sankey 图表类型代替:

var trace1 = 
  type: "sankey",
  orientation: "h",
  node:   
   groups: ["Quiz 1", "Quiz 2", "Quiz 3"],
   label: ["Black", "Brown", "Red", "Brown", "Blue", "Female", "Male"],
   color: ["blue", "blue", "blue", "blue", "blue", "blue", "blue"]
  ,
  link: 
    source: [0,1,1,1,2,3,3,3,4,4],
    target: [3,3,3,4,4,5,5,6,6,6],
    value:  [3,1,1,2,1,3,1,1,2,1]
  
;

var data = [ trace1 ];

var layout = 
   title: 
      text:'SANKEY Title',
      font: 
         family: 'Courier New, monospace',
         size: 24
      ,
   ,
   annotations: [
      text: 'QUIZ 1',
      x: 0.0,
      y: 1.1,
      showarrow: false,
      font: size: 12
    , 
    
      text: 'QUIZ 2',
      x: 0.5,
      y: 1.1,
      showarrow: false,
      font: size: 12
    , 
    
      text: 'QUIZ 3',
      x: 1.0,
      y: 1.1,
      showarrow: false,
      font: size: 12
    ],
   width: 600,
;

Plotly.newPlot('myDiv', data, layout);
<head>
  <!-- Plotly.js -->
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>

<body>
  <div id="myDiv"></div>
</body>

如您所见,它与 Parcats 图表不完全一样,但确实可以。

关于此图表的一些信息:

与 parcats 不同,它为图表的每个部分创建一个 svg path,因此每个 path 的突出显示悬停是分开的。

为了清楚起见,第 1 行:黑色 - 棕色 - 女性现在有两个 svg paths,例如:

<!-- Black - Brown PATH -->
<path class="sankey-link" d="M30,1.9895196601282805e-13C603.5,
1.9895196601282805e-13 603.5,15.000000000000114 1177, 15.000000000000114L1177,
105.00000000000011C603.5,105.00000000000011 603.5,90.0000000000002 30,90.0000000000002Z" 
style="stroke: rgb(68, 68, 68); stroke-opacity: 1; fill: rgb(0, 0, 0); fill-opacity: 0.2;
stroke-width: 0; opacity: 1;"></path>

<!-- Brown - Female PATH -->
<path class="sankey-link" d="M1207,15.000000000000114C1780.5,
15.000000000000114 1780.5,15.000000000000142 2354,15.000000000000142L2354,
105.00000000000014C1780.5,105.00000000000014 1780.5,
105.00000000000011 1207,105.00000000000011Z" style="stroke: rgb(68, 68, 68);
stroke-opacity: 1; fill: rgb(0, 0, 0); fill-opacity: 0.2; stroke-width: 0; opacity: 1;"></path>

此图表需要有Link 字段,带有特定值(sourcetargetvalue)。您可以查看有关此选项的更多信息here。

您可以编辑和自定义此图表中的标签。您可以通过here 和here 了解更多信息。

【讨论】:

是否可以像parcats一样在每个级别添加Quiz 1,Quiz 2,Quiz 3标签? @orbital,我相信不可能为每个级别添加标签。但是您可以通过解决方法来实现这一点 - > layout 对象内的 annotations 属性。我已经更新了图表代码sn-p,你可以查看一下。 谢谢@luis-paulo-pinto 试图找出如何给你赏金 我很高兴您对解决方案感到满意!关于赏金,基本上您只需将答案设置为已接受,单击答案旁边的复选标记将其从灰色切换为填写(更多信息here)。关于赏金,您可以查看更多信息here。【参考方案2】:

据我了解,Parallel Categories Diagram 旨在处理整行,它无法选择单个线段。

但是,还有另一个图表看起来相似,但侧重于各个细分市场。这是Sankey Diagram。但它需要重新排列原始数据,以准确指示各个值在每个段上的变化情况。

    type参数设置为sankey。 在label 参数中,我们按顺序列出图表中出现的所有值。 首先是第一个测验(BlackBrownRed),然后是第二个(BrownBlue),最后是第三个(FemaleMale)。 因此,我们将所有值转换为数组元素,因此我们可以通过它们的不规则访问它们。 例如,第一个测验中的 Brown 的索引为 1,第二个测验中的 Brown 的索引为 3 (数组中的索引从零开始)。 然后我们在sourcetarget 参数中使用这些索引。 link 中的值描述了图中的所有段。 为方便起见,我将它们排列成列。 例如,第一列0, 3, 3 表示Quiz 1 中的Blacksource 中的索引0)和Quiz 2 中的Blacktarget 中的索引3)具有3 名参与者(3 中的value)。

例如:https://jsfiddle.net/glebkema/subnqp8v/

var trace1 = 
  type: 'sankey',
  node: 
    pad: 15,
    thickness: 20,
    line: 
      color: "black", 
      width: 0.5
    ,
    label: [
      'Black', 'Brown', 'Red',  // Quiz 1
      'Brown', 'Blue',          // Quiz 2
      'Female', 'Male'          // Quiz 3
    ],
    color: "blue",
  ,
  link:      
    //        Quiz 1 -> Quiz 2                  Quiz 2 -> Quiz 3 
    //        Quiz 1: Black Brown Red  Brown    Quiz 2: Brown  Brown Blue
    source: [         0,    1,    1,   2,               3,     3,    4   ],
    //        Quiz 2: Brown Brown Blue Blue     Quiz 3: Female Male  Male    
    target: [         3,    3,    4,   4,               5,     6,    6   ],
    value:  [         3,    2,    2,   1,               4,     1,    3   ],
  ,
;

var data = [ trace1 ];

var layout = width: 600;

Plotly.newPlot('myDiv', data, layout);
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>

<div id="myDiv"></div>

【讨论】:

以上是关于自定义 parcats plotly.js 图表的悬停的主要内容,如果未能解决你的问题,请参考以下文章

图表没有响应-react-plotly.js

使用 Plotly.js 自定义垂直线

如何在 plotly.js 图表中添加彩色背景条

自定义外观 plotly.js 图例

使用 Plotly.js 在 3D 图中绘制 2D 平面

如何在 plotly.js 中添加针或刻度盘来测量指示器?