Skip to content

Instantly share code, notes, and snippets.

@vabarbosa
Last active October 24, 2024 20:16
Show Gist options
  • Save vabarbosa/bff35152c3888f4e2c0ad92e2511dc2b to your computer and use it in GitHub Desktop.
Save vabarbosa/bff35152c3888f4e2c0ad92e2511dc2b to your computer and use it in GitHub Desktop.
add simple data visualizations to Cloudant and CouchDB views
// ==UserScript==
// @name chango
// @namespace vabarbosa.simple-data-vis
// @description add simple data visualizations to cloudant.com and couchdb views
// @match *://*.cloudant.com/dashboard.html*
// @include /^http://127.0.0.1:5984/_utils/#/database/.*/_design/.*/_view/.*$/
// @require https://d3js.org/d3.v4.min.js
// @require https://raw.githubusercontent.com/vabarbosa/simple-data-vis/master/simpledatavis.js
// @require https://raw.githubusercontent.com/vabarbosa/simple-data-vis/master/vis/simpledatavis-barchart.js
// @require https://raw.githubusercontent.com/vabarbosa/simple-data-vis/master/vis/simpledatavis-bubblechart.js
// @require https://raw.githubusercontent.com/vabarbosa/simple-data-vis/master/vis/simpledatavis-groupedbarchart.js
// @require https://raw.githubusercontent.com/vabarbosa/simple-data-vis/master/vis/simpledatavis-piechart.js
// @require https://raw.githubusercontent.com/vabarbosa/simple-data-vis/master/vis/simpledatavis-table.js
// @require https://raw.githubusercontent.com/vabarbosa/simple-data-vis/master/vis/simpledatavis-rangebarchart.js
// @grant none
// @author va barbosa
// @version 0.8.3
// ==/UserScript==
// check if in a View
function inDesignView () {
// console.log('chango... inDesignView');
if (/#\/database\/.*\/_design\/.*\/_view\/.*/.test(location.hash)) {
return true;
}
}
// define css style
function setupCSS () {
// console.log('chango... setupCSS');
var style = document.querySelector('style[data-chango]');
if (!style) {
var css =
'.chango-vis-chart {' +
'height: 60vh;' +
'padding: 25px; }' +
'.chango-vis-spinner {' +
'background-color: rgba(0, 0, 0, 0.1);' +
'bottom: 0;' +
'display: none;' +
'left: 0;' +
'position: absolute;' +
'right: 0;' +
'text-align: center;' +
'top: 0;' +
'z-index: 100; }' +
'.chango-vis-spinner span {' +
'display: inline-block;' +
'font-size: 2em;' +
'margin: 50px;' +
'-webkit-animation-name: chango-vis-loading;' +
'-webkit-animation-duration: 0.5s;' +
'-webkit-animation-timing-function: linear;' +
'-webkit-animation-iteration-count: infinite;' +
'animation-name: chango-vis-loading;' +
'animation-duration: 0.5s;' +
'animation-timing-function: linear;' +
'animation-iteration-count: infinite; }' +
'@-webkit-keyframes chango-vis-loading {' +
'from { -webkit-transform: rotate(0deg); }' +
'to { -webkit-transform: rotate(360deg); } }' +
'@keyframes chango-vis-loading {' +
'from { transform: rotate(0deg); }' +
'to { transform: rotate(360deg); } }';
// append style sheet
style = document.createElement('style');
style.setAttribute('data-chango', 'true')
if (style.styleSheet) {
style.styleSheet.cssText = css;
}
else {
style.appendChild(document.createTextNode(css));
}
document.getElementsByTagName('head')[0].appendChild(style);
}
}
// add chart button
function addChartButton () {
// console.log('chango... addChartButton');
var buttonGroup = document.querySelector('.two-sides-toggle-button.btn-group');
var chartBtn = document.getElementById('chango-btn');
if (buttonGroup && !chartBtn) {
document.getElementById('footer').style.display = 'initial';
chartBtn = document.createElement('button');
chartBtn.id = 'chango-btn';
chartBtn.className = 'btn btn-default';
var span = document.createElement('span');
span.innerHTML = '<i class="fonticon-stats"></i> Chart';
chartBtn.appendChild(span);
buttonGroup.appendChild(chartBtn);
attachButtonsListener();
}
return chartBtn
}
// remove chart button
function removeChartButton () {
// console.log('chango... removeChartButton');
var chartBtn = document.getElementById('chango-btn');
if (chartBtn) {
chartBtn.parentNode.removeChild(chartBtn)
}
}
// attach to the json, metadata, table buttons click event
function attachButtonsListener () {
// console.log('chango... attachButtonsListener');
var buttons = document.querySelectorAll('.two-sides-toggle-button > button');
[].forEach.call(buttons, function(btn) {
if (btn.id === 'chango-btn') {
attachChangoListener(btn);
}
else {
btn.addEventListener("click", function(event) {
var chartBtn = document.getElementById('chango-btn');
if (chartBtn.className.indexOf('active') != -1) {
document.getElementById('footer').style.display = 'initial';
chartBtn.className = chartBtn.className.replace('active', '').trim();
btn.className += ' active';
var container = document.querySelector('.chango-vis');
if (container) {
container.parentNode.removeChild(container);
}
container = document.getElementById('doc-list') || document.querySelector('.table-view-docs');
if (container) {
container.style.display = '';
}
}
});
}
});
}
// attach to the chart button click event
function attachChangoListener (chartBtn) {
// console.log('chango... attachChangoListener');
if (chartBtn) {
chartBtn.addEventListener("click", function(event) {
var apiUrl = getApiUrl();
if (!apiUrl) {
console.warn('cloudant-eyecandy: Unable to obtain the API url');
}
else {
// apiUrl = apiUrl.replace(/limit=(\d)+/g, '');
var activeBtn = document.querySelector('.two-sides-toggle-button > button.active');
if (activeBtn.id !== 'chango-btn') {
prevBtn = activeBtn;
activeBtn.className = activeBtn.className.replace('active', '').trim();
chartBtn.className += ' active';
addChartDiv();
}
renderChart(apiUrl)
}
});
}
}
// add chart container div
function addChartDiv () {
// console.log('chango... addChartDiv');
document.getElementById('footer').style.display = 'none';
var container = document.getElementById('doc-list') || document.querySelector('.table-view-docs');
var parent = container ? container.parentNode : null;
if (parent) {
container.style.display = 'none';
container = document.createElement('div');
container.className = 'chango-vis';
container.innerHTML = '<div class="chango-vis-spinner"><span>&profline;</span></div><div class="chango-vis-chart"></div>';
parent.appendChild(container);
}
}
// remove chart container div
function removeChartDiv () {
// console.log('chango... removeChartDiv');
var container = document.getElementById('doc-list') || document.querySelector('.table-view-docs');
var parent = container ? container.parentNode : null;
if (parent) {
var visdiv = document.getElementsByClassName('chango-vis')[0];
if (visdiv) {
parent.removeChild(visdiv);
}
}
}
// run simple-data-vis to render chart
function renderChart (apiUrl) {
// console.log('chango... renderChart');
SimpleDataVis(apiUrl)
.on('fail', function(msg) {
console.error('Failed to render chart:', msg);
})
.on('start', function() {
document.querySelector('.chango-vis-spinner').style.display = 'block';
})
.on('data', function(data) {
document.querySelector('.chango-vis-spinner').style.display = 'none';
return data;
})
.render('.chango-vis-chart');
}
// get the api url from the api dropdown
function getApiUrl () {
var apiUrl = null;
var apiBtn = document.querySelector('button.control-toggle-api-url');
if (apiBtn) {
apiBtn.click();
var apiUrlContainer = document.querySelector('.api-bar-tray [data-clipboard-text]');
if (apiUrlContainer) {
apiUrl = apiUrlContainer.getAttribute('data-clipboard-text');
}
apiBtn.click();
} else {
var jsonLink = document.querySelector('header a.faux__jsonlink-link');
if (jsonLink) {
apiUrl = jsonLink.href;
}
}
console.log('chango... ', apiUrl);
return apiUrl;
}
// update page accordingy when it changes
function handlePageChange () {
// console.log('chango... handlePageChange');
if (inDesignView()) {
var chartBtn = addChartButton()
if (chartBtn && chartBtn.className.indexOf('active') > -1) {
chartBtn.className = chartBtn.className.replace('active', '').trim();
if (prevBtn) {
prevBtn.className += ' active';
}
removeChartDiv();
}
} else {
if (prevBtn) {
prevBtn.className += ' active';
}
removeChartDiv()
removeChartButton()
}
}
// previously active button
var prevBtn = null;
// run initialization
function initChango () {
setupCSS()
prevBtn = document.querySelector('.two-sides-toggle-button > button');
if (inDesignView()) {
addChartButton();
}
window.addEventListener('popstate', handlePageChange);
}
setTimeout(initChango, 500);
@sauraba
Copy link

