Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Customise hover of parcats plotly.js chart

I've used a plotly.js parcats chart to make a sequential sankey (eg https://github.com/EE2dev/sequence-explorer). Here are the example parcats that shows changes in grades between quizzes:

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);

When I hover over a path the full path from 'Quiz 1' to 'Quiz 3' highlights but what I'd like is for only the path between 'Quiz 1' to 'Quiz 2' to highlight. I tried hover on but nothing changed.

This is the 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>

Is there a way to customize the hover functionality?

like image 565
orbital Avatar asked Jun 11 '21 09:06

orbital


1 Answers

Unfortunately, I believe that's not possible on this specific parcats ploty chart.

When this parcats chart is created, its generate an svg path for each "ROW", and when i say "ROW" you can understand it being like this:

  • Row 1: Black - Brown - Female
  • Row 2: Brown - Brown - Female
  • Row 3: Brown - Brown - Male
  • Row 4: Brown - Blue - Male
  • Row 5: Red - Blue - Male

This way, we can say that your chart has 5 "ROWS".

And as I said before, each of this "ROW" is a SVG path, like this:

<path class="path" stroke-opacity="1" fill="#1f77b4" fill-opacity="0.6"
stroke="lightgray" stroke-width="0.2" 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>

So, when you hover this path, it changes fill-opacity, stroke and stroke-width, like this:

<path class="path" stroke-opacity="1" fill="#1f77b4" fill-opacity="0.8"
stroke="white" stroke-width="0.3" 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>

Therefore, its not possible to highlight only paths 'Quiz 1' to 'Quiz 2' when you hover it.

What you can do here, is use the sankey chart type instead:

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>

As you can see, isn't exactly like the parcats chart, but it does the job.

Some infos about this chart:

  • Unlike parcats, it creates an svg path for each part of the chart, so the highlight hover is separated for each path.

Just to be clear, the Row 1: Black - Brown - Female has now TWO svg paths, like:

<!-- 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>
  • This chart need to have the Link field, with the specific values (source, target and value). You can check more about this option here.

  • You can edit and customize the labels in this chart. You can check more about it here and here.

like image 86
Luis Paulo Pinto Avatar answered Sep 18 '22 17:09

Luis Paulo Pinto