Chart.js - generateLegend() call results in "undefined is not a function" - chart.js

When I attempt to call generateLegened() on my chart:
var ctx = $("#chart").get(0).getContext("2d");
var ctxOptions = {
responsive: false,
legendTemplate: "<ul>LEGEND</ul>"
};
var chart = new Chart(ctx);
chart.Line(data, ctxOptions);
var legend = chart.generateLegend();
it errors with:
Uncaught TypeError: undefined is not a function
on the chart.GenerateLegend() line.
I'm completely confused as to what the problem it. The function is clearly in the .js file being included.
I'm using this script: //cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.1/Chart.min.js
Is this a bug, or can someone tell me what I'm doing wrong?
Thanks

Interestingly, if I change the code as follows:
var chart = new Chart(ctx).Line(data, ctxOptions);
the legend works as expected!?
A bug with chart.js?

Try
legendTemplate: function(data) { return "<ul>LEGEND</ul>"; }
instead. Seems like some bug in the chart.js.

Related

How do you create an extension to Chart.js?

I have created a new chart type:
Chart.types.Line.extend({
name: "LineWithRectangle",
draw: function () {
Chart.types.Line.prototype.draw.apply(this, arguments);
var startPoint = this.datasets[0].points[this.options.startIndex]
var endPoint = this.datasets[0].points[this.options.endIndex]
var scale = this.scale
this.chart.ctx.fillStyle = "#808080";
ctx.globalAlpha = 0.2;
this.chart.ctx.fillRect(startPoint.x,
scale.startPoint,
endPoint.x - startPoint.x,
scale.endPoint - scale.startPoint);
ctx.stroke();
ctx.globalAlpha = 1;
this.chart.ctx.textAlign = 'center';
this.chart.ctx.fillText("EVENT DAY",
startPoint.x + (endPoint.x - startPoint.x) / 2,
scale.startPoint + 20);
}
});
I placed this code in another file and referenced in the page :
<script src="~/lib/charts-js/Chart.js" type="text/javascript"></script>
<script src="~/lib/charts-js/ChartExtensions.js" type="text/javascript"></script>
But when I try to use it I'm not getting a chart object in the debugger:
new Chart(ctx.children[0].getContext("2d")).LineWithRectangle(data, { pointHitDetectionRadius: 0.05, animation: false, startIndex: start, endIndex: end })
Chrome is not reporting a ChartType object like it does for built in chart types but says "not available".
What am I doing wrong here?
Your code expects different values for ctx in the main code vs. your extension. In your main code it seems like a DOM node and in your extension you are using it as a context.
Just add
var ctx = this.chart.ctx;
after Chart.types.Line.prototype.draw.apply(this, arguments); and it should work. If not, check if your main code variables are all defined with correct values (start, end and ctx)

Chart.js Legend not showing

I'm trying to get my piechart to display its legend however I can't seem to get it right.
I've post my codes here:
var legend = mydoughnutChart.generateLegend();
$('#doughnutChart').append(legend);
http://jsfiddle.net/mark5ahm/3k2be814/
Fixed it with a latest update in jsfiddle.
var doughnutOptions = {
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
}
http://jsfiddle.net/mark5ahm/3k2be814/5/

Famo.us - How to add content to a CanvasSurface