sauraba commented Oct 25, 2018

Script download is failing with error - 404 - Not Found at https://ibm-watson-data-lab.github.io/simple-data-vis/simpledatavis.js

@PrapthiCariappa
Copy link

Unable to install the raw script with grease monkey extension in Firefox.

User script download failed

404 - Not Found at https://ibm-watson-data-lab.github.io/simple-data-vis/simpledatavis.js
404 - Not Found at https://ibm-watson-data-lab.github.io/simple-data-vis/vis/simpledatavis-barchart.js
404 - Not Found at https://ibm-watson-data-lab.github.io/simple-data-vis/vis/simpledatavis-bubblechart.js
404 - Not Found at https://ibm-watson-data-lab.github.io/simple-data-vis/vis/simpledatavis-groupedbarchart.js
404 - Not Found at https://ibm-watson-data-lab.github.io/simple-data-vis/vis/simpledatavis-piechart.js
404 - Not Found at https://ibm-watson-data-lab.github.io/simple-data-vis/vis/simpledatavis-table.js
404 - Not Found at https://ibm-watson-data-lab.github.io/simple-data-vis/vis/simpledatavis-rangebarchart.js

@vabarbosa
Copy link
Author

vabarbosa commented Nov 23, 2018

@sauraba @PrapthiCariappa
i have updated the script and fixed a few other issues. it is working again for me. please update your user script and let me know if you notice any other issues.

@PrapthiCariappa
Copy link

@vabarbosa It's working now. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment