GEOLYTIX / xyz

An open source javascript framework for spatial data and application interfaces.
MIT License
87 stars 25 forks source link

Remove default dataviews imports; Allow for dynamic dataviews. #1333

Closed dbauszus-glx closed 2 months ago

dbauszus-glx commented 3 months ago

The dataview methods have been revised and are now fully documented.

The dataview chart and tabulator modules require plugins and have been removed from the ui.utils.

The dataview plugin specific configuration wiki should be moved to a wiki with the relevant plugins.

The dataview.create method is not required to be async with dataview plugins loading the required third party libraries.

The location and layer dataviews are essentially the same. A location must have a layer which is assigned as the dataview layer by the dataview location entry method.

The should not be duplicate code between the location and layer dataview methods.

The display and hide dataview methods are assigned in the dataview creation itself.

The dataview create method defines whether a dataview has already been created. The dataview create method can be used to re-create a dataview but this requires a change to the dataview plugin. The target element children must be replaced rather than appended.

dbauszus-glx commented 3 months ago

@AlexanderGeere This should be resolved in https://github.com/GEOLYTIX/xyz/pull/1333/commits/5dd0cf46c119ef621b69b18d807192c6c7ca4d1b

The issue was that chatjs library wasn't loaded. The checkDataview method must assign and return the error.

The location entry and layer [panel] dataview methods must return if the dataview creation errs.

image

dbauszus-glx commented 3 months ago

The dataview decorator method creates a typedef:dataview which is added to the global in the ui/Dataview module.

Within the mapp core code the mapp.ui.Dataview() method is only called from the dataview locations entry or the dataviews layer panel.

A dataview from a layer panel is assumed to be in tab[view].

A dataview show and hide method for tabview display are assigned before the Dataview is decorated.

The show method will create the tab when first called. The addTab event method will sortcircuit if a tab has already been created. The dataview.hide() method will call the tab.remove() method.

    dataview.show ??= () => {

      // Create tab after dataview creation is complete.
      dataview.tabview.dispatchEvent(new CustomEvent('addTab', {
        detail: dataview
      }))

      // Show the dataview tab.
      dataview.show()
    }

    dataview.hide ??= () => {

      dataview.display = false

      dataview.remove()
    }

    if (mapp.ui.Dataview(dataview) instanceof Error) return;

    // Display dataview if layer and dv have display flag.
    layer.display
      && dataview.display
      && dataview.show()

    layer.showCallbacks.push(()=>{
      dataview.display && dataview.show()
    })

In the location entry method the tabview is created if defined before the dataview is created. This will assign the tab.show() and tab.hide() methods to the dataview object. The dataview is a tabview as well as a dataview. The dataview will be created/updated in the activate event for the panel. This is debounced to only create a dataview in an active panel and not n dataviews all at once if multiple tabs are added on the initial load.

  // Find tabview element from data-id attribute.
  entry.tabview ??= typeof entry.target === 'string'
    && document.querySelector(`[data-id=${entry.target}]`)

  // Dataview will be rendered into a tabview panel.
  if (entry.tabview) {

    // Assign border style based on the location view record (from list)
    entry.tab_style ??= `border-bottom: 3px solid ${entry.location.style.strokeColor}`

    // Assign target html element for dataview.
    entry.target = mapp.utils.html.node`
      <div class="dataview-target">`

    // Create tab after dataview creation is complete.
    entry.tabview.dispatchEvent(new CustomEvent('addTab', {
      detail: entry
    }))

  } else {

    // Dataview will be rendered into location view.
    entry.locationViewTarget = mapp.utils.html.node`
      <div class="${`location ${entry.class}`}">`

    entry.target = entry.locationViewTarget
  }

  if (mapp.ui.Dataview(entry) instanceof Error) return;

  // Dataview should be displayed.
  entry.display && entry.show()
dbauszus-glx commented 2 months ago

@AlexanderGeere The activate method is now assigned in the addTab as a function to be debounced rather than using the dispatch event.

dbauszus-glx commented 2 months ago

@simon-leech

I remove the warning if the dataview type isn't implicit but can be inferred from table or chart object entry.

I assign the key from query/title/label if not implicit to help identifying the dataview in error message.

I assign an update method with a warning to prevent the update query crashing the script execution.

simon-leech commented 2 months ago

Toggling the display of a dataview from an infoj entry in the tabview works to add to the tabview. But then toggling the checkbox to false, the dataview is removed from display within the tabview tab, but the tab itself is not removed.

In custom views if the tabulator/ chartjs plugins are not loaded I see errors / warnings. This is a divergence from the existing set up so needs to be well explained / perhaps a point release as it is technically a breaking change. image

dbauszus-glx commented 2 months ago

@dbauszus-glx the issue with tabs not hiding has been resolved in last commit. The hide [dataview] method must be overwritten with the remove tabview method.

simon-leech commented 2 months ago

queryCheck does not work as it previously did. Previously if no data was returned the checkbox was disabled. Now it returns a No Data message - is this expected / what we want to do?

Arguably, I actually think it's clearer for the user anyway to show a No Data Message. But just need to make sure this is dictionary term.

But wonder if we even need querycheck flag after this? As if it shows No Data with or without that flag it has no use.

dbauszus-glx commented 2 months ago

We can alter the behaviour but I need to understand what the queryCheck flag should do?

The current behaviour for an entry with queryCheck is that the query will be executed and the data stored as value.

Then a tabview will be created if the checkbox is clicked, and the dataview will be created. The query will be run again because the update query is run after the dataview is created.

dbauszus-glx commented 2 months ago

@simon-leech I added the check to disable the dataview entry with querycheck:true and null response.