How to properly render the kendo chart custom labels - javascript

I neede to customize labels (like a bubbletalk) of a kendo line chart.
I build a template (like in this kendo test: http://dojo.telerik.com/#PMcDonou/URiZA. I took this demo from an admin solution in a kendo forum thread) and it work when load the page first time, but in some situations kendo UI not render the labels.
The problem appears in this two cases:
When I refresh manually chart with a button that to click on it you need to
scroll the page.
When i refresh the page(F5) after that i scrolled down the page.
I noticed that the position of the labels moves upwards based on the offset from top given by scrolling.
I did this fiddle for you to see the first case.
For see an example of the second case look the fiddle in a full screen page, try to scroll down and refresh the page(F5) and try this in multiple positions of scroll. Thank you for attention and help me please.
function createChart(){
var dataSource = new kendo.data.DataSource({
data: [{
category: "A", value: 10
}, {
category: "B", value: 20
}, {
category: "C", value: 30
}]
});
var labelTemplate = kendo.template($("#labelTemplate").html());
$("#chart").kendoChart({
dataSource: dataSource, series: [{
type: "line", style: "smooth", field: "value", categoryField: "category", labels: {
visible: true, template: "#= category #", visual: function(e) {
var dataItem = $.grep(dataSource.data(), function(item) {
return item.category === e.text;
})[0];
// Label origin position (same as where the original label would be)
var origin = e.rect.origin;
var content = $('<div/>')
.css({
position: "absolute",
font: "11px Arial,Helvetica,sans-serif",
left: 0,
top: 0
})
.appendTo(document.body)
.html(labelTemplate(dataItem));
var visual = new kendo.drawing.Group();
kendo.drawing.drawDOM(content).done(function(group) {
// Place drawn shapes on original label position
group.transform(kendo.geometry.transform().translate(origin.x, origin.y));
visual.append(group);
// Remove element from DOM
content.remove();
});
return visual;
}
}
}]
});
}
$(function(){
createChart();
$("#refreshChart").on("click", function(){
$("#chart").data("kendoChart").refresh();
})
});
.talk-bubble {
width: auto;
height: auto;
background-color: red;
color: white;
border-radius: 30px;
}
.talktext {
padding: 1em;
text-align: left;
line-height: 1.5em;
}
.talktext p {
/* remove webkit p margins */
-webkit-margin-before: 0em;
-webkit-margin-after: 0em;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.common.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.rtl.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.default.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.2.621/styles/kendo.mobile.all.min.css">
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.2.621/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.2.621/js/jszip.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.2.621/js/kendo.all.min.js"></script>
</head>
<body>
<!-- Div for chart -->
<div id="chart"></div>
<!-- Example div container -->
<h1>Go down and click button</h1>
<div style="height:3000px; background-color: yellow;"></div>
<!-- Button that refresh chart -->
<h3>Click button</h3>
<button type="button" id="refreshChart">Refresh chart</button>
<h1>Now go up, label not rendered</h1>
<!-- Label Template Custom -->
<script id="labelTemplate" type="text/x-kendo-template">
<div class="talk-bubble">
<div class="talktext">
<p>Value: #= kendo.format('{0:n2}', data.value) #</p>
</div>
</div>
</script>
</body>
</html>

Related

Updating jquery-ui tooltip during hide animation breaks it

Whenever you update the content of a jquery-ui tooltip while the hide-animation is running, it'll pop back into visibility and enter some broken state where it is visible forever and unresponsive to events.
Yeah, i know, i know, the lib is dead.
Still, is there any way to get around this bug? I need to update my tooltip in 1 second intervals because it has a timer in it, and I would like to use a fade-out animation somehow.
Demo:
Just move the mouse in and out of the first block a couple of times:
$("#animated").tooltip( {items: "div", content: ""} );
$("#not-animated").tooltip( {items: "div", hide: false, content: ""} );
setInterval( function() {
$("#animated").tooltip("option", "content", Math.random().toFixed(3));
$("#not-animated").tooltip("option", "content", Math.random().toFixed(3));
}, 500 );
.item {
display: inline-block;
background-color: DeepSkyBlue;
padding: 12px;
}
<html>
<head>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
</head>
<body>
<div class="item" id="animated">hiding animated</div>
<div class="item" id="not-animated">hiding not animated</div>
</body>
</html>
You could try updating the .ui-tooltip-content element manually.
$(function() {
function getRandom() {
return Math.random().toFixed(3);
}
function updateContent() {
$(".ui-tooltip-content", $("#animated").tooltip("widget")).html(getRandom());
$("#not-animated").tooltip("option", "content", getRandom());
}
$("#animated").tooltip({
items: "div",
hide: 200,
content: getRandom
});
$("#not-animated").tooltip({
items: "div",
hide: false,
content: getRandom
});
var intv = setInterval(updateContent, 500);
});
.item {
display: inline-block;
background-color: DeepSkyBlue;
padding: 12px;
}
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="item" id="animated">hiding animated</div>
<div class="item" id="not-animated">hiding not animated</div>

jQuery autocomplete: undefined value pressing the UP arrow key

I am working on an app where I need an input with the autocomplete function provided by jQuery. Everything is okay, until I add some more elements into the <ul> where the options are actually added.
What I need, is some 'contextual help' where I can show to the user some basic queries he can enter there.
They appear and they seem to work, until you press the UP arrow key multiple times. If you are on the first element and press the up arrow key, the focus moves to the input. If I press the up arrow key again, an error appears and my app crashes:
uncaught TypeError: Cannot read property 'value' of undefined
at $.(fiddle.jshell.net/_display/anonymous function).(anonymous function).menufocus (https://code.jquery.com/ui/1.12.1/jquery-ui.js:5831:25)
at HTMLUListElement.handlerProxy (jquery-ui.js:606)
........
The down arrow key is working without problems.
You can check a jsfiddle here or the one below.
How to replicate the error:
Focus on the input box and write COM; a dummy autocomplete will apear
Use the down arrow key to move down 1-2 elements; then, use the up arrow key to move back to the first element;
Press the up arrow key to move the focus onto the input box
Press the up arrow key again
var tags = ["COMMAND_1", "COMMAND_2", "COMMAND_3", "COMMAND_4"];
$("#autocomplete").autocomplete({
open: function(e, ui) {
var autocompleteElement = $('.ui-autocomplete');
contextualItems = ["COMMAND_1 {item}", "COMMAND_2 {item}", "COMMAND_3 {item}", "COMMAND_4 [{item_1}, {item_2}]"]
autocompleteElement.append('<li class="ch">Contextual Help</li>');
for (var i = 0; i < contextualItems.length; i++) {
autocompleteElement.append('<li class="ui-autocomplete-category" style="background-color: #EEE; padding-top: 5px">' + contextualItems[i] + '</li>');
console.log(contextualItems[i]);
}
},
source: function(request, response) {
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term), "i");
response($.grep(tags, function(item) {
return matcher.test(item);
}));
}
});
.ch {
background-color: #EEE;
border-top: solid 1px grey;
padding-top: 5px;
text-align: center;
font-weight: bold
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>autocomplete demo</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.12.4.js"></script>
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<label for="autocomplete">Select a programming language: </label>
<input id="autocomplete">
</body>
</html>
I tried changing the Contextual Help in a div, I tried to use categories, but I did not succeed. Can you please give me a hint or an idea on how I might solve this?
Thanks!
Jquery-UI's autocomplete always will create a menu with an items option that accepts all children as menu items. Unfortunately, it's hardcoded in the autocomplete class. You can change the option to avoid selecting elements that aren't proper items, but JQuery recommends against changing it after the menu is already created. Still, you can still do it, and it seems to work for me. To change the items option in the ui-menu that is created after the autocorrect input, I did:
$("#autocomplete ~ .ui-menu").menu("option", "items", "> :not(.ui-autocomplete-category):not(.ch)" );
In my example, I used the sibling selector so that you can have it particular to the autocomplete id (assuming there's only at most one autocomplete per container) if you want to. Whatever is the best way for you to select the ui-menu is what you should use; this was just an example.
var tags = ["COMMAND_1", "COMMAND_2", "COMMAND_3", "COMMAND_4"];
$("#autocomplete").autocomplete({
open: function(e, ui) {
var autocompleteElement = $('.ui-autocomplete');
contextualItems = ["COMMAND_1 {item}", "COMMAND_2 {item}", "COMMAND_3 {item}", "COMMAND_4 [{item_1}, {item_2}]"]
autocompleteElement.append('<li class="ch">Contextual Help</li>');
for (var i = 0; i < contextualItems.length; i++) {
autocompleteElement.append('<li class="ui-autocomplete-category" style="background-color: #EEE; padding-top: 5px">' + contextualItems[i] + '</li>');
console.log(contextualItems[i]);
}
},
source: function(request, response) {
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term), "i");
response($.grep(tags, function(item) {
return matcher.test(item);
}));
}
});
$("#autocomplete ~ .ui-menu").menu("option", "items", "> :not(.ui-autocomplete-category):not(.ch)");
.ch {
background-color: #EEE;
border-top: solid 1px grey;
padding-top: 5px;
text-align: center;
font-weight: bold
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>autocomplete demo</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<label for="autocomplete">Select a programming language: </label>
<input id="autocomplete">
</body>
</html>
JSFiddle at:
https://jsfiddle.net/p1y2587a/7/
As mentioned in the comments, I doubt you're supposed to manually change the contents of .ui-autocomplete.
What you can do instead is add a contextual help element outside of the dropdown and position it dynamically upon focus (or any other event, depending):
var tags = ["COMMAND_1", "COMMAND_2", "COMMAND_3", "COMMAND_4"];
$("#autocomplete").autocomplete({
source: function(request, response) {
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term), "i");
response($.grep(tags, function(item) {
return matcher.test(item);
}));
},
focus: function(event, ui) {
$('[data-context-help]')
.css({
top: $('.ui-autocomplete').position().top + $('.ui-autocomplete').outerHeight(true),
left: $('.ui-autocomplete').position().left,
width: $('.ui-autocomplete').outerWidth(true)
})
.text('Help for ' + ui.item.value)
.show()
},
close: function(event, ui) {
$('[data-context-help]').hide();
}
});
.ch {
background-color: #EEE;
border-top: solid 1px grey;
padding-top: 5px;
text-align: center;
font-weight: bold;
position: absolute;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>autocomplete demo</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.12.4.js"></script>
<script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>
<body>
<label for="autocomplete">Select a programming language: </label>
<input id="autocomplete">
<div data-context-help class="ch" style="display:none">Help goes here</div>
</body>
</html>

Set header and footer reveal.js presentation

I want to set a header and footer in my presentation. I used the following issue as a starting point: https://github.com/hakimel/reveal.js/issues/806 and http://www.ciges.net/revealjs_demo/#/
My current implementation gives the following output:
Now as far as I have understand reveal.js uses fixed size for the presentation by default with a width of 960px and height of 700px. This size is completely fine to me. However, I want the headers and footer not to be fixed in this window. They need to adapt to the actual screen size. That is to say, I want the left header to be aligned to the top left corner of the screen. Likewise for the other header and footers, see also the image. How can I achieve this? Currently it seems that my headers and footers are fixed within the default window (960x700).
I use the following code (index.html) with reveal.js 3.2.0
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>reveal.js – The HTML Presentation Framework</title>
<meta name="description" content="A framework for easily creating beautiful presentations using HTML">
<meta name="author" content="Hakim El Hattab">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/simple.css" id="theme">
<!-- Code syntax highlighting -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
<!--[if lt IE 9]>
<script src="lib/js/html5shiv.js"></script>
<![endif]-->
<style type="text/css">
.reveal div.header-left {
position: absolute;
top: 0;
left: 0;
padding: 0;
margin: 0;
}
.reveal div.header-right {
position: absolute;
top: 0;
right: 0;
padding: 0;
margin: 0;
}
.reveal div.footer-left {
position: absolute;
bottom: 0;
left: 0;
padding: 0;
margin: 0;
}
.reveal div.footer-right {
position: absolute;
bottom: 0;
right: 0;
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<div id="hidden" style="display:none;">
<div id="header">
<div class="header-left">test header left</div>
<div class="header-right">test header right</div>
<div class="footer-left">test footer left</div>
<div class="footer-right">test footer right</div>
</div>
</div>
<div class="reveal">
<!-- Any section element inside of this container is displayed as a slide -->
<div class="slides">
<section>
<h1>Reveal.js</h1>
<h3>The HTML Presentation Framework</h3>
<p>
<small>Created by $x^2$ Hakim El Hattab / #hakimel</small>
</p>
</section>
<section>
<h2>Hello There</h2>
<p>
reveal.js enables you to create beautiful interactive slide decks using HTML. This presentation will show you examples of what it can do.
</p>
</section>
<!-- Example of nested vertical slides -->
<section>
<section>
<h2>Vertical Slides</h2>
<p>Slides can be nested inside of each other.</p>
<p>Use the <em>Space</em> key to navigate through all slides.</p>
<br>
<a href="#" class="navigate-down">
<img width="178" height="238" data-src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
</a>
</section>
<section>
<h2>Basement Level 1</h2>
<p>Nested slides are useful for adding additional detail underneath a high level horizontal slide.</p>
</section>
<section>
<h2>Basement Level 2</h2>
<p>That's it, time to go back up.</p>
<br>
<a href="#/2">
<img width="178" height="238" data-src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Up arrow" style="transform: rotate(180deg); -webkit-transform: rotate(180deg);">
</a>
</section>
</section>
</div>
</div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
<script>
// Full list of configuration options available at:
// https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
controls: false,
progress: true,
slideNumber: true,
history: true,
center: false,
transition: 'slide', // none/fade/slide/convex/concave/zoom
math: {
mathjax: 'https://cdn.mathjax.org/mathjax/latest/MathJax.js',
config: 'TeX-AMS_HTML-full' // See http://docs.mathjax.org/en/latest/config-files.html
},
// Optional reveal.js plugins
dependencies: [
{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
{ src: 'plugin/zoom-js/zoom.js', async: true },
{ src: 'plugin/notes/notes.js', async: true },
{ src: 'plugin/math/math.js', async: true }
]
});
</script>
<script src="//code.jquery.com/jquery-2.2.0.min.js"></script>
<script type="text/javascript">
var header = $('#header').html();
if ( window.location.search.match( /print-pdf/gi ) ) {
$('.slides > section').prepend(header);
} else {
$('.slides').prepend(header);
}
</script>
</body>
</html>
Here is a slightly more complicated answer that also works with the pdf-export print version:
Add the elements to the slide-background <div> (instead of section, slides, or reveal). This <div> is dynamically generated, so we must wait for the Reveal.js ready event. When printing there is a slight delay followed by unnecessary animation of the headers and footers moving into place, but all the headers/footers are rendered in the PDF as desired.
Pseudo-code:
Style header/footer <div> so they are positioned as desired.
Create hidden header/footer <div>
On Reveal.js ready event, copy header/footer <div> into each .slide-background <div>
Code: this can be copy-pasted into the end of a reveal.js file (right before the end </body> tag):
<style type="text/css">
/* 1. Style header/footer <div> so they are positioned as desired. */
#header-left {
position: absolute;
top: 0%;
left: 0%;
}
#header-right {
position: absolute;
top: 0%;
right: 0%;
}
#footer-left {
position: absolute;
bottom: 0%;
left: 0%;
}
</style>
<!-- 2. Create hidden header/footer <div> -->
<div id="hidden" style="display:none;">
<div id="header">
<div id="header-left">HEADER-LEFT</div>
<div id="header-right">HEADER-RIGHT</div>
<div id="footer-left">FOOTER-LEFT</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript">
// 3. On Reveal.js ready event, copy header/footer <div> into each `.slide-background` <div>
var header = $('#header').html();
if ( window.location.search.match( /print-pdf/gi ) ) {
Reveal.addEventListener( 'ready', function( event ) {
$('.slide-background').append(header);
});
}
else {
$('div.reveal').append(header);
}
</script>
Insert the header/footer elements into the div.reveal element instead of the .slides slides element.
The position within the DOM tree you where insert the header/footer elements affects which CSS is applied, which in turn affects their positioning.
$('.slides').prepend(header) adds the elements inside the slides <div>. The elements will be fixed to the default (960x700) window because that is how the slides <div> is sized.
$('div.reveal').append(header) adds the elements inside the reveal <div>. The elements will be fixed to the screen because the reveal <div> is sized to take up the entire browser view port.
Note this does not work for the print/pdf version... I'm still trying to figure that one out...

