I have the following graph:
Vertices and edges have been added like this:
def graph=ConfiguredGraphFactory.open('Baptiste');def g = graph.traversal();
graph.addVertex(label, 'Group', 'text', 'BNP Paribas');
graph.addVertex(label, 'Group', 'text', 'BNP PARIBAS');
graph.addVertex(label, 'Company', 'text', 'JP Morgan Chase');
graph.addVertex(label, 'Location', 'text', 'France');
graph.addVertex(label, 'Location', 'text', 'United States');
graph.addVertex(label, 'Location', 'text', 'Europe');
def v1 = g.V().has('text', 'JP Morgan Chase').next();def v2 = g.V().has(text, 'BNP Paribas').next();v1.addEdge('partOf',v2);
def v1 = g.V().has('text', 'JP Morgan Chase').next();def v2 = g.V().has(text, 'United States').next();v1.addEdge('doesBusinessIn',v2);
def v1 = g.V().has('text', 'BNP Paribas').next();def v2 = g.V().has(text, 'United States').next();v1.addEdge('doesBusinessIn',v2);
def v1 = g.V().has('text', 'BNP Paribas').next();def v2 = g.V().has(text, 'France').next();v1.addEdge('partOf',v2);
def v1 = g.V().has('text', 'BNP PARIBAS').next();def v2 = g.V().has(text, 'Europe').next();v1.addEdge('partOf',v2);
And I need a query that returns me every paths possible given specific vertex labels, edge labels and number of possible hops.
Let's say I need paths with maximum hops of 2 and every labels in this example. I tried this query:
def graph=ConfiguredGraphFactory.open('TestGraph');
def g = graph.traversal();
g.V().has(label, within('Location', 'Company', 'Group'))
.repeat(bothE().has(label, within('doesBusinessIn', 'partOf')).bothV().has(label, within('Location', 'Company', 'Group')).simplePath())
.emit().times(2).path();
This query returns 20 paths (supposed to return 10 paths). So it returns paths in the 2 possible directions. Is there a way to specify that I need only 1 direction? I tried adding dedup() in my query but it returns 7 paths instead of 10 so it's not working?
Also whenever I try to find paths with 4 hops, it doesn't return me the "cyclic" paths such as France -> BNP Paribas -> United States -> JP Morgan Chase -> BNP Paribas. Any idea what to add in my query to allow returning those kind of paths?
EDIT:
Thanks for your solution #DanielKuppitz. It seems to be exactly what I'm looking for.
I use JanusGraph built on top of Apache Tinkerpop:
I tried the first query:
g.V().hasLabel('Location', 'Company', 'Group').
repeat(bothE('doesBusinessIn', 'partOf').otherV().simplePath()).
emit().times(2).
path().
dedup().
by(unfold().order().by(id).fold())
And it threw the following error:
Error: org.janusgraph.graphdb.relations.RelationIdentifier cannot be cast to java.lang.Comparable
So I moved the dedup command. into the repeat loop like so:
g.V().hasLabel('Location', 'Company', 'Group').
repeat(bothE('doesBusinessIn', 'partOf').otherV().simplePath().dedup().by(unfold().order().by(id).fold())).
emit().times(2).
path().
And it only returned 6 paths :
[
[
"JP Morgan Chase",
"doesBusinessIn",
"United States"
],
[
"JP Morgan Chase",
"partOf",
"BNP Paribas"
],
[
"JP Morgan Chase",
"partOf",
"BNP Paribas",
"partOf",
"France"
],
[
"Europe",
"partOf",
"BNP PARIBAS"
],
[
"BNP PARIBAS",
"partOf",
"Europe"
],
[
"United States",
"doesBusinessIn",
"JP Morgan Chase"
]
]
I'm not sure what's going on here... Any ideas?
Is there a way to specify that I need only 1 direction?
You kinda need a bidirected traversal, so you'll have to filter duplicated paths in the end ("duplicated" in this case means that 2 paths contain the same elements). In order to do that you can dedup() paths by a deterministic order of elements; the easiest way to do it is to order the elements by their id.
g.V().hasLabel('Location', 'Company', 'Group').
repeat(bothE('doesBusinessIn', 'partOf').otherV().simplePath()).
emit().times(2).
path().
dedup().
by(unfold().order().by(id).fold())
Any idea what to add in my query to allow returning those kinds of paths (cyclic)?
Your query explicitly prevents cyclic paths through the simplePath() step, so it's not quite clear in which scenarios you want to allow them. I assume that you're okay with a cyclic path if the cycle is created by only the first and last element in the path. In this case, the query would look more like this:
g.V().hasLabel('Location', 'Company', 'Group').as('a').
repeat(bothE('doesBusinessIn', 'partOf').otherV()).
emit().
until(loops().is(4).or().cyclicPath()).
filter(simplePath().or().where(eq('a'))).
path().
dedup().
by(unfold().order().by(id).fold())
Below is the output of the 2 queries (ignore the extra map() step, it's just there to improve the output's readability).
gremlin> g.V().hasLabel('Location', 'Company', 'Group').
......1> repeat(bothE('doesBusinessIn', 'partOf').otherV().simplePath()).
......2> emit().times(2).
......3> path().
......4> dedup().
......5> by(unfold().order().by(id).fold()).
......6> map(unfold().coalesce(values('text'), label()).fold())
==>[BNP Paribas,doesBusinessIn,United States]
==>[BNP Paribas,partOf,France]
==>[BNP Paribas,partOf,JP Morgan Chase]
==>[BNP Paribas,doesBusinessIn,United States,doesBusinessIn,JP Morgan Chase]
==>[BNP Paribas,partOf,JP Morgan Chase,doesBusinessIn,United States]
==>[BNP PARIBAS,partOf,Europe]
==>[JP Morgan Chase,doesBusinessIn,United States]
==>[JP Morgan Chase,partOf,BNP Paribas,doesBusinessIn,United States]
==>[JP Morgan Chase,partOf,BNP Paribas,partOf,France]
==>[France,partOf,BNP Paribas,doesBusinessIn,United States]
gremlin> g.V().hasLabel('Location', 'Company', 'Group').as('a').
......1> repeat(bothE('doesBusinessIn', 'partOf').otherV()).
......2> emit().
......3> until(loops().is(4).or().cyclicPath()).
......4> filter(simplePath().or().where(eq('a'))).
......5> path().
......6> dedup().
......7> by(unfold().order().by(id).fold()).
......8> map(unfold().coalesce(values('text'), label()).fold())
==>[BNP Paribas,doesBusinessIn,United States]
==>[BNP Paribas,partOf,France]
==>[BNP Paribas,partOf,JP Morgan Chase]
==>[BNP Paribas,doesBusinessIn,United States,doesBusinessIn,JP Morgan Chase]
==>[BNP Paribas,doesBusinessIn,United States,doesBusinessIn,BNP Paribas]
==>[BNP Paribas,partOf,France,partOf,BNP Paribas]
==>[BNP Paribas,partOf,JP Morgan Chase,doesBusinessIn,United States]
==>[BNP Paribas,partOf,JP Morgan Chase,partOf,BNP Paribas]
==>[BNP Paribas,doesBusinessIn,United States,doesBusinessIn,JP Morgan Chase,partOf,BNP Paribas]
==>[BNP PARIBAS,partOf,Europe]
==>[BNP PARIBAS,partOf,Europe,partOf,BNP PARIBAS]
==>[JP Morgan Chase,doesBusinessIn,United States]
==>[JP Morgan Chase,doesBusinessIn,United States,doesBusinessIn,JP Morgan Chase]
==>[JP Morgan Chase,partOf,BNP Paribas,doesBusinessIn,United States]
==>[JP Morgan Chase,partOf,BNP Paribas,partOf,France]
==>[JP Morgan Chase,partOf,BNP Paribas,partOf,JP Morgan Chase]
==>[JP Morgan Chase,doesBusinessIn,United States,doesBusinessIn,BNP Paribas,partOf,France]
==>[JP Morgan Chase,doesBusinessIn,United States,doesBusinessIn,BNP Paribas,partOf,JP Morgan Chase]
==>[France,partOf,BNP Paribas,doesBusinessIn,United States]
==>[France,partOf,BNP Paribas,partOf,France]
==>[France,partOf,BNP Paribas,partOf,JP Morgan Chase,doesBusinessIn,United States]
==>[United States,doesBusinessIn,JP Morgan Chase,doesBusinessIn,United States]
==>[United States,doesBusinessIn,BNP Paribas,doesBusinessIn,United States]
==>[United States,doesBusinessIn,JP Morgan Chase,partOf,BNP Paribas,doesBusinessIn,United States]
==>[Europe,partOf,BNP PARIBAS,partOf,Europe]
UPDATE (based on latest comments)
Since JanusGraph has non-comparable edge identifiers, you'll need a unique comparable property on all edges. This can be as simple as a random UUID.
This is how I updated your sample graph:
g.addV('Group').property('text', 'BNP Paribas').as('a').
addV('Group').property('text', 'BNP PARIBAS').as('b').
addV('Company').property('text', 'JP Morgan Chase').as('c').
addV('Location').property('text', 'France').as('d').
addV('Location').property('text', 'United States').as('e').
addV('Location').property('text', 'Europe').as('f').
addE('partOf').from('c').to('a').
property('uuid', UUID.randomUUID().toString()).
addE('doesBusinessIn').from('c').to('e').
property('uuid', UUID.randomUUID().toString()).
addE('doesBusinessIn').from('a').to('e').
property('uuid', UUID.randomUUID().toString()).
addE('partOf').from('a').to('d').
property('uuid', UUID.randomUUID().toString()).
addE('partOf').from('b').to('f').
property('uuid', UUID.randomUUID().toString()).
iterate()
Now, that we have properties that can uniquely identify an edge, we also need unique properties (of the same data type) on all vertices. Luckily the existing text properties seem to be good enough for that (otherwise it would be the same story as with the edges - just add a random UUID). The updated queries now look like this:
g.V().hasLabel('Location', 'Company', 'Group').
repeat(bothE('doesBusinessIn', 'partOf').otherV().simplePath()).
emit().times(2).
path().
dedup().
by(unfold().values('text','uuid').order().fold())
g.V().hasLabel('Location', 'Company', 'Group').as('a').
repeat(bothE('doesBusinessIn', 'partOf').otherV()).
emit().
until(loops().is(4).or().cyclicPath()).
filter(simplePath().or().where(eq('a'))).
path().
dedup().
by(unfold().values('text','uuid').order().fold())
The result are, of course, the same as above.
Related
I have 3 dataframes: train, validation, test.
I want to create a dictionary with these 3 dataframes to get the output below:
features are the dataframe columns's name
How ca I do this dictionary of dataframe?
DatasetDict({
train: Dataset({
features: ['ID', 'Tweet', 'anger', 'anticipation', 'disgust', 'fear', 'joy', 'love', 'optimism', 'pessimism', 'sadness', 'surprise', 'trust'],
num_rows: 6838
})
test: Dataset({
features: ['ID', 'Tweet', 'anger', 'anticipation', 'disgust', 'fear', 'joy', 'love', 'optimism', 'pessimism', 'sadness', 'surprise', 'trust'],
num_rows: 3259
})
validation: Dataset({
features: ['ID', 'Tweet', 'anger', 'anticipation', 'disgust', 'fear', 'joy', 'love', 'optimism', 'pessimism', 'sadness', 'surprise', 'trust'],
num_rows: 886
})
})
I am trying this:
DatasetDict = {}
dataframes = [train, validation, test]
for grp in dataframes:
DatasetDict[grp] = df
But it's not working
train.name = 'train'
test.name = 'test'
validation.name = 'validation'
datasetdict = {}
dataframes = [train, validation, test]
for df in dataframes:
datasetdict[df.name] = {'features': df.columns.to_list(), 'num_rows': len(df)}
I am building a telegram-bot and using Dialogflow in it, I am getting the following error :
2021-11-19 23:26:46,936 - __main__ - ERROR - Update '{'message': {'entities': [],
'delete_chat_photo': False, 'text': 'hi', 'date': 1637344606, 'new_chat_members': [],
'channel_chat_created': False, 'message_id': 93, 'photo': [], 'group_chat_created':
False, 'supergroup_chat_created': False, 'new_chat_photo': [], 'caption_entities': [],
'chat': {'id': 902424541, 'type': 'private', 'first_name': 'Akriti'},
'from': {'first_name': 'Akriti', 'id': 902424541, 'is_bot': False, 'language_code': 'en'}
}, 'update_id': 624230278}' caused error 'module 'google.cloud.dialogflow' has no
attribute 'types''
It appears there is some issue with the Dialogflow attribute "types", but I don't know what I am doing wrong.
Here is the code where I am using it:
import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "client.json"
from google.cloud import dialogflow
dialogflow_session_client = dialogflow.SessionsClient()
PROJECT_ID = "get-informed-ufnl"
from gnewsclient import gnewsclient
client = gnewsclient.NewsClient()
def detect_intent_from_text(text, session_id, language_code='en'):
session = dialogflow_session_client.session_path(PROJECT_ID, session_id)
text_input = dialogflow.types.TextInput(text=text, language_code=language_code)
query_input = dialogflow.types.QueryInput(text=text_input)
response = dialogflow_session_client.detect_intent(session=session, query_input=query_input)
return response.query_result
def get_reply(query, chat_id):
response = detect_intent_from_text(query, chat_id)
if response.intent.display_name == 'get_news':
return "get_news", dict(response.parameters)
else:
return "small_talk", response.fulfillment_text
def fetch_news(parameters):
client.language = parameters.get('language')
client.location = parameters.get('geo-country')
client.topic = parameters.get('topic')
return client.get_news()[:5]
topics_keyboard = [
['Top Stories', 'World', 'Nation'],
['Business', 'Technology', 'Entertainment'],
['Sports', 'Science', 'Health']
]
I figured it out, the problem lies in the import statement. The correct module name should be:
import google.cloud.dialogflow_v2 as dialogflow
I recommend to deactivate your current error handler or use one similar to this example such that you can see the full traceback of the exception :)
Disclaimer: I'm currently the maintainer of python-telegram-bot
I am currently working on a project where I need to translate Customer comments into English from the source language on AWS. It is easy to do so using AWS Translate but before I call translate API to translate text into English, I want to check whether the source language is supported by AWS or not?
One solution is to put all the language codes supported by AWS Translate into a list and then check source language against this list. This is easy but it is going to be messy and I want to make it more dynamic.
So, I am thinking to code like this
import boto3
def translateUserComment(source_language):
translate = boto3.client(service_name='translate', region_name='region', use_ssl=True)
languages_supported = tanslate.<SomeMethod>()
if source_language in languages_supported:
result = translate.translate_text(Text="Hello, World",
SourceLanguageCode=source_language, TargetLanguageCode="en")
print('TranslatedText: ' + result.get('TranslatedText'))
print('SourceLanguageCode: ' + result.get('SourceLanguageCode'))
print('TargetLanguageCode: ' + result.get('TargetLanguageCode'))
else:
print("The source language is not supported by AWS Translate")
Problem is that I am not able to find out any API call to get the list of languages/language codes supported by AWS Translate for place.
Before I posted this question,
I have tried to search for similar questions on stackoverflow
I have gone through the AWS Translate Developer guide but still no luck
Any suggestion/ redirection to the right approach is highly appreciated.
Currently there is no API for this service, although this code would work, in this code a class is created Translate_lang with all the language codes and country wise
from here-> https://docs.aws.amazon.com/translate/latest/dg/what-is.html
, you can call this class into your program and use it by creating an instance of the class:
translate_lang_check.py
class Translate_lang:
def __init__(self):
self.t_lang = {'Afrikaans': 'af', 'Albanian': 'sq', 'Amharic': 'am',
'Arabic': 'ar', 'Armenian': 'hy', 'Azerbaijani': 'az',
'Bengali': 'bn', 'Bosnian': 'bs', 'Bulgarian': 'bg',
'Catalan': 'ca', 'Chinese (Simplified)': 'zh',
'Chinese (Traditional)': 'zh-TW', 'Croatian': 'hr',
'Czech': 'cs', 'Danish': 'da ', 'Dari': 'fa-AF',
'Dutch': 'nl ', 'English': 'en', 'Estonian': 'et',
'Farsi (Persian)': 'fa', 'Filipino Tagalog': 'tl',
'Finnish': 'fi', 'French': 'fr', 'French (Canada)': 'fr-CA',
'Georgian': 'ka', 'German': 'de', 'Greek': 'el', 'Gujarati': 'gu',
'Haitian Creole': 'ht', 'Hausa': 'ha', 'Hebrew': 'he ', 'Hindi': 'hi',
'Hungarian': 'hu', 'Icelandic': 'is', 'Indonesian': 'id ', 'Italian': 'it',
'Japanese': 'ja', 'Kannada': 'kn', 'Kazakh': 'kk', 'Korean': 'ko',
'Latvian': 'lv', 'Lithuanian': 'lt', 'Macedonian': 'mk', 'Malay': 'ms',
'Malayalam': 'ml', 'Maltese': 'mt', 'Mongolian': 'mn', 'Norwegian': 'no',
'Persian': 'fa', 'Pashto': 'ps', 'Polish': 'pl', 'Portuguese': 'pt',
'Romanian': 'ro', 'Russian': 'ru', 'Serbian': 'sr', 'Sinhala': 'si',
'Slovak': 'sk', 'Slovenian': 'sl', 'Somali': 'so', 'Spanish': 'es',
'Spanish (Mexico)': 'es-MX', 'Swahili': 'sw', 'Swedish': 'sv',
'Tagalog': 'tl', 'Tamil': 'ta', 'Telugu': 'te', 'Thai': 'th',
'Turkish': 'tr', 'Ukrainian': 'uk', 'Urdu': 'ur', 'Uzbek': 'uz',
'Vietnamese': 'vi', 'Welsh': 'cy'}
def check_lang_in_translate(self, given_country):
if given_country in self.t_lang:
return self.t_lang[given_country]
else:
return None
def check_lang_code_in_translate(self, given_lang):
if given_lang in list(self.t_lang.values()):
return True
else:
return False
You can call and check your lang codes using the methods of this class:
from translate_lang_check import Translate_lang
tl = Translate_lang()
print(tl.check_lang_code_in_translate('en'))
This is a Python Program to get all the captions from youtube link:
from pytube import YouTube
yt = YouTube('https://youtu.be/5MgBikgcWnY')
captions = yt.captions.all()
for caption in captions:
print(caption)
and the output of the above program is:
<Caption lang="Arabic" code="ar">
<Caption lang="Chinese (China)" code="zh-CN">
<Caption lang="English" code="en">
<Caption lang="English (auto-generated)" code="a.en">
<Caption lang="French" code="fr">
<Caption lang="German" code="de">
<Caption lang="Hungarian" code="hu">
<Caption lang="Italian" code="it">
But I want to get only the lang and code from the above output in a dictionary pair.
{"Arabic" : "ar", "Chinese" : "zh-CN", "English" : "en",
"French : "fr", "German" : "de", "Hungarian" : "hu", "Italian" : "it"}
Thanks in Advance.
It's pretty simple
from pytube import YouTube
yt = YouTube('https://youtu.be/5MgBikgcWnY')
captions = yt.captions.all()
captions_dict = {}
for caption in captions:
# Mapping the caption name to the caption code
captions_dict[caption.name] = caption.code
If you want a one-liner
captions_dict = {caption.name: caption.code for caption in captions}
Output
{'Arabic': 'ar', 'Bangla': 'bn', 'Burmese': 'my', 'Chinese (China)': 'zh-CN',
'Chinese (Taiwan)': 'zh-TW', 'Croatian': 'hr', 'English': 'en',
'English (auto-generated)': 'a.en', 'French': 'fr', 'German': 'de',
'Hebrew': 'iw', 'Hungarian': 'hu', 'Italian': 'it', 'Japanese': 'ja',
'Persian': 'fa', 'Polish': 'pl', 'Portuguese (Brazil)': 'pt-BR',
'Russian': 'ru', 'Serbian': 'sr', 'Slovak': 'sk', 'Spanish': 'es',
'Spanish (Spain)': 'es-ES', 'Thai': 'th', 'Turkish': 'tr',
'Ukrainian': 'uk', 'Vietnamese': 'vi'}
I'm trying to install the default example of Tabulator (http://tabulator.info/docs/4.0/quickstart).
I installed Tabulator in my NodeJS project.
My route definition looks like this in my index.js file:
app.get("/", (req, res) => {
var table = new tabulator("#example-table", {
height:205,
layout:"fitColumns", //fit columns to width of table (optional)
columns:[
{title:"Name", field:"name", width:150},
{title:"Age", field:"age", align:"left", formatter:"progress"},
{title:"Favourite Color", field:"col"},
{title:"Date Of Birth", field:"dob", sorter:"date", align:"center"},
],
rowClick:function(e, row){
alert("Row " + row.getData().id + " Clicked!!!!");
},
});
var tabledata = [
{id:1, name:"Oli Bob", age:"12", col:"red", dob:""},
{id:2, name:"Mary May", age:"1", col:"blue", dob:"14/05/1982"},
{id:3, name:"Christine Lobowski", age:"42", col:"green", dob:"22/05/1982"},
{id:4, name:"Brendon Philips", age:"125", col:"orange", dob:"01/08/1980"},
{id:5, name:"Margret Marmajuke", age:"16", col:"yellow", dob:"31/01/1999"},
];
res.render("index", { title: "Home"});
});
Then I added a div in my index.pug:
div.example-table
However, I got the following error:
ReferenceError: document is not defined
at Tabulator.initializeElement (C:\Users\SESA509216\Box\Perso\Scripts\LMS\Audit-Trail\node_modules\tabulator-tables\dist\js\tabulator.js:9223:19)
at new Tabulator (C:\Users\SESA509216\Box\Perso\Scripts\LMS\Audit-Trail\node_modules\tabulator-tables\dist\js\tabulator.js:8612:12)
at app.get (C:\Users\SESA509216\Box\Perso\Scripts\LMS\Audit-Trail\index.js:37:17)
at Layer.handle [as handle_request] (C:\Users\SESA509216\Box\Perso\Scripts\LMS\Audit-Trail\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\SESA509216\Box\Perso\Scripts\LMS\Audit-Trail\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Users\SESA509216\Box\Perso\Scripts\LMS\Audit-Trail\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Users\SESA509216\Box\Perso\Scripts\LMS\Audit-Trail\node_modules\express\lib\router\layer.js:95:5)
at C:\Users\SESA509216\Box\Perso\Scripts\LMS\Audit-Trail\node_modules\express\lib\router\index.js:281:22
at Function.process_params (C:\Users\SESA509216\Box\Perso\Scripts\LMS\Audit-Trail\node_modules\express\lib\router\index.js:335:12)
at next (C:\Users\SESA509216\Box\Perso\Scripts\LMS\Audit-Trail\node_modules\express\lib\router\index.js:275:10)
I guess, that Tabulator should somehow be initialized on the client side. But I don't know how...
I solved my problem.
I joined the tabulator-tables css & js path to the app configuration in index.js:
app.use(express.static(path.join(__dirname, "node_modules/tabulator-tables/dist/css")));
app.use(express.static(path.join(__dirname, "node_modules/tabulator-tables/dist/js")));
Then, I imported the tabulator css and js files in my frontend:
link(rel="stylesheet" href="tabulator.min.css")
script(type='text/javascript' src="tabulator.min.js")
Finally, I copied the sample-script in my page:
div.example-table(id="example-table")
script.
//create Tabulator on DOM element with id "example-table"
var table = new Tabulator("#example-table", {
height:205, // set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically (can be any valid css height value)
layout:"fitColumns", //fit columns to width of table (optional)
columns:[ //Define Table Columns
{title:"Name", field:"name", width:150},
{title:"Age", field:"age", align:"left", formatter:"progress"},
{title:"Favourite Color", field:"col"},
{title:"Date Of Birth", field:"dob", sorter:"date", align:"center"},
],
rowClick:function(e, row){ //trigger an alert message when the row is clicked
alert("Row " + row.getData().id + " Clicked!!!!");
},
});
//define some sample data
var tabledata = [
{id:1, name:"Oli Bob", age:"12", col:"red", dob:""},
{id:2, name:"Mary May", age:"1", col:"blue", dob:"14/05/1982"},
{id:3, name:"Christine Lobowski", age:"42", col:"green", dob:"22/05/1982"},
{id:4, name:"Brendon Philips", age:"125", col:"orange", dob:"01/08/1980"},
{id:5, name:"Margret Marmajuke", age:"16", col:"yellow", dob:"31/01/1999"},
];
//load sample data into the table
table.setData(tabledata);
Thank you very much for your help!
That looks like you are trying to use Tabulator in the response on the controller.
Tabulator is designed to be run client side, not server side. you would need to return some HTML with a script tag that then built the table on a DOM node.
You are also instantiating tabulator with a lower case "T" it should be new Tabulator
I suggest what you need to do is create an HTML page to show the table, for example the source at http://tabulator.info/basic/4.8 would do, though you would also need to serve the source JS and CSS files for the demo to work, alternativly you could change the local file paths to the CDN Links for a quick demo.
You would then need to serve this page with ExpressJS, using the sendFile function and the path to your html file
// viewed at http://localhost:8080
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
To pass table data from node to script in a pug file do the following:
// node index.js
let data = [
{id : 1, name : 'Adam', zip : '11101'},
{id : 2, name : 'Bob', zip : '95134'}
];
res.render('table.pug', { table_data: data });
// table.pug
div.example-table(id="example-table")
script.
var table = new Tabulator("#example-table", {
columns:[
{title:"Name", field:"name"},
{title:"ZIP", field:"zip"}
]
});
//load sample data into the table
table.setData(!{JSON.stringify(table_data)});
What I did to get Tabulator up and running with nodejs and express.
At first install Tabulator Tables in your nodejs/express project by npm i tabulator-tables. Then proceed as follows:
The main Javascript file in my case is "app.js".
In "app.js": Use static files to serve them:
// Use static files
app.use(express.static(path.join(__dirname, "node_modules/tabulator-tables/dist/css")));
app.use(express.static(path.join(__dirname, "node_modules/tabulator-tables/dist/js")));
In the <head> section of the html document, in my case "index.html":
<head>
<!-- Tabulator Tables -->
<link rel="stylesheet" href="tabulator.min.css">
<script src="tabulator.min.js"></script>
</head>
In the body-section of the "index.html" place a div where the table should appear:
<div id="example-table"></div>
Also in "index.html" reference a scriptfile before the closing body-tag:
<!-- Document ready -->
<script src="index.js"></script>
</body>
Last but not least in the "index.js" file:
//define some sample data
var tabledata = [
{id:1, name:"Oli Bob", age:"12", col:"red", dob:""},
{id:2, name:"Mary May", age:"1", col:"blue", dob:"14/05/1982"},
{id:3, name:"Christine Lobowski", age:"42", col:"green", dob:"22/05/1982"},
{id:4, name:"Brendon Philips", age:"125", col:"orange", dob:"01/08/1980"},
{id:5, name:"Margret Marmajuke", age:"16", col:"yellow", dob:"31/01/1999"},
];
//create Tabulator on DOM element with id "example-table"
var table = new Tabulator("#example-table", {
height:205, // set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically (can be any valid css height value)
data:tabledata, //assign data to table
layout:"fitColumns", //fit columns to width of table (optional)
columns:[ //Define Table Columns
{title:"Name", field:"name", width:150},
{title:"Age", field:"age", hozAlign:"left", formatter:"progress"},
{title:"Favourite Color", field:"col"},
{title:"Date Of Birth", field:"dob", sorter:"date", hozAlign:"center"},
],
});
//trigger an alert message when the row is clicked
table.on("rowClick", function(e, row){
alert("Row " + row.getData().id + " Clicked!!!!");
});
Then start node app.js and open your "index.html" in the browser. If the table appears and you get a message when you click on a row of it, then everything works fine.
Hope this helps.