Do not render chart when no data is found or display a message or something similar - zingchart

I'm using the drilldown pie chart to drill down into children of a node, etc. The problem is that at some point, the children do not contain any data. Is there a way to display a message or something similar inside the chart instead of a white area (because of no series data) that informs the user that there is no more data to display?

Very good question! Inside of your JSON configuration you can define the nodata attribute.
var myConfig = {
type: "bar",
noData:{
text:"Empty Series",
backgroundColor: "#20b2db"
},
series:[
{
values:[]
}
]
};
zingchart.render({
id : 'myChart',
data : myConfig,
height: 400,
width: 600
});
<!DOCTYPE html>
<html>
<head>
<script src= "https://cdn.zingchart.com/zingchart.min.js"></script>
</head>
<body>
<div id='myChart'></div>
</body>
</html>
You can even use background image like a loading screen. In the following example I'm displaying spongebob while I'm waiting for chart data to come in. So I initially render a chart with no series values and nodata defined. The image is displayed while the Ajax call happens asynchronously.
demo

Related

Cannot get PubNub EON chart to work

I have run into a dead end trying to get the following HTML to work. I am trying to use the real time gauge chart to display a value coming from a photon. This is the snippet code from the pubnub site.
(I have proven that the published value is arriving in the Javascript using the commented out pubnub code in the Javascript. The value is displayed in the P tag.)
The P tag is displayed on the screen, but no gauge is displayed.
Could you please have a look at my code and guide me on where I have made a mistake. I have not worked with EON before, so I may be making very basic mistake.
<!DOCTYPE html>
<html>
<!-- <script type="text/javascript" src="http://cdn.pubnub.com/pubnub-3.16.1.min.js"></script> -->
<script type="text/javascript" src="//pubnub.github.io/eon/v/eon/0.0.10/eon.js"></script>
<link type="text/css" rel="stylesheet" href="//pubnub.github.io/eon/v/eon/0.0.10/eon.css"/>
<div id="chart"></div>
<script type="text/javascript">
*var pubnub = PUBNUB.init({subscribe_key: 'xxxxxxx'});
/*
pubnub.subscribe ({channel : "datatest", message : function(tempmsg)
{document.getElementById("x").innerHTML = tempmsg.eon.data;}});
*/
var channel 'datatest';
eon.chart({
channel: channel,
generate: {
bindto: '#chart',
data: {
type: 'gauge',
},
gauge: {
min: 0,
max: 100
},
color: {
pattern: ['#FF0000', '#F6C600', '#60B044'],
threshold: {
values: [30, 60, 90]
}
}
}
});
</script>
<body>
<p id ="x"> This is my text that will be replaced by the value from the photon </p>
</body>
</html>
The output from the photon looks like this:
publishing message: {"eon": {"data":56}}
publishing message: {"eon": {"data":56}}
publishing message: {"eon": {"data":56}}
publishing message: {"eon": {"data":56}}
There is a missing line of code in the PubNub EON JavaScript embed code for the Gauge Chart.
You must add pubnub: pubnub, to bind the graph instance to the PubNub stream.

Google Translate widget - responsive