Allowing Chart.js to work with jQuery Tabs

On my page I have jQuery creating tabs, and I have Chart.js creating a line chart. They both work fine, except I cannot make Chart.js show the line chart inside a jQuery tab. I don't understand what it is about jQuery tabs that could be preventing the chart to display.
The only error I get from Chrome is "Uncaught TypeError: Cannot call method 'getContext' of null" referring to line 64.
How do I go about making this work?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!--[if lt IE 9]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<title></title>
<meta name="keywords" content="" />
<meta name="description" content="" />
<link href="css/style.css" rel="stylesheet">
<!--Chart.js stuff-->
<script src="js/Chart.js"></script>
<meta name = "viewport" content = "initial-scale = 1, user-scalable = no">
<style>
canvas{
}
</style>
<!--jQuery/jQuery UI files-->
<link href="css/smoothness/jquery-ui-1.10.3.custom.css" rel="stylesheet">
<script src="js/jquery-1.9.1.js"></script>
<script src="js/jquery-ui-1.10.3.custom.js"></script>
<!--To enable jQuery elements-->
<script>
$(function()
{
$( "#tabs" ).tabs();
});
</script>
</head>
<body>
<script>
var lineChartData = {
labels : ["January","February","March","April","May","June","July"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
pointColor : "rgba(220,220,220,1)",
pointStrokeColor : "#fff",
data : [65,59,90,81,56,55,40]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : [28,48,40,19,96,27,100]
}
]
}
var myLine = new Chart(document.getElementById("canvas").getContext("2d")).Line(lineChartData);
</script>
<div class="wrapper">
<div class="middle">
<div class="container">
<main class="content">
<div id="tabs">
<ul>
<li>Tab 1</li>
<li>Tab 2</li>
</ul>
<div id="tabs-1">
<!--Trying to display the chart here is not working-->
<canvas id="canvas" height="450" width="600"></canvas>
</div>
<div id="tabs-2">
<p></p>
</div>
</div>
</main><!-- .content -->
</div><!-- .container-->
</div><!-- .middle-->
</div><!-- .wrapper -->
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name = "viewport" content = "initial-scale = 1, user-scalable = no">
<title>Untitled Document</title>
<style>
canvas{
}
/*** tabs ****/
.etabs { margin: 0;
padding-left:20%; }
.etabs li
{display:inline-block;
width:auto;
padding:0 3% 2% 3%;
text-align:center;
}
.tab { display: inline-block;
zoom:1;
display:inline;
background:url(../images/li_border.fw.png) no-repeat right;
height:23px;
}
.tab a { font-size: 20px;
line-height: 2em;
display: block;
outline: none;
color:#D80000;
font-size:20px;
text-decoration:none;
}
.tab a:hover { text-decoration: none; }
.tab.active { color:#D80000;
position: relative;
border-color: #666; }
.tab a.active {
color:#0085B2; }
.tab-container .panel-container { background: #fff;
border: solid #666 1px;
padding: 10px;
-moz-border-radius: 0 4px 4px 4px;
-webkit-border-radius: 0 4px 4px 4px;
}
/*** tabs ****/
</style>
</head>
<body>
<div id="tab-container" class="tab-container">
<ul class='etabs'>
<li class='tab'>Chart</li>
<li class='tab'>Bar chart</li>
</ul>
<div id="history" class="heig">
<h1>bar chart</h1>
<canvas id="canvas" height="450" width="600"></canvas>
</div>
<div id="business" class="heig">
<h1>pie chart</h1>
<canvas id="canvaspie" height="450" width="450"></canvas>
</div>
</div>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="jquery.easytabs.js"></script>
<script src="Chart.js"></script>
<script>
$(document).ready(function(){ $('#tab-container').easytabs(); });
</script>
<script>
var barChartData = {
labels : ["Pass","Fail"],
datasets : [
{
fillColor : "rgba(220,220,220,0.5)",
strokeColor : "rgba(220,220,220,1)",
data : [65,0]
},
{
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
data : [0,47]
}
]
}
var myLine=new Chart(document.getElementById("canvas").getContext("2d")).Bar(barChartData);
</script>
<script>
var pieData = [
{
value: 30,
color:"#F38630"
},
{
value : 50,
color : "#E0E4CC"
},
{
value : 100,
color : "#69D2E7"
}
];
var myPie = new Chart(document.getElementById("canvaspie").getContext("2d")).Pie(pieData);
</script>
</body>
</html>
I just posted an answer in a different related question in ChartJS charts not generating within tabs with example code and jsfiddle. I'm not using jquery.tabs but I was having the same problem with tabs I made myself. I realized the issue is that with display:none chartjs doesn't know the size of the div to render the chart. The ^ fiddle makes use of two fixes actually: using jquery.hide()/show() instead and temporarily hiding the area with a cover while they render (which I found was necessary in large pages).
The trick is to hide each tab as soon as you render the chart. Again, using tabs I made myself but this should fix your issue too if you're willing to adjust how you show/hide tabs.
The business (full code on the jsfiddle)
var ctx = document.getElementById('chart1').getContext('2d');
var chart1 = new Chart(ctx).Bar(data1);
$('#tab1').hide();
var ctx = document.getElementById('chart2').getContext('2d');
var chart2 = new Chart(ctx).Line(data2);
$('#tab2').hide();
$('#tab1_btn').on('click',function(){
$('#tab1').show();
$('#tab2').hide()
})
$('#tab2_btn').on('click',function(){
$('#tab1').hide();
$('#tab2').show()
})
This works for me. The trick is generate the chart when the tab activated.
var chartIsShow = false;
$(function() {
$( "#Tabs1" ).tabs({
activate: function(event, ui) {
if(chartIsShow === false) {
var ctx = document.getElementById("chart").getContext("2d");
window.myLine = new Chart(ctx).Line(chart_data,{ animation : false, responsive : true });
chartIsShow = true;
}
}
});
});
download customized jquery-ui.js file and check minimum things (only tabs) and uncheck all other at http://jqueryui.com/download/ and include this js file instead of yours on this page

How to make the extjs accordion layout example dynamic?

I've pulled out the accordion layout .html and .js files from the extjs examples (below).
What is the next step to make this dynamic e.g. how the syntax of a link looks so that the HTML that fills a section under a panel on the left has links which fill the content on the right.
Does anyone know of tutorials which go beyond this shell and show how to make it dynamic, i.e. integrate it in a working application?
<html>
<head>
<title>Accordion Layout</title>
<link rel="stylesheet" type="text/css" href="resources/css/ext-all.css"/>
<!-- GC -->
<!-- LIBS -->
<script type="text/javascript" src="adapter/ext/ext-base.js"></script>
<!-- ENDLIBS -->
<script type="text/javascript" src="ext-all.js"></script>
<style type="text/css">
html, body {
font: normal 12px verdana;
margin: 0;
padding: 0;
border: 0 none;
overflow: hidden;
height: 100%;
}
.empty .x-panel-body {
padding-top:20px;
text-align:center;
font-style:italic;
color: gray;
font-size:11px;
}
</style>
<script type="text/javascript">
Ext.onReady(function() {
var item1 = new Ext.Panel({
title: 'Start',
html: '<this is the start content>',
cls:'empty'
});
var item2 = new Ext.Panel({
title: 'Application',
html: '<empty panel>',
cls:'empty'
});
var item3 = new Ext.Panel({
title: 'Module',
html: '<empty panel>',
cls:'empty'
});
var accordion = new Ext.Panel({
region:'west',
margins:'5 0 5 5',
split:true,
width: 210,
layout:'accordion',
items: [item1, item2, item3]
});
var viewport = new Ext.Viewport({
layout:'border',
items:[
accordion, {
region:'center',
margins:'5 5 5 0',
cls:'empty',
bodyStyle:'background:#f1f1f1',
html:'This is where the content goes for each selection.'
}]
});
});
</script>
</head>
<body>
<script type="text/javascript" src="../shared/examples.js"></script><!-- EXAMPLES -->
</body>
</html>
There's a billion ways to do it. The question is vague... but here's a very simplistic one. Just have an Ajax function that calls the server and adds the panels dynamically.
Say your server provides the following JSON, by calling /links.json
{links: ['http://www.google.com'], ['http://www.yahoo.com']}
You would do the following
Ext.onReady(function() {
var accordion = new Ext.Panel({
region:'west',
margins:'5 0 5 5',
split:true,
width: 210,
layout:'accordion'
});
new Ext.Viewport({
layout:'border',
items:[
accordion,
{region:'center', html:'This is where the content goes for each selection.'}]
});
Ext.Ajax.request({
url: '/links.json',
callback: function(response) {
var json = Ext.decode(response);
var cfgs = [];
for (var i = 0; i < json.links.length; i++) {
cfgs.push({
html: json.links[i]
})
}
accordion.add(cfgs);
}
});
});
But there's nothing that I coded here that you didn't already know, is there?
Here's a very good source of information that will probably help you get forward:
Saki's Ext Examples Page.

Categories