I've just moved to Famo.us and think it has some amazing potential. I am trying to build a new App using Famo.us and will be having 'layered' Views, one of which has a CanvasSurface inside.
My question is about how I would populate the CanvasSurface? I have checked the Docs and while they talk about some of the parameter options they do not tell you how.
I have a View within which I add a Layout and then a Surface to that Layout. Other Views that have ImageSurfaces work fine - but I do not know if I am on the right track with CanvasSurface.
So far I have: (part of inside a BackgroundView.js file)
function BackgroundView() {
View.apply(this, arguments);
_createLayout.call(this);
_createBody.call(this);
_setListeners.call(this);
}
function _createBody() {
this.bodySurface = new CanvasSurface({
canvasSize : [undefined, undefined]
});
var bodyContext= this.bodySurface.getContext('2d');
bodyContext.fillText("Text on Canvas", 100, 100);
this.layout.content.add(this.bodySurface);
}
It runs with no errors, but shows nothing. The CanvasSurface is rendered...
Are there any examples using CanvasSurface or does anyone have any thoughts?
Thanks again for your help in advance.
:)
There are a couple of things I added to your code.. Defining the prototype and prototype.constructor, as well as adding the CanvasSurface to the BackgroundView. I found that canvasSize does not currently support the undefined size attribute like Surface does. You need to be explicit and use pixel size.
Check out what I did to your code.. Hope this helps..
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var View = require('famous/core/View');
var CanvasSurface = require('famous/surfaces/CanvasSurface');
var context = Engine.createContext();
function BackgroundView() {
View.apply(this, arguments);
// _createLayout.call(this);
_createBody.call(this);
// _setListeners.call(this);
}
BackgroundView.prototype = Object.create(View.prototype);
BackgroundView.prototype.constructor = BackgroundView;
function _createBody() {
this.bodySurface = new CanvasSurface({
size:[400,200]
});
var bodyContext= this.bodySurface.getContext('2d');
bodyContext.font="20px Georgia";
bodyContext.fillText("Hello World!",50,50);
this.add(this.bodySurface);
}
var bg = new BackgroundView();
context.add(bg);

Get reference to paper via dom element

Is there a way to get the paper for an element by referencing the element?
I'm creating elements in a loop and with each element i'm creating a new Raphael(...). See sample below.
Basically I want to stop the animation on click, but paper is undefined and calling stop() on the element itself doesn't work either.
$.each(el,function(key,value)
{
var li = $("<li>",{id:"item"+key).appendTo("#myUl");
var ppr = new Raphael($("item"+key),get(0),48,48);
//... do stuff like animate ...
li.click(function()
{
console.log($(this).paper); //undefined
})
})
I was wondering about a closure like below to capture the paper, so when the anonymous func runs, it has the variable captured.
Note, I'm not sure this is the best method overall, something feels a bit clunky about creating a new paper each time, but just trying to address the specific issue.
Untested code, but if you can get it on a fiddle, I think it should be possible to sort.
$.each(el,function(key,value)
{
var li = $("<li>",{id:"item"+key).appendTo("#myUl");
var ppr = new Raphael($("item"+key),get(0),48,48);
(function() {
var myPaper = ppr;
li.click(function()
{
console.log(myPaper);
})
})();
})
You can also attach the paper to the element's "data" using https://api.jquery.com/data/
$.each(el,function(key,value)
{
var li = $("<li>",{id:"item"+key).appendTo("#myUl");
var ppr = new Raphael($("item"+key),get(0),48,48);
li.data("paper", ppr ); // SAVE
li.click(function()
{
console.log($(this).data("paper")); // LOAD
})
})

how can i show/hide a raphael object with button click event

i want to show/hide my raphael svg graph with a button click event
please someone who know how to do this. please help me
i try to do by this way but it's not working.
var p = Raphael(900,70,200,200);
p.circle(20,20,20);
$n("#shide").click(function(){
p.hide();
});
please someone who know how to do this. please help me.
Thanks in advance.
You'd better use the return value of drawing functions.
var element1 = p.circle(20,20,20);
var element2 = p.circle(99,99,20);
$n("#shide").click(function(){
element1.hide();
// element2.hide();
});
Also I have some advanced skills about this kind of problem. These skills will be very usefull when you draw your circles or other things with the ajax response data.
function drawCircle() {
var elementObj = {};
$.ajax({url: '', dataType: 'json', method: 'post', data: yourData, success: function (data) {
elementObj['circle1'] = p.circle(20,20,20);
elementObj['circle2'] = p.circle(99,99,20);
});
return elementObj;
}
Then you call this function like this:
var ele = drawCircle();
var hoverInCb = function () {
ele['circle1'] && ele['circle1'].show();
ele['circle2'] && ele['circle2'].show();
};
var hoverOutCb = function () {
ele['circle1'] && ele['circle1'].hide();
ele['circle2'] && ele['circle2'].hide();
};
These code will work because that the returned elementObj is a 'link' of the object. After the data fetched by ajax request, the elementObj will be filled with data, and the ele variable outside there will also get the new data.
Like this:
var paper = Raphael(10, 50, 320, 200);
paper.circle(10, 10, 10, 10)
.attr({fill: "#000"})
.click(function () {
this.hide();
});