Original from Zhihu:
zhuanlan.zhihu.com/p/32740553
Introduction, why do you want to study Chartjs
After we studied SVG.js and Frappe Charts, we have already had a preliminary understanding of SVG’s chart library, but we should put more effort into understanding and learning canvas of the visual world.
When chartitist. Js talks about his strengths and mentions that some chart libraries use the wrong technical canvas, it becomes more interesting to understand why this is so. Let’s take a look at Chartjs first.
Chartjs introduction
Chartjs is a simple and flexible chart library. Comparatively speaking, Chartjs has the advantages of simple configuration and elegant animation in chart library. The feature based on Canvas gives Chartjs more advantages in performance. Chartjs currently has a 34.4K star, which is almost synonymous with the Canvas version of charts and the most popular Canvas based chart library. A search of chart on GitHub shows that Chartjs ranks second only to D3 in popularity.
Let’s see how Chartjs works first.
<canvas id="myChart"></canvas> Copy the code
var ctx = document.getElementById('myChart').getContext("2d");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["JAN"."FEB"."MAR"."APR"."MAY"."JUN"."JUL"],
datasets: [{
label: "Data",
borderColor: "#80b6f4",
fill: false,
data: [50, 120, 150, 170, 180, 170, 160]
}]
}
});Copy the code
You get a trend diagram of the figure
Chart.js code organization
Chart.js Chart creation process
From the core.controller.js analysis of the source file, we can see the Chartjs initialization diagram process as follows:
On the left are events that trigger the plug-in mechanism.
Chartjs plugin mechanism
Chartjs’s plug-in mechanism may seem simple, but it works. The plugin is registered directly with the Plugin, has full execution lifecycle, has direct access to Chart global variables, and has access to all APIS.
Chart.plugins.register({
beforeInit() {}
afterInit() {}
afterUpdate() {}
afterLayout() {}
afterDatasetsUpdate() {}
afterDatasetUpdate() {}
afterRender() {}
afterDraw() {}
afterDatasetsDraw() {}
afterDatasetDraw() {}
afterEvent() {}
resize() {}
destroy() {}});Copy the code
Chartjs mouse events and animations
Dealing with mouse time has always been a hassle for Canvas charts. Let’s see what Chartjs does. It can be seen from the handleEvent of the core.controller.js file in the source file that Chartjs listens for the corresponding mouse event at the root element position, and then finds the nearest corresponding element through the previously recorded element position and responds to the corresponding event.
if (e.type === 'mouseout') {
me.active = [];
} else{ me.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions); }... me.updateHoverStyle(me.active, hoverOptions.mode,true);Copy the code
As can be seen from the code, Chartjs by getElementsAtEventForMode method to obtain the corresponding elements. Chartjs provides six modes to respond to interactions. Let’s take a look at these six patterns.
-
Point: Finds the corresponding element where the mouse position intersects
-
Nearest: Find the corresponding nearest element
-
Index: Finds data corresponding to index in different data sets based on location
-
Dataset: Finds elements that are only in the same dataset by location
-
X: Find the element that intersects the X-axis value based on the X-axis value of the mouse position, which is suitable for the vertical cursor scenario
-
Y: Locate the element that intersects the Y-axis value based on the Y-axis value of the mouse position, applicable to the vertical cursor scenario
For animation, the stack of animation is implemented in core.animation.js file, and the animation is called in turn using requestAnimationFrame. Animation is also built into the common various easing functions for common animation effects. We can look at the core implementation of the animation, the Advance method.
while (i < animations.length) {
animation = animations[i];
chart = animation.chart;
animation.currentStep = (animation.currentStep || 0) + count;
animation.currentStep = Math.min(animation.currentStep, animation.numSteps);
helpers.callback(animation.render, [chart, animation], chart);
helpers.callback(animation.onAnimationProgress, [animation], chart);
if (animation.currentStep >= animation.numSteps) {
helpers.callback(animation.onAnimationComplete, [animation], chart);
chart.animating = false;
animations.splice(i, 1);
} else{ ++i; }}Copy the code
In the above code, animation.render draws the intermediate states of the elements involved in the animation according to the progress of the current animation in the animation.
Chartjs floating point problem
In the process of reading the Chartjs source code, I found that the source code does not deal with floating point problems, and many places do not consider floating point problems. Therefore, Chartjs may have the following problems during its use:
One more thing
In the next installment, we’ll take a look at the visual graphics syntax G2 and see how G2 achieves a high degree of ease-of-use and extensibility for diagrams.
While looking at the Chartjs source code, we also experimented with some basic diagrams on canvas (see Taco).
If you want to work with us on visualization, please send your resume to [email protected]