chart.js on animation end callback - javascript

Does the library chart.js support any sort of callbacks on specific events? I'm mostly interested in 'on animation end' event, but would be nice to know any other events if they're supported.
If this is not an option, do you know any workarounds? I'm using jQuery and vue.js and I just need to show some additional text on the page (completely outside of the chart itself) when chart.js finishes the animation of the chart.

For Chart.Js 2.6.0
options: {
cutoutPercentage: 90,
animation: {
duration: 2000,
onProgress: function(animation) {
$progress.attr({
value: animation.animationObject.currentStep / animation.animationObject.numSteps,
});
},
onComplete: function(animation) {
alert('onAnimationComplete')
}
}
},
See this codepen https://codepen.io/shivabhusal/pen/XaZQaW

There is an onAnimationComplete option you can specify to run stuff once the animation completes. See this section of the documentation.
Example
var ctx = document.getElementById("chart").getContext("2d");
var myLine1 = new Chart(ctx).Line(lineChartData1, {
onAnimationComplete: function() {
alert('animation complete')
}
});
Fiddle - http://jsfiddle.net/4vo72rLd/

Related

Highcharts - Suppress points being dragged on drag event

I'm new to Highcharts - it seems you can only trigger drag events if the appropriate dragDrop events are defined and enabled on a series. E.g. https://api.highcharts.com/highcharts/plotOptions.series.dragDrop
How can I suppress the points actually being moved around in my chart? I have tried setting allowPointSelect: false and disabling both draggableX and draggableY but of course doing that don't fire any drag events. I have also tried event.preventDefault but no luck
What I'm basically looking for is to have a user drag over a range in a line/area chart from startX/Y to endX/Y and display the results to the user (which I can successfully get using mouseOver - a nice feature!)
For such a feature, you don't need to use draggable-points module. A simple custom solution with a crosshair and dynamically added/removed plot-lines will be enough. For example:
chart: {
animation: false,
events: {
load: function() {
const chart = this;
this.series[0].points.forEach(point => {
point.graphic.on('mousedown', function() {
chart.draggedPoint = point;
chart.xAxis[0].update({
plotLines: [{
width: 2,
color: 'grey',
dashStyle: 'ShortDash',
value: point.x
}]
});
});
});
document.body.addEventListener('mouseup', function() {
chart.draggedPoint = null;
chart.xAxis[0].update({
plotLines: []
});
});
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/rsuj93at/
API Reference: https://api.highcharts.com/highcharts/tooltip.formatter

Trying to randomize a news ticker interval in jQuery

I have a jQuery-based scrolling news ticker that uses a set interval in milliseconds to control the delay between the reveal of each new section of text. I'd like to randomize the delay so that it more closely mimics the way a realtime news feed would look.
I've tried experimenting with some Math.random javascript where the newsTickerInterval parameter is, but JS is not my native language and I'm having trouble making it work.
Here's the jQuery function my scroller uses to config the display:
$(function () {
$(".demo2").bootstrapNews({
newsPerPage: 4,
autoplay: true,
pauseOnHover: true,
navigation: false,
direction: 'down',
newsTickerInterval: 3000,
onToDo: function () {
//console.log(this);
}
});
});
Any hints or suggestions would be greatly appreciated!
Instead of using newsTickerInterval, make a function getNewsTickerDelay that generates a random delay interval and call it using a setTimeout whenever needed.
$(function () {
$(".demo2").bootstrapNews({
newsPerPage: 4,
autoplay: true,
pauseOnHover: true,
navigation: false,
direction: 'down',
getNewsTickerDelay: function() {
var minimumInterval = 2000;
var maximumInterval = 5000;
var additionalInterval = Math.floor(
Math.random() * (maximumInterval - minimumInterval)
);
return minimumInterval + additionalInterval;
},
onToDo: function () {
//console.log(this);
}
});
});
So, every time your timeout is called, set another one with a random delay using getNewsTickerDelay
--EDIT--
As pointed out by #Barmar, you might need to tweak the implementation of the plugin in your case and implement its internal animate method to use your defined random interval instead of a fixed value. You'll just need to replace the self.options.newsTickerInterval in that plugin's JS to self.options.getNewsTickerDelay(). That is if you are willing to mutate the plugin's implementation.

Phaser scrolling background

My goal is to make a sprite bigger than the screen and have the user scroll to see the different parts of it, so I wanted to ask if Phaser had any sprite eventListener-functions such as:
var canvas = window.document.getElementsByTagName('canvas')[0],
prevX = 0, prevY = 0, mouseDown = false;
where canvas can be used as
canvas.addEventListener('mousedown',function(e){
});
canvas.addEventListener('mousemove',function(e){
});
Here is how I did it.
In your update function:
if (this.game.input.activePointer.isDown) {
if (this.game.origDragPoint) {
// move the camera by the amount the mouse has moved since last update
this.game.camera.x += this.game.origDragPoint.x - this.game.input.activePointer.position.x;
this.game.camera.y += this.game.origDragPoint.y - this.game.input.activePointer.position.y;
}
// set new drag origin to current position
this.game.origDragPoint = this.game.input.activePointer.position.clone();
}
else {
this.game.origDragPoint = null;
}
If using the camera is OK for you, you can try this Phaser 2 plugin: https://jdnichollsc.github.io/Phaser-Kinetic-Scrolling-Plugin/
With this plugin you can enable vertical and horizontal scroll to simulate scrolling into the canvas element used by Phaser, also you can customize the movement before to initialize the plugin, example:
var game = new Phaser.Game(400, 400, Phaser.AUTO, '', {
init: function () {
//Load the plugin
this.game.kineticScrolling = this.game.plugins.add(Phaser.Plugin.KineticScrolling);
},
create: function () {
//Configure the plugin
this.game.kineticScrolling.configure({
kineticMovement: true,
timeConstantScroll: 325, //really mimic iOS
horizontalScroll: true,
verticalScroll: false,
horizontalWheel: true,
verticalWheel: false,
deltaWheel: 40
});
//Starts the plugin
this.game.kineticScrolling.start();
//Changing the world size
this.game.world.setBounds(0, 0, 800, 800);
},
stopScrolling: function () {
//Stop the plugin
this.game.kineticScrolling.stop();
}
});
Also there's a fork for Phaser 3, check the repo from GitHub.
Regards, Nicholls

Phaser loading screen animation

So I am working on a simple android app using Phaser. But I was looking if it is possible to create a loading screen that uses a spritesheet animation or programmatically do an animation other than just a simple crop how phaser does it?
this.preloadBar = this.add.sprite(50, 170, 'preloaderBar');
this.load.setPreloadSprite(this.preloadBar);
Thanks in advance :)
In order to achieve that, i have a boot state where i initialise various game related utilities and the sprite i want to have during the loading screen. Then i just load the preloader state where everything else is being loaded and i just put the previous sprite on the screen. When everything finishes, main game, or menu state starts.
Here is an example:
Test.Boot.prototype = {
init: function () {
//general game config like scaleManager
},
preload: function () {
this.game.stage.backgroundColor = '#000000';
// the sprite you want to show during loading
this.game.load.atlasJSONHash('logo', 'asset/images/hand.png', 'asset/images/hand.json');
},
create: function () {
this.state.start('Preloader');
}
};
// Preloader.js
Test.Preloader.prototype = {
preload: function() {
//add the animation
this.logo = this.add.sprite(this.world.width/2, this.world.height/2, 'logo');
this.logo.anchor.set(0.5, 0.5);
this.logo.animations.add('shake',[8,9,10,11,12,13,14,15,16,17,17,8,9,8]);
this.logo.animations.play('shake', 60, true);
//load all the other assets
this.game.load.image("hero", "asset/images/hero.png");
this.game.load.image("clouds", "asset/images/sky3.jpg");
//this.game.load.image("rope", "asset/images/rope.png");
this.game.load.atlasJSONHash('items', 'asset/images/items.png', 'asset/images/items.json');
this.game.load.physics('physicsData', 'asset/images/polygon.json');
},
create: function() {
this.game.stage.backgroundColor = '#1589FF';
//A simple fade out effect
this.game.time.events.add(Phaser.Timer.SECOND * 2.0, function() {
var tween = this.add.tween(this.logo)
.to({alpha: 0}, 750, Phaser.Easing.Linear.none);
tween.onComplete.add(function() {
this.logo.destroy();
this.startGame();
}, this);
tween.start();
}, this);
},
startGame: function() {
this.state.start('MainMenu');
},
};
There is a video tutorial with similar technique here if you want to know more.

How to add zoom in zoom out buttons in visjs using angularjs?

Need help in having a zoom in and zoom out button in visjs network graph using angularjs, I could not find any relevant options for this. Please help, I am also providing a plunker link as an example
Code
<vis-network data="data" options="options" height="100%"></vis-network>
$scope.options = {
autoResize: true,
height: '800',
width: '100%'
};
Take a look at the interaction, navigationButtons option. It has built in controls for zoom, pan and reset view.
You need to change your vis options to include navigationButtons: true and keyboard: true to have keboard shortcuts enabled
$scope.options = {
autoResize: true,
height: '600',
width: '100%',
interaction: {
navigationButtons: true,
keyboard: true
}
};
Check this plunker
I've never worked with plunker, so I can not integrated my solution into your example, but I've created a JSFiddle for it which is based on a simple network example from the visjs.org website.
Unfortunately there is no setScale(scale) method available right now, but you could extend the network until someone implements it.
var network;
var zoomstep = 0.3;
function zoomin() {
network.setScale(network.getScale() - zoomstep);
}
function zoomout() {
network.setScale(network.getScale() + zoomstep);
}
vis.Network.prototype.setScale = function (scale) {
var options = {
nodes: []
};
var range = this.view._getRange(options.nodes);
var center = this.view._findCenter(range);
var animationOptions = {
position: center,
scale: scale,
animation: options.animation
};
this.view.moveTo(animationOptions);
};
The vis.Network.setScale code was taken from the Network.js and View.js source code, based on what getScale() did. I had to redo some things which the methods View.fit, View._getRange and View._findCenter did but it's working good so far.
Updated solution for vis.js 4.21.0
vis.Network.prototype.zoom = function (scale) {
const animationOptions = {
scale: this.getScale() + scale,
animation: { duration: 300 }
};
this.view.moveTo(animationOptions);
};
Click handler code:
this.network.zoom(-0.5) // or 0.5 to zoom in

Categories

Resources