Determine state changes of Plotly.js Sunburst chart
P粉659516906
P粉659516906 2023-08-31 20:42:38
0
1
475
<p>I have a React application in which I use plotly.js to display a sunburst chart. I have other actions/components that change based on the "zoom state" of the sunburst chart. For example, if I zoom out completely, the burst chart shows 4 concentric circles. If I click on the second circle from the center it zooms in and then there are only 3 concentric circles. I thought I could determine the status via a click handler, but that doesn't seem straightforward. </p> <p>The state I'm interested in is actually what is visible, and to what depth (how many concentric circles there are). </p> <p>I was hoping to find some callbacks or something that reflects the state, but all I found was a click handler for the sunburst chart (reference https://github.com/plotly/react-plotly.js/blob /master/README.md#event-handler-props-onSunburstClick, https://community.plotly.com/t/capturing-sunburst-on-click-events/32171)</p> <p>The problem is that it's hard to infer state from clicks. Clicking on a paragraph changes state in different ways. If I click on the outermost paragraph, it doesn't change state at all. If I click on the innermost circle, it may zoom in or out depending on what paragraph is currently displayed in the innermost circle. </p> <p> Someone on codepen has an example based on this code: </p> <pre class="brush:php;toolbar:false;">Plotly.newPlot('graph', [{ type: 'sunburst', parents: ['', 'Root', 'Root', 'A'], labels: ['Root', 'A', 'B', 'a'] }]).then(gd => { gd.on('plotly_sunburstclick', console.log) })</pre> <p>If you go there and click 'A', you'll go into a state where 'A' is the center circle and 'a' is the outer circle. If you click on 'A' again, then you will get 'root' as the center circle. To the click handler, the two clicks look basically the same, but the resulting status (which is the part I care about) is different. In my case I tried some heuristics to infer whether it was scaling up or down, but nothing I tried worked consistently. </p> <p>I've searched for a solution but the closest thing I've found so far is a click handler, which after some effort didn't solve my problem. If there's already an answer, that's great, but please don't be too quick to mark a question as a duplicate without being sure if it's already been solved. I see a lot of questions being marked as duplicates where the answers mentioned don't actually address the new question, while the discussion and any attempt to answer the actual question is effectively closed. </p> <p> I should add that I don't necessarily have to use plotly.js, and if there are other libraries for React that might solve my problem, I'm open to suggestions. </p>
P粉659516906
P粉659516906

reply all(1)
P粉811349112

In this case, the click event ultimately triggers a behavior similar to a "switch".

By default, we see the root node and all child nodes of the hierarchy.

  • Clicking on a ring with at least one child node (e.g. 'A') will filter out its parent node ('Root') and sibling node ('B') and visually treat the ring as a new For the root node, we only see the hierarchy under the ring (that is, the ring filtering switch is turned on, and the attribute nextLevel in the event data is set to 'A' accordingly, such as "A is the new root node") .

  • Clicking on the ring again - now the innermost ring - turns off the filter and the parent and sibling nodes reappear, nextLevel is set to 'Root'.

  • Clicking on a ring with no child nodes (e.g. 'a' or 'B') has no effect, so nextLevel is undefined in this case.

In fact, the attribute nextLevel reflects the change of state.

Now to better understand what's going on in the click handler, you might want to check the currentpath (or for consistency, a slightly tweaked version) as well as the nextLevel Existence/value:

Plotly.newPlot('graph', [{
  type: 'sunburst',
  parents: ['', 'Root', 'Root', 'A'],
  labels: ['Root', 'A', 'B', 'a']
}]).then(gd => {
  gd.on('plotly_sunburstclick', data => {
    const pt = data.points[0]
    const path = ((pt.currentPath ?? '/') + pt.label).replace('Root', '')
    console.log('path:', path)                // 点击元素的路径
    console.log('nextLevel:', data.nextLevel) // 如果有的话,新根节点的标签
  })
})
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template