On my Web page I put translate widget when i resize browsers widged does not change size
I tried change css but i can change only css for Iframe
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<script type="text/javascript" src="script.js"></script>
<script type="text/javascript">
function googleTranslateElementInit() {
new google.translate.TranslateElement({
pageLanguage: 'en',
layout: google.translate.TranslateElement.InlineLayout.SIMPLE
}, 'google_translate_element');
}
</script>
<script type="text/javascript"
src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
</head>
<body>
<div id="google_translate_element"></div>
</body>
</html>
do you heve any solution?
Google Translate popup Layout - responsive fixed
<div id="google_translate_element" style="text-align: center;"></div>
<style>
.goog-te-banner-frame.skiptranslate {
display: none !important;
}
body {
top: 0px !important;
}
.goog-te-menu-frame {
max-width:100% !important;
}
.goog-te-menu2 {
max-width: 100% !important;
overflow-x: scroll !important;
box-sizing:border-box !important;
height:auto !important;
}
</style>
<script type="text/javascript">
function googleTranslateElementInit() {
new google.translate.TranslateElement({
pageLanguage: 'en',
autoDisplay: false,
layout: google.translate.TranslateElement.InlineLayout.SIMPLE
}, 'google_translate_element');
function changeGoogleStyles() {
if($('.goog-te-menu-frame').contents().find('.goog-te-menu2').length) {
$('.goog-te-menu-frame').contents().find('.goog-te-menu2').css({
'max-width':'100%',
'overflow-x':'auto',
'box-sizing':'border-box',
'height':'auto'
});
} else {
setTimeout(changeGoogleStyles, 50);
}
}
changeGoogleStyles();
}
</script>
<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
Not the solution to resizing issue but maybe helpful. You can change the default layout in the init function of the google translate selector.
Change in the line
layout: google.translate.TranslateElement.InlineLayout.SIMPLE to layout: google.translate.TranslateElement.InlineLayout.VERTICAL or layout: google.translate.TranslateElement.InlineLayout.HORIZONTAL.
These options will show the language choices in a vertical dropdown with also either the 'Made possible by Google Translate' label under or next to it.
You will not be able to adjust the layout of this widget using strictly CSS. The <a> elements containing links for all of the languages to choose from are laid out in <td> cells in rows. Therefore, they will not be laid out dynamically with resizing.
You can however, get around this by getting all the language links in the contained <iframe> and appending them to a <div> outside the <table>.
This should perform what you seek though may still require much CSS tweaking. Much of Google's UI elements are laid out manually with pixel dimensions and overridden attributes like overflow:hidden to avoid default (sometimes inconsistent) browser behavior. This solution may require a fair bit of [poking around the DOM][1] to determine where these adjustments are being done.
This should be executed in the top-most frame to access the <iframe> element and make changes to its CSS. Note that the selector is not a unique ID so it may return a different <iframe> than expected depending on the contents of your page.
var iframe = document.querySelector('.goog-te-menu-frame.skiptranslate');
if (iframe === null) {
console.error('Could not find iframe of language links');
} else {
// Force <iframe> visibility and auto-resizing
iframe.style.display = '';
iframe.style.height = '';
iframe.style.width = '99%!important';
This should be executed in the about:blank frame of the <iframe> to have access to the elements within.
// Get all the <a> elements
var anchors = document.querySelectorAll('a.goog-te-menu2-item');
anchors = Array.prototype.slice.call(language_anchors);
if (anchors.length < 1) {
console.error('Found no language links');
}
// Get the conatiner <div> that holds the table of links
var div = document.getElementById(':1.menuBody');
if (div === null) {
console.error('Could not find div containing table of language links');
} else {
// Remove width/height attributes to have <div> resize
div.style.height = '';
div.style.width = '';
// Iterate through all language links
anchors.forEach(function (a) {
// Set display to inline=block so its rendered like text
// This is what gets the elements onto a new line if they don't fit
a.style.display = 'inline-block';
// Append them directly to the <div>
div.appendChild(a);
});
// Remove the now empty <table> to keep things clean
div.removeChild(div.querySelector('table'));
}
This may break easily if Google changes their CSS class names or element IDs. Keep that in mind and happy rendering.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<script type="text/javascript" src="script.js"></script>
<script type="text/javascript">
function googleTranslateElementInit() {
new google.translate.TranslateElement({
pageLanguage: 'en',
layout: google.translate.TranslateElement.InlineLayout.HORIZONTAL
}, 'google_translate_element');
}
</script>
<script type="text/javascript"
src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
</head>
<body>
<div id="google_translate_element"></div>
</body>
</html>
YOU NEED TO CHANGE THE "SIMPLE" TO "HORIZONTAL"
You can put this in your css file for the theme that you're using. Tweak it to make it work for you. Hope that helps!
select.goog-te-combo{width:100%!important;}

Plot dimple(d3.js) chart in deck.js section

I would like to insert a dimple plot into a deck.js presentation. The code below online puts the plot in the body at the background. But I would like to have the plot displayed in the section class. I think I have to change something in var svg = dimple.newSvg("body", 800, 600). Because of my very limited javascript skills I have no idea what to change exactly. Any help would be very much appreciated.
<section class="slide" id="test-section">
<h2>test section</h2>
<script type="text/javascript">
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://dimplejs.org/dist/dimple.v1.min.js"></script>
var svg = dimple.newSvg("body", 800, 600);
var data = [
{ "Word":"Hello", "Awesomeness":2000 },
{ "Word":"World", "Awesomeness":3000 }
];
var chart = new dimple.chart(svg, data);
chart.addCategoryAxis("x", "Word");
chart.addMeasureAxis("y", "Awesomeness");
chart.addSeries(null, dimple.plot.bar);
chart.draw();
</script>
</section>
If only the included the specific section class code in my question. If needed the complete code can be found here. The index page in the is located in the introduction folder.
A couple things need fixing:
First, you can't put a script tag inside of another script tag. You should move the code that loads d3 and dimple to the head of the document:
...
<script src="../modernizr.custom.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://dimplejs.org/dist/dimple.v1.min.js"></script>
</head>
Second, as you suspected and John points out, something with dimple.newSvg is wrong. You probably want var svg = dimple.newSvg("#test-section", 800, 600); so the graph is only added to the test-selection slide, not all of the slides.
I would actually go one step farther and change the html a little bit so you can control precisely where the graph appears:
<h2>Graph Title</h2>
<div id = "graphHere"></div>
<h3>Some more text about the graph below the graph</h3>
To make the graph appear between the text, just change the selection passed to dimple to the id of the div we've created:
var svg = dimple.newSvg("#graphHere", 800, 600);
Finally, chart.js is doing some weird resizing the graph since it is too big to fit on the slide. Without digging through the source of chart.js, we can fix the problem by creating a smaller graph:
var svg = dimple.newSvg("#graphHere", 400, 200);
I like the look of deck.js so I just pulled it down and had a play. I then came back and found Adam had basically explained everything I just found out. You need to put a div within the slide and add the svg to that, otherwise the deck scaling code duplicates the chart.
First add a div to the relevant slide:
<section class="slide">
<div id="myChartDiv"></div>
</section>
Then add the references to the set at the bottom (or the header if you like):
<!-- Required JS files. -->
<script src="jquery-1.7.2.min.js"></script>
<script src="core/deck.core.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://dimplejs.org/dist/dimple.v1.min.js"></script>
then the dimple code below that:
<script type="text/javascript">
var svg = dimple.newSvg("#myChartDiv", 800, 600);
var data = [
{ "Word":"Hello", "Awesomeness":2000 },
{ "Word":"World", "Awesomeness":3000 }
];
var chart = new dimple.chart(svg, data);
chart.addCategoryAxis("x", "Word");
chart.addMeasureAxis("y", "Awesomeness");
chart.addSeries(null, dimple.plot.bar);
chart.draw();
</script>
I hope that hopes
John
I've never used deck.js but have you tried:
var svg = dimple.newSvg(".slide", 800, 600);
or
var svg = dimple.newSvg("#test-section", 800, 600);
Let me know if that works. If not I'll take a look at your code.
I know that this thread is from a long time ago, but let me add one thing in addition to Adam's answer.
At least on dimple v2.1.2 + deck.js v1.1.0 + Firefox 34.0, the graph is corrupted in Adam's example.
It seems that the size of the div tag must be explicitly set:
<div id="graphHere" style="width:400px;height:300px;"></div>
...
<script>
var svg = dimple.newSvg("#graphHere", 400, 300);
// plotting function goes here
</script>

SVG shapes added to Raphael group fire events as if separate

Imagine this:
2 concentric circles, with the smaller one over the larger one so
that both are visible
both are added to a Raphael group (set)
the group has mouseout and mouseover event handlers
Problem:
When the cursor goes from one circle to the other, both event handlers fire, as if they were added separately to each circle.
What I want is for events to be handled for the entire group as if it was a single shape.
How can I achieve that?
Here's the html code:
<!DOCTYPE html>
<html>
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/raphael/2.0.0/raphael-min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<div id="target"></div>
</body>
</html>
Javascript:
var W=200;
var H=200;
var paper=new Raphael(document.getElementById('target'),W,H);
var c1=paper.circle(W/2,H/2,70).attr({fill:'orange','stroke-width':4,stroke:'red',opacity:0.7});
var c2=paper.circle(W/2,H/2,50).attr({fill:'green','stroke-width':4,stroke:'yellow',opacity:0.7});
var group=paper.set();
group.push(c1,c2);
var count=0;
group.mouseover(function()
{
console.log('IN',++count);
});
group.mouseout(function()
{
console.log('OUT',++count);
});
and the CSS code:
#target{width:200px;}
Run the above code and see the results here: http://jsbin.com/ivules/7.
Console shows IN and OUT logs.
Just move the mouse between the two circles' bounds.
For your mouseout() function, please try:
group.mouseout(function()
{
this.mouseout(function(){
console.log('OUT',++count);
});
});
When you hover over the outer circle, you will get "IN". When you hover over the inner circle, you will get "IN" again. When you leave the circle entirely, you will finally get "OUT".
If that's too many "IN"'s, try creating an invisible circle, place it over top the current 2 circles, and only add the mouseover event to that circle. For instance, try:
c3=paper.circle(W/2,H/2,70).attr({fill:'orange','stroke-width':4,stroke:'red',opacity:0});
c3.mouseover(function()
{
console.log('IN',++count);
});
c3.mouseout(function()
{
console.log('OUT',++count);
});

How to render a YUI datatable?

Following the documentation of the YUI DataTable control i've inferred the following code:
<!DOCTYPE HTML>
<HTML>
<HEAD>
<SCRIPT type="text/javascript" src="http://yui.yahooapis.com/3.5.1/build/yui/yui-min.js"></SCRIPT>
<SCRIPT type="text/javascript">
// Create a new YUI instance and populate it with the required modules.
YUI().use('datatable', function (Y) {
// Columns must match data object property names
var data = [
{ id: "ga-3475", name: "gadget", price: "$6.99", cost: "$5.99" },
{ id: "sp-9980", name: "sprocket", price: "$3.75", cost: "$3.25" },
{ id: "wi-0650", name: "widget", price: "$4.25", cost: "$3.75" }
];
var table = new Y.DataTable({
columns: ["id", "name", "price"],
data: data,
// Optionally configure your table with a caption
caption: "My first DataTable!",
// and/or a summary (table attribute)
summary: "Example DataTable showing basic instantiation configuration"
});
table.render("#example");
});
</SCRIPT>
</HEAD>
<BODY>
</BODY>
</HTML>
The insulting thing is that the documentation says:
This code produces this table:
except that this code produces this table:
So obviously i'm missing something pretty fundamental about how to render a YUI data table. What is the correct way to render a YUI data table?
Q. How to render a YUI datatable?
Another page mentions including a <div>, changing my <BODY> from empty to:
<BODY>
<div class="example yui3-skin-sam">
<div id="simple"></div>
<div id="labels"></div>
</div>
</BODY>
but does not change the look of the control.
Add class="yui3-skin-sam" in body tag, table css is written corresponding to this class.
Move the <script>s to the bottom of the <body>, or at least after the <div> that will contain the DataTable. That will avoid a race condition where the scripts may be loaded before the DOM is set up.
render('#example') is telling the DataTable to render into an element with an id of 'example' The markup sample you included has a div with a class of 'example', then two divs with ids 'simple' and 'labels'. You need to make sure you're rendering inside a parent element with class yui3-skin-sam. If you tell a YUI widget to render into an element it can't find, it falls back to rendering it inside the <body>. You can fix this in a few ways:
add the class to the <body> tag instead of a <div> (not a bad idea, but you should still fix the render target selector)
use a render(?) target selector that matches an element on the page, such as render('.example'), render('#simple'), or render('#labels').
In any case, make sure your render target is inside an element with class="yui3-skin-sam"

Resources