pandafulmanda / brainbrowser-minimal-example

Minimal BrainBrowser example, BrainBrowser -- https://brainbrowser.cbrain.mcgill.ca
0 stars 4 forks source link

Example Schema #3

Open akeshavan opened 7 years ago

akeshavan commented 7 years ago
{
model_timepoints: {0: {
                                     left_hemi: {model: "/path/to/model_file/tp0",
                                                       intensity:"/path/to/intensity_file/tp0},
                                     right_hemi: {model: "/path/to/model_file/tp0", 
                                                          intensity:"/path/to/intensity_file/tp0},
                                     lesions: {model: "/path/to/model_file/tp0",
                                                   intensity:"/path/to/intensity_file/tp0},
                                    },
                                1: {...},
                                2: {...}} // the keys in the model_timepoints dict must map to values of the "name" key in models
models: [{
    name: left_hemi
    opacity: 1,
    intensity_options: {
         blend_with_color: true/false
         blend_with_opacity: true/false
         columns: [{name: thickness, visible: true, vmin: 0, vmax: 5, colormap: Spectrum }, 
                          {name: curvature, visible: false, vmin: -2, vmax: 0, colormap: Gray},
                         ] //would be cool to swap order of this to see different columns on "top" when it comes to blending 2 overlays
         },
    events:{
         shift_click: some_click_callback
         shift_mouseover: some_mouseover_callback
         },
    link_to: "right_hemi" //this means, whatever options chosen on left should go to right 
    },
{
    name: right_hemi
    opacity: 1,
    intensity_options: {
         blend_with_color: true/false
         blend_with_opacity: true/false
         colormap: Spectrum
         columns: [{name: thickness, visible: true, vmin: 0, vmax: 5, colormap: Spectrum }, 
                          {name: curvature, visible: false, vmin: 0, vmax: 5, colormap: Spectrum},
                         ],
         link_to: "left_hemi"
         },
    events:{
         shift_click: some_click_callback
         shift_mouseover: some_mouseover_callback
         }
    }
],
timepoint: 0 //actually i think the values here could be dates (milliseconds from 1972 or whatever) or strings. As long as they map to keys in the model_timepoints object.
background_color: "white" //or  "black"
rotation:{x: false, y:false, z:true}
}
akeshavan commented 7 years ago

we know the dat.gui will change some of these options, so we need a way to encode the "state" of this schema so that people can share what exactly they are looking at:

akeshavan commented 7 years ago

also, not sure how the events should be defined in the schema. I'd like to use this library in another app that does d3 plots depending on which part of the mesh you click - so ideally that app would pass functions into this config

pandafulmanda commented 7 years ago

hmmm...what about something where the data and the UI settings for them are more separated?

I think that would help with coding in smart defaults for data without changed UI settings. Also, it will help with the UI looking at one object to update when the user changes something.

For example:

{
  "data": [{
    "type": "surface",
    "location": "url/to/file",
    "name": "left-hemisphere" // name per type should be unique
  }, {
    "type": "surface",
    "location": "url/to/right-hemisphere" // name will default to filename without extension if omitted
  }, {
    "type": "surface",
    "name": "legions",
    "items": [{ // items to hold onto any series
      "location": "url/to/file01"
    },  {
      "location": "url/to/file02"
    }]
  }, {
    "type": "intensity",
    "name": "right-hemisphere", // same name different type will automatically link
    "location": {
      // another way to pass in a series
      "pattern": "url/to/filenamepattern{i}",
      "indexRange": "000:100"
    },
    // parsing options for loader
    "option": {
      "columns": ["freesurfer convexity (sulc)", "freesurfer thickness", "freesurfer curvature"]
    }
  }, {
    "type": "intensity",
    "name": "left-hemisphere-hello",
    "location": {
      "pattern": "url/to/filenamepattern{i}",
      "indexRange": "000:100"
    }
  }],

  // can explicitly link things.
  "link": [
    [{
      "type": "intensity",
      "name": "left-hemisphere-hello"
    }, {
      "type": "surface",
      "name": "left-hemisphere"
    }], [{
      "type": "settings",
      "name": "left-hemisphere"
    }, {
      "type": "settings",
      "name": "right-hemisphere"
    }]
  ],

  // one way to define interface options, values get to be more shallow
  "settings": [{
      "for": "right-hemisphere.intensity['freesurfer curvature'].min",
      "value": 4
    }, {
      "for": "right-hemisphere.intensity['freesurfer curvature'].max",
      "value": 5
    }, {
      "for": "right-hemisphere.intensity['freesurfer curvature'].show",
      "value": false
    }, {
      "for": "rotation",
      "value": {
        "x":  false,
        "y":  false,
        "z":  true
      }
    }, {
      "for": "backgroundColor",
      "value": 0XFFFFFF
  }, {
    "for": "index",
    "value": 0
  }],

  // another way to define interface options
  "settings": {
    "right-hemisphere": {
      "intensity": {
        "freesurfer curvature": {
          "min": 4,
          "max": 5,
          "show": false
        }
      }
    },
    "rotation": {
      "x":  false,
      "y":  false,
      "z":  true
    },
    "backgroundColor": 0XFFFFFF,
    "index": 0
  },

  // code will listen to event names to trigger events
  // this way, events can be easily combined for different interactions
  "events": [{
    "type": [["keypress", "shift"]],
    "name": "eventNameToListenTo"
  }, {
    "type": ["right-hemisphere.surface.click"],
    "name": "anotherEventNameToListenTo"
  }, {
    "type": ["right-hemisphere.surface.mouseover"],
    "name": "anotherEventNameToListenTo",
    "trigger": "functionName" //  for more common things we want on event.  these would be defined in the library
  }]
  // or we would implement vega's event signaling idea
}
akeshavan commented 7 years ago

Also, I see that dat.gui has a saving structure. http://workshop.chromeexperiments.com/examples/gui/#5--Saving-Values Should we think about getting things to play nice with their schema?