ras0q / obsidian-graph-banner

An Obsidian plugin to display a local graph view to the note header.
MIT License
26 stars 0 forks source link

[Feature Request] Add Customizable Graph Position Options and Visibility Toggle for Enhanced Visualization #40

Open PandaNocturne opened 2 weeks ago

PandaNocturne commented 2 weeks ago

Thank you for your work on this plugin. It has been extremely helpful for Obsidian's local graph feature.However, I would like to move the graph to the top right corner of the note interface, similar to the publish layout.

Here is a small adjustment I made to your Styles.css file:

image

PixPin_2024-06-22_00-55-22

/* https://github.com/mgmeyers/obsidian-style-settings */
/* @settings
name: Graph Banner
id: graph-banner
settings:
  - id: hide-graph-banner
    title: Hide Graph Banner
    type: class-toggle
    addCommand: true
  - id: graph-banner-type-select
    title: Select graph type
    type: class-select
    allowEmpty: false
    default: banner-graph
    options:
      - banner-graph
      - hanging-graph
  - id: banner-height
    title: Banner Height
    description: The height of the banner. (e.g. 20vh, 200px)
    type: variable-text
    default: 20vh
  - id: banner-width
    title: Banner Width
    description: The width of the banner. (e.g. 20vh, 200px)
    type: variable-text
    default: 400px
*/

body {
  --banner-height: 20vh;
  --banner-width: 400px;
}

body.hide-graph-banner .graph-banner-content {
  display: none !important;
}

.banner-graph .graph-banner-content {
  width: auto;
  height: var(--banner-height);
  margin-bottom: 16px;
}

.hanging-graph .cm-sizer>div.view-content.graph-banner-content,
.hanging-graph .mod-header>div.view-content.graph-banner-content {
  display: block;
  position: fixed !important;
  right: 50px;
  top: 50px;
  z-index: 2;

  border-radius: 10px;
  border: 1px solid var(--background-modifier-border);
  width: var(--banner-width);
  height: var(--banner-height);
  margin-bottom: 16px;
}

I added two types of graph display modes:

  1. banner-graph - retains the original display.
  2. hanging-graph - positions the graph at the top-right corner of the note interface.

Additionally, I also added a CSS class toggle control using the Style Settings plugin to manage the visibility of the graph banner. The .hide-graph-banner class can be toggled using Obsidian commands, which could be useful with the Commander plugin.

I'd love it if you could consider adding this CSS modification to your plugin. I think it would offer an even richer visualization experience. Thanks again for all your hard work on this plugin!

PandaNocturne commented 2 weeks ago

Of course, if my modifications do not align with your original design intent, then let it remain unchanged. I will use it as it is.

PandaNocturne commented 1 week ago

I discovered through developer mode that in reading mode, the functions prototype.detach and Node.prototype.setChildrenInPlace would delete the mod-header element, causing the graph-banner to disappear. To solve this issue, I overrode these two functions to skip the check for the mod-header element and load them in onload(). This way, in my reading mode, the graph-banner can always be displayed. Since I am not very knowledgeable about computers, these modifications were made with the help of GPT, so I cannot guarantee that there won't be any issues, but so far, testing has not revealed any problems.

Node.prototype.detach = function() {
  if (this.classList && this.classList.contains('mod-header')) {
      // console.log('Skipping detach for mod-header:', this);
      return;
  }
  this.parentNode && this.parentNode.removeChild(this);
};

Node.prototype.setChildrenInPlace = function(t) {
  for (var e = this.firstChild, n = new Set(t), r = 0, o = t; r < o.length; r++) {
      for (var i = o[r]; e && !n.has(e); ) {
          var s = e;
          e = e.nextSibling;
          // console.log('Node classList:', s.classList);
          if (s.nodeType === 1 && s.classList.contains('mod-header')) {
              // console.log('Skipping node with mod-header:', s);
          } else {
              this.removeChild(s);
          }
      }
      i !== e ? this.insertBefore(i, e) : e = e.nextSibling;
  }
  for (; e; ) {
      s = e;
      e = e.nextSibling;
      if (s.nodeType === 1 && s.classList.contains('mod-header')) {
          // console.log('Skipping node with mod-header:', s);
      } else {
          this.removeChild(s);
      }
  }
};