From e6d8d72e52f16033990c327c7b005627199bf01c Mon Sep 17 00:00:00 2001 From: Patrick Jentsch Date: Wed, 14 Jun 2023 14:50:04 +0200 Subject: [PATCH 1/3] Add visualization data method to cqi over socketio --- .../cqi_over_socketio/cqi_corpora_corpus.py | 77 +++++++++++++++++-- app/static/js/CorpusAnalysis/CQiClient.js | 14 ++++ .../js/CorpusAnalysis/CorpusAnalysisApp.js | 9 +++ 3 files changed, 95 insertions(+), 5 deletions(-) diff --git a/app/corpora/cqi_over_socketio/cqi_corpora_corpus.py b/app/corpora/cqi_over_socketio/cqi_corpora_corpus.py index 9a976dd7..79b1a800 100644 --- a/app/corpora/cqi_over_socketio/cqi_corpora_corpus.py +++ b/app/corpora/cqi_over_socketio/cqi_corpora_corpus.py @@ -1,6 +1,8 @@ +from collections import Counter from flask import session import cqi import math +import random from app import db, socketio from app.decorators import socketio_login_required from app.models import Corpus @@ -38,10 +40,75 @@ def cqi_corpora_corpus_query(cqi_client: cqi.CQiClient, corpus_name: str, subcor @cqi_over_socketio def cqi_corpora_corpus_update_db(cqi_client: cqi.CQiClient, corpus_name: str): corpus = Corpus.query.get(session['d']['corpus_id']) - corpus.num_tokens = cqi_client.corpora.get(corpus_name).attrs['size'] + cqi_corpus = cqi_client.corpora.get(corpus_name) + corpus.num_tokens = cqi_corpus.size db.session.commit() +@socketio.on('cqi.corpora.corpus.get_visualization_data', namespace=ns) +@socketio_login_required +@cqi_over_socketio +def cqi_corpora_corpus_get_visualization_data(cqi_client: cqi.CQiClient, corpus_name: str): + cqi_corpus = cqi_client.corpora.get(corpus_name) + payload = {} + payload['num_tokens'] = cqi_corpus.size + cqi_word_attr = cqi_corpus.positional_attributes.get('word') + payload['num_unique_words'] = cqi_word_attr.lexicon_size + payload['word_freqs'] = dict(zip(cqi_word_attr.values_by_ids(list(range(0, cqi_word_attr.lexicon_size))), cqi_word_attr.freqs_by_ids(list(range(0, cqi_word_attr.lexicon_size))))) + # payload['word_freqs'].sort(key=lambda a: a[1], reverse=True) + # payload['word_freqs'] = {k: v for k, v in payload['word_freqs']} + cqi_lemma_attr = cqi_corpus.positional_attributes.get('lemma') + payload['num_unique_lemmas'] = cqi_lemma_attr.lexicon_size + payload['lemma_freqs'] = dict(zip(cqi_lemma_attr.values_by_ids(list(range(0, cqi_lemma_attr.lexicon_size))), cqi_lemma_attr.freqs_by_ids(list(range(0, cqi_lemma_attr.lexicon_size))))) + # payload['lemma_freqs'].sort(key=lambda a: a[1], reverse=True) + # payload['lemma_freqs'] = {k: v for k, v in payload['lemma_freqs']} + cqi_s_attr = cqi_corpus.structural_attributes.get('s') + payload['num_sentences'] = cqi_s_attr.size + # assuming all tokens are in a sentence + payload['average_sentence_length'] = payload['num_tokens'] / payload['num_sentences'] if payload['num_sentences'] != 0 else 0 + # payload['average_sentence_length'] = 0 + # for s_id in range(0, cqi_s_attr.size): + # s_lbound, s_rbound = cqi_s_attr.cpos_by_id(s_id) + # payload['average_sentence_length'] += s_rbound - s_lbound + 1 + # payload['average_sentence_length'] /= payload['num_sentences'] + cqi_ent_type_attr = cqi_corpus.structural_attributes.get('ent_type') + payload['num_ent_types'] = cqi_ent_type_attr.size + payload['ent_type_freqs'] = dict(Counter(cqi_ent_type_attr.values_by_ids(list(range(0, cqi_ent_type_attr.size))))) + payload['num_unique_ent_types'] = len(payload['ent_type_freqs']) + payload['texts'] = [] + cqi_text_attr = cqi_corpus.structural_attributes.get('text') + for text_id in range(0, cqi_text_attr.size): + text_lbound, text_rbound = cqi_text_attr.cpos_by_id(text_id) + text_cpos_list = list(range(text_lbound, text_rbound + 1)) + text_payload = {} + text_payload['num_tokens'] = text_rbound - text_lbound + 1 + text_word_ids = cqi_word_attr.ids_by_cpos(text_cpos_list) + print(text_word_ids) + text_payload['num_unique_words'] = len(set(text_word_ids)) + text_payload['word_freqs'] = dict(Counter(cqi_word_attr.values_by_ids(text_word_ids))) + text_lemma_ids = cqi_lemma_attr.ids_by_cpos(text_cpos_list) + text_payload['num_unique_lemmas'] = len(set(text_lemma_ids)) + text_payload['lemma_freqs'] = dict(Counter(cqi_word_attr.values_by_ids(text_lemma_ids))) + text_s_attr_ids = list(filter(lambda x: x != -1, cqi_s_attr.ids_by_cpos(text_cpos_list))) + text_payload['num_sentences'] = len(set(text_s_attr_ids)) + # assuming all tokens are in a sentence + text_payload['average_sentence_length'] = text_payload['num_tokens'] / text_payload['num_sentences'] if text_payload['num_sentences'] != 0 else 0 + # text_payload['average_sentence_length'] = 0 + # for text_s_id in range(0, cqi_s_attr.size): + # text_s_lbound, text_s_rbound = cqi_s_attr.cpos_by_id(text_s_id) + # text_payload['average_sentence_length'] += text_s_rbound - text_s_lbound + 1 + # text_payload['average_sentence_length'] /= text_payload['num_sentences'] + text_ent_type_ids = list(filter(lambda x: x != -1, cqi_ent_type_attr.ids_by_cpos(text_cpos_list))) + text_payload['num_ent_types'] = len(set(text_ent_type_ids)) + text_payload['ent_type_freqs'] = dict(Counter(cqi_ent_type_attr.values_by_ids(text_ent_type_ids))) + text_payload['num_unique_ent_types'] = len(text_payload['ent_type_freqs']) + for text_sub_attr in cqi_corpus.structural_attributes.list(filters={'part_of': cqi_text_attr}): + text_payload[text_sub_attr.name[(len(cqi_text_attr.name) + 1):]] = text_sub_attr.values_by_ids([text_id])[0] + payload['texts'].append(text_payload) + # print(payload) + return {'code': 200, 'msg': 'OK', 'payload': payload} + + @socketio.on('cqi.corpora.corpus.paginate', namespace=ns) @socketio_login_required @cqi_over_socketio @@ -52,13 +119,13 @@ def cqi_corpora_corpus_paginate(cqi_client: cqi.CQiClient, corpus_name: str, pag per_page < 1 or page < 1 or ( - cqi_corpus.attrs['size'] > 0 - and page > math.ceil(cqi_corpus.attrs['size'] / per_page) + cqi_corpus.size > 0 + and page > math.ceil(cqi_corpus.size / per_page) ) ): return {'code': 416, 'msg': 'Range Not Satisfiable'} first_cpos = (page - 1) * per_page - last_cpos = min(cqi_corpus.attrs['size'], first_cpos + per_page) + last_cpos = min(cqi_corpus.size, first_cpos + per_page) cpos_list = [*range(first_cpos, last_cpos)] lookups = lookups_by_cpos(cqi_corpus, cpos_list) payload = {} @@ -67,7 +134,7 @@ def cqi_corpora_corpus_paginate(cqi_client: cqi.CQiClient, corpus_name: str, pag # the lookups for the items payload['lookups'] = lookups # the total number of items matching the query - payload['total'] = cqi_corpus.attrs['size'] + payload['total'] = cqi_corpus.size # the number of items to be displayed on a page. payload['per_page'] = per_page # The total number of pages diff --git a/app/static/js/CorpusAnalysis/CQiClient.js b/app/static/js/CorpusAnalysis/CQiClient.js index fcc0c87d..5baa59e8 100644 --- a/app/static/js/CorpusAnalysis/CQiClient.js +++ b/app/static/js/CorpusAnalysis/CQiClient.js @@ -98,6 +98,20 @@ class CQiCorpus { this.subcorpora = new CQiSubcorpusCollection(this.socket, this); } + getVisualizationData() { + return new Promise((resolve, reject) => { + const args = {corpus_name: this.name}; + + this.socket.emit('cqi.corpora.corpus.get_visualization_data', args, response => { + if (response.code === 200) { + resolve(response.payload); + } else { + reject(response); + } + }); + }); + } + getCorpusData() { return new Promise((resolve, reject) => { const dummyData = { diff --git a/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js b/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js index cb012730..c955117b 100644 --- a/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js +++ b/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js @@ -34,6 +34,15 @@ class CorpusAnalysisApp { .then( cQiCorpus => { this.data.corpus = {o: cQiCorpus}; + // this.data.corpus.o.getVisualizationData() + // .then( + // (visualizationData) => { + // console.log(visualizationData); + // this.renderGeneralCorpusInfo(visualizationData); + // this.renderTextInfoList(visualizationData); + // this.renderTextProportionsGraphic(visualizationData); + // } + // ); this.data.corpus.o.getCorpusData() .then(corpusData => { this.renderGeneralCorpusInfo(corpusData); From 972f514e6bc88e0dd651dfb966c5ec9aacb6a62e Mon Sep 17 00:00:00 2001 From: Patrick Jentsch Date: Fri, 16 Jun 2023 17:35:54 +0200 Subject: [PATCH 2/3] Implementation of visdata v2 --- .../cqi_over_socketio/cqi_corpora_corpus.py | 179 ++++++++++++------ 1 file changed, 124 insertions(+), 55 deletions(-) diff --git a/app/corpora/cqi_over_socketio/cqi_corpora_corpus.py b/app/corpora/cqi_over_socketio/cqi_corpora_corpus.py index 79b1a800..fff6a0b3 100644 --- a/app/corpora/cqi_over_socketio/cqi_corpora_corpus.py +++ b/app/corpora/cqi_over_socketio/cqi_corpora_corpus.py @@ -49,62 +49,131 @@ def cqi_corpora_corpus_update_db(cqi_client: cqi.CQiClient, corpus_name: str): @socketio_login_required @cqi_over_socketio def cqi_corpora_corpus_get_visualization_data(cqi_client: cqi.CQiClient, corpus_name: str): - cqi_corpus = cqi_client.corpora.get(corpus_name) + corpus = cqi_client.corpora.get(corpus_name) + text = corpus.structural_attributes.get('text') + s = corpus.structural_attributes.get('s') + ent = corpus.structural_attributes.get('ent') + word = corpus.positional_attributes.get('word') + lemma = corpus.positional_attributes.get('lemma') + pos = corpus.positional_attributes.get('pos') + simple_pos = corpus.positional_attributes.get('simple_pos') payload = {} - payload['num_tokens'] = cqi_corpus.size - cqi_word_attr = cqi_corpus.positional_attributes.get('word') - payload['num_unique_words'] = cqi_word_attr.lexicon_size - payload['word_freqs'] = dict(zip(cqi_word_attr.values_by_ids(list(range(0, cqi_word_attr.lexicon_size))), cqi_word_attr.freqs_by_ids(list(range(0, cqi_word_attr.lexicon_size))))) - # payload['word_freqs'].sort(key=lambda a: a[1], reverse=True) - # payload['word_freqs'] = {k: v for k, v in payload['word_freqs']} - cqi_lemma_attr = cqi_corpus.positional_attributes.get('lemma') - payload['num_unique_lemmas'] = cqi_lemma_attr.lexicon_size - payload['lemma_freqs'] = dict(zip(cqi_lemma_attr.values_by_ids(list(range(0, cqi_lemma_attr.lexicon_size))), cqi_lemma_attr.freqs_by_ids(list(range(0, cqi_lemma_attr.lexicon_size))))) - # payload['lemma_freqs'].sort(key=lambda a: a[1], reverse=True) - # payload['lemma_freqs'] = {k: v for k, v in payload['lemma_freqs']} - cqi_s_attr = cqi_corpus.structural_attributes.get('s') - payload['num_sentences'] = cqi_s_attr.size - # assuming all tokens are in a sentence - payload['average_sentence_length'] = payload['num_tokens'] / payload['num_sentences'] if payload['num_sentences'] != 0 else 0 - # payload['average_sentence_length'] = 0 - # for s_id in range(0, cqi_s_attr.size): - # s_lbound, s_rbound = cqi_s_attr.cpos_by_id(s_id) - # payload['average_sentence_length'] += s_rbound - s_lbound + 1 - # payload['average_sentence_length'] /= payload['num_sentences'] - cqi_ent_type_attr = cqi_corpus.structural_attributes.get('ent_type') - payload['num_ent_types'] = cqi_ent_type_attr.size - payload['ent_type_freqs'] = dict(Counter(cqi_ent_type_attr.values_by_ids(list(range(0, cqi_ent_type_attr.size))))) - payload['num_unique_ent_types'] = len(payload['ent_type_freqs']) - payload['texts'] = [] - cqi_text_attr = cqi_corpus.structural_attributes.get('text') - for text_id in range(0, cqi_text_attr.size): - text_lbound, text_rbound = cqi_text_attr.cpos_by_id(text_id) - text_cpos_list = list(range(text_lbound, text_rbound + 1)) - text_payload = {} - text_payload['num_tokens'] = text_rbound - text_lbound + 1 - text_word_ids = cqi_word_attr.ids_by_cpos(text_cpos_list) - print(text_word_ids) - text_payload['num_unique_words'] = len(set(text_word_ids)) - text_payload['word_freqs'] = dict(Counter(cqi_word_attr.values_by_ids(text_word_ids))) - text_lemma_ids = cqi_lemma_attr.ids_by_cpos(text_cpos_list) - text_payload['num_unique_lemmas'] = len(set(text_lemma_ids)) - text_payload['lemma_freqs'] = dict(Counter(cqi_word_attr.values_by_ids(text_lemma_ids))) - text_s_attr_ids = list(filter(lambda x: x != -1, cqi_s_attr.ids_by_cpos(text_cpos_list))) - text_payload['num_sentences'] = len(set(text_s_attr_ids)) - # assuming all tokens are in a sentence - text_payload['average_sentence_length'] = text_payload['num_tokens'] / text_payload['num_sentences'] if text_payload['num_sentences'] != 0 else 0 - # text_payload['average_sentence_length'] = 0 - # for text_s_id in range(0, cqi_s_attr.size): - # text_s_lbound, text_s_rbound = cqi_s_attr.cpos_by_id(text_s_id) - # text_payload['average_sentence_length'] += text_s_rbound - text_s_lbound + 1 - # text_payload['average_sentence_length'] /= text_payload['num_sentences'] - text_ent_type_ids = list(filter(lambda x: x != -1, cqi_ent_type_attr.ids_by_cpos(text_cpos_list))) - text_payload['num_ent_types'] = len(set(text_ent_type_ids)) - text_payload['ent_type_freqs'] = dict(Counter(cqi_ent_type_attr.values_by_ids(text_ent_type_ids))) - text_payload['num_unique_ent_types'] = len(text_payload['ent_type_freqs']) - for text_sub_attr in cqi_corpus.structural_attributes.list(filters={'part_of': cqi_text_attr}): - text_payload[text_sub_attr.name[(len(cqi_text_attr.name) + 1):]] = text_sub_attr.values_by_ids([text_id])[0] - payload['texts'].append(text_payload) + payload['corpus'] = {'lexicon': {}, 'values': []} + payload['corpus']['lexicon'][0] = { + 'bounds': [0, corpus.size - 1], + 'counts': { + 'text': text.size, + 's': s.size, + 'ent': ent.size, + 'token': corpus.size + }, + 'freqs': { + 'word': dict( + zip( + range(0, word.lexicon_size), + word.freqs_by_ids(list(range(0, word.lexicon_size))) + ) + ), + 'lemma': dict( + zip( + range(0, lemma.lexicon_size), + lemma.freqs_by_ids(list(range(0, lemma.lexicon_size))) + ) + ), + 'pos': dict( + zip( + range(0, pos.lexicon_size), + pos.freqs_by_ids(list(range(0, pos.lexicon_size))) + ) + ), + 'simple_pos': dict( + zip( + range(0, simple_pos.lexicon_size), + simple_pos.freqs_by_ids(list(range(0, simple_pos.lexicon_size))) + ) + ) + } + } + payload['text'] = {'lexicon': {}, 'values': None} + for text_id in range(0, text.size): + text_lbound, text_rbound = text.cpos_by_id(text_id) + text_cpos_range = range(text_lbound, text_rbound + 1) + text_s_ids = s.ids_by_cpos(list(text_cpos_range)) + text_ent_ids = ent.ids_by_cpos(list(text_cpos_range)) + payload['text']['lexicon'][text_id] = { + 'bounds': [text_lbound, text_rbound], + 'counts': { + 's': len([x for x in text_s_ids if x != -1]), + 'ent': len([x for x in text_ent_ids if x != -1]), + 'token': text_rbound - text_lbound + 1 + }, + 'freqs': { + 'word': dict( + Counter(word.ids_by_cpos(list(text_cpos_range))) + ), + 'lemma': dict( + Counter(lemma.ids_by_cpos(list(text_cpos_range))) + ), + 'pos': dict( + Counter(pos.ids_by_cpos(list(text_cpos_range))) + ), + 'simple_pos': dict( + Counter(simple_pos.ids_by_cpos(list(text_cpos_range))) + ) + } + } + payload['text']['values'] = [ + sub_attr.name[(len(text.name) + 1):] + for sub_attr in corpus.structural_attributes.list(filters={'part_of': text}) + ] + payload['s'] = {'lexicon': {}, 'values': None} + for s_id in range(0, s.size): + payload['s']['lexicon'][s_id] = { + # 'bounds': s.cpos_by_id(s_id) + } + payload['s']['values'] = [ + sub_attr.name[(len(s.name) + 1):] + for sub_attr in corpus.structural_attributes.list(filters={'part_of': s}) + ] + payload['ent'] = {'lexicon': {}, 'values': None} + for ent_id in range(0, ent.size): + payload['ent']['lexicon'][ent_id] = { + # 'bounds': ent.cpos_by_id(ent_id) + } + payload['ent']['values'] = [ + sub_attr.name[(len(ent.name) + 1):] + for sub_attr in corpus.structural_attributes.list(filters={'part_of': ent}) + ] + payload['lookups'] = { + 'corpus': {}, + 'text': {}, + 's': {}, + 'ent': {}, + 'word': dict( + zip( + range(0, word.lexicon_size), + word.values_by_ids(list(range(0, word.lexicon_size))) + ) + ), + 'lemma': dict( + zip( + range(0, lemma.lexicon_size), + lemma.values_by_ids(list(range(0, lemma.lexicon_size))) + ) + ), + 'pos': dict( + zip( + range(0, pos.lexicon_size), + pos.values_by_ids(list(range(0, pos.lexicon_size))) + ) + ), + 'simple_pos': dict( + zip( + range(0, simple_pos.lexicon_size), + simple_pos.values_by_ids(list(range(0, simple_pos.lexicon_size))) + ) + ) + } # print(payload) return {'code': 200, 'msg': 'OK', 'payload': payload} From f037c31b8856db181dccb641de05ef1c44119c90 Mon Sep 17 00:00:00 2001 From: Patrick Jentsch Date: Mon, 19 Jun 2023 13:22:20 +0200 Subject: [PATCH 3/3] Add more visualization data --- .../cqi_over_socketio/cqi_corpora_corpus.py | 67 ++++++++++++++++--- .../js/CorpusAnalysis/CorpusAnalysisApp.js | 1 + 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/app/corpora/cqi_over_socketio/cqi_corpora_corpus.py b/app/corpora/cqi_over_socketio/cqi_corpora_corpus.py index fff6a0b3..3e49ac09 100644 --- a/app/corpora/cqi_over_socketio/cqi_corpora_corpus.py +++ b/app/corpora/cqi_over_socketio/cqi_corpora_corpus.py @@ -50,9 +50,52 @@ def cqi_corpora_corpus_update_db(cqi_client: cqi.CQiClient, corpus_name: str): @cqi_over_socketio def cqi_corpora_corpus_get_visualization_data(cqi_client: cqi.CQiClient, corpus_name: str): corpus = cqi_client.corpora.get(corpus_name) + # s_attrs = [x for x in corpus.structural_attributes.list() if not x.has_values] + # p_attrs = corpus.positional_attributes.list() + # payload = { + # 's_attrs': {}, + # 'p_attrs': {}, + # 'values': { + # 's_attrs': {}, + # 'p_attrs': {} + # } + # } + # for s_attr in s_attrs: + # s_attr_lbound, s_attr_rbound = s_attr.cpos_by_id(text_id) + # s_attr_cpos_range = range(s_attr_lbound, s_attr_rbound + 1) + # payload['text']['lexicon'][text_id] = { + # 's_attrs': [s_attr_lbound, s_attr_rbound], + # 'counts': { + # 'token': s_attr_rbound - s_attr_lbound + 1 + # }, + # 'freqs': { + # p_attr.name: dict(Counter(p_attr.ids_by_cpos(list(s_attr_cpos_range)))) + # for p_attr in p_attrs + # } + # } + # for p_attr in p_attrs: + # payload['p_attrs'] = dict( + + # ) + # payload['values']['p_attrs'] = dict( + # zip( + # range(0, p_attr.lexicon_size), + # p_attr.values_by_ids(list(range(0, p_attr.lexicon_size))) + # ) + # ) text = corpus.structural_attributes.get('text') + text_value_names = [] + text_values = [] + for text_sub_attr in corpus.structural_attributes.list(filters={'part_of': text}): + text_value_names.append(text_sub_attr.name[(len(text.name) + 1):]) + text_values.append(text_sub_attr.values_by_ids(list(range(0, text.size)))) s = corpus.structural_attributes.get('s') ent = corpus.structural_attributes.get('ent') + ent_value_names = [] + ent_values = [] + for ent_sub_attr in corpus.structural_attributes.list(filters={'part_of': ent}): + ent_value_names.append(ent_sub_attr.name[(len(ent.name) + 1):]) + ent_values.append(ent_sub_attr.values_by_ids(list(range(0, ent.size)))) word = corpus.positional_attributes.get('word') lemma = corpus.positional_attributes.get('lemma') pos = corpus.positional_attributes.get('pos') @@ -122,10 +165,7 @@ def cqi_corpora_corpus_get_visualization_data(cqi_client: cqi.CQiClient, corpus_ ) } } - payload['text']['values'] = [ - sub_attr.name[(len(text.name) + 1):] - for sub_attr in corpus.structural_attributes.list(filters={'part_of': text}) - ] + payload['text']['values'] = text_value_names payload['s'] = {'lexicon': {}, 'values': None} for s_id in range(0, s.size): payload['s']['lexicon'][s_id] = { @@ -140,15 +180,22 @@ def cqi_corpora_corpus_get_visualization_data(cqi_client: cqi.CQiClient, corpus_ payload['ent']['lexicon'][ent_id] = { # 'bounds': ent.cpos_by_id(ent_id) } - payload['ent']['values'] = [ - sub_attr.name[(len(ent.name) + 1):] - for sub_attr in corpus.structural_attributes.list(filters={'part_of': ent}) - ] + payload['ent']['values'] = ent_value_names payload['lookups'] = { 'corpus': {}, - 'text': {}, + 'text': { + text_id: { + text_value_name: text_values[text_value_name_idx][text_id_idx] + for text_value_name_idx, text_value_name in enumerate(text_value_names) + } for text_id_idx, text_id in enumerate(range(0, text.size)) + }, 's': {}, - 'ent': {}, + 'ent': { + ent_id: { + ent_value_name: ent_values[ent_value_name_idx][ent_id_idx] + for ent_value_name_idx, ent_value_name in enumerate(ent_value_names) + } for ent_id_idx, ent_id in enumerate(range(0, ent.size)) + }, 'word': dict( zip( range(0, word.lexicon_size), diff --git a/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js b/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js index c955117b..77dfdbe1 100644 --- a/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js +++ b/app/static/js/CorpusAnalysis/CorpusAnalysisApp.js @@ -34,6 +34,7 @@ class CorpusAnalysisApp { .then( cQiCorpus => { this.data.corpus = {o: cQiCorpus}; + this.data.corpus.o.getVisualizationData().then(data => console.log(data)); // this.data.corpus.o.getVisualizationData() // .then( // (visualizationData) => {