0

I would like to use the Cytoscape extension cytoscape-qtip in a component of my Ember app which already uses Cytoscape.js as a dependency to draw a graph.

Successful Setup of Cytoscape.js

Cytoscape.js itself is already successfully hooked into Ember by installing it via bower bower install cytoscape and importing it via ember-cli-build.js:

in my-ember-app/ember-cli-build.js:

// in my-ember-app/ember-cli-build.js
// ....
app.import('bower_components/cytoscape/dist/cytoscape.js');
return app.toTree();

In my cytoscape-graph component I can then use the cytoscape global variable out of the box:

in my-ember-app/app/components/cytoscape-graph.js:

import Ember from 'ember';
export default Ember.Component.extend({
didInsertElement(){
  let container = this.$();
 // ...
 var cy = cytoscape({
   container: container,
 // ... styles, layout, element selection
 }); // this cytoscape instance renders fine!

Accessing the global cytoscape works fine with this approach.


Analogue Setup of Cytoscape-Qtip doesn't work

Although, when I install cytoscape-qtip via bower, import the dependency similar to cytoscape into my app in ember-cli-build.js like so:

in my-ember-app/ember-cli-build.js:

// ...
module.exports = function(defaults) {
  var app = new EmberApp(defaults, {
  // ;....
  });
  // ....
  app.import('bower_components/cytoscape/dist/cytoscape.js');
  app.import('bower_components/cytoscape-qtip/cytoscape-qtip.js');

  return app.toTree();
};

and try to use the qtip method in my cytoscape-graph component:

in my-ember-app/app/components/cytoscape-graph.js:

// ....
didInsertElement(){
  // ....
  cy.on('mouseover', 'node', function(event) {
    var node = event.cyTarget;
    node.qtip({
        content: 'hello',
        show: {
            event: event.type,
            ready: true
        },
        hide: {
            event: 'mouseout unfocus'
        }
    }, event);
  });

I will get the following console error once the mouseover event on any graph node is triggered:

Uncaught TypeError: qtip.$domEle.qtip is not a function(…) indicating that qtip itself is not defined in my component yet. A similar question asked here didn't help me with my issue, as the person asking there had issues with jquery being loaded in the correct order. In my case jquery is already included in my app and working fine.


How do I include the cytoscape-qtip extension in my Ember app to be able to use qtip in my component?

Community
  • 1
  • 1
jessica
  • 480
  • 6
  • 17
  • Just to be sure, you've called `app.import` in the right order? – Lux Nov 17 '16 at 17:25
  • Do you mean the right order being: 1. load cytoscape, 2. load cytoscape-qtip? I have included the order of ``app.import``s in my current ember-cli-build.js file up ahead in the question. – jessica Nov 17 '16 at 19:00

2 Answers2

0

You must follow the instructions for registering the extension and its dependencies exactly as specified in the readme:

For CommonJS (e.g. npm+browserify or npm+webpack):

var cytoscape = require('cytoscape');
var jquery = require('jquery');
var cyqtip = require('cytoscape-qtip');

cyqtip( cytoscape, jquery ); // register extension

For ES6 style (any tooling that supports ES6):

import cytoscape from 'cytoscape';
import jquery from 'jquery';
import cyqtip from 'cytoscape-qtip';

cyqtip( cytoscape, jquery ); // register extension

The lines are pretty much identical either way.

Qtip must be registered to jQuery, so you'll probably have to expose jQuery globally first:

window.$ = window.jQuery = require('jquery');
require('qtip');

See also https://github.com/qTip2/qTip2/pull/810

maxkfranz
  • 11,896
  • 1
  • 27
  • 36
  • I have problems importing the cyqtip module from the cytoscape-qtip package: `loader.js:219 Uncaught Error: Could not find module `cytoscape-qtip` imported from 'my-ember-app/components/cytoscape-graph'` Do I need to follow any additional steps to expose the module properly so I can import it in my component? – jessica Nov 22 '16 at 11:50
  • Ember.js components are based on ES6 modules and use the `import` syntax to load modules. Therefore I tried the setup you described for the ES6 style of module loading in your answer as follows: `import cyqtip from 'cytoscape-qtip'; cyqtip( cytoscape, jQuery );` Global variables defined in vendor libraries are implicitly defined and available in my Ember component. Therefore I can confirm the definition of jQuery and cytoscape in the component by a simple `console.log(jQuery); console.log(cytoscape);` which returns the function in the console without any errors. – jessica Nov 22 '16 at 11:55
  • Extensions aren't going to expose anything globally, nor should they. You'll have to configure your module loader. If you use npm and Webpack or Browserify, that's always automatic. If you use bower, you'll have to figure out how Ember handles non-global packages and/or package lookup. Unless Ember only works with bower, you may want to consider using npm instead. Npm is far better than bower. – maxkfranz Nov 22 '16 at 20:08
0
    var node = event.cyTarget;
                                                       node.qtip({
                                                           content: 'hello:',
                                                           position: {
                                                               my: 'top center',
                                                               at: 'bottom center',
                                                               adjust: {
                                                                   method: 'shift'
                                                               },
                                                               viewport: true
                                                           },

                                                           show: {
                                                               event: 'mouseover'
                                                           },

                                                           hide: {
                                                               event: 'mouseout unfocus'
                                                           },

                                                           style: {
                                                               classes: 'qtip-bootstrap qtip-filters',
                                                               tip: {
                                                                   width: 16,
                                                                   height: 8
                                                               }
                                                           },


                                                       });
  • 1
    1. Properly format your code. 2. Explain what this code does and how/why it solves problem in question. – lolbas Feb 21 '18 at 10:38