Copyright notice: This article is the blogger’s original article, shall not be reproduced without the permission of the blogger. Please contact the author by leaving a comment at the bottom of the article.
The background,
In the actual development process, the UI design draft may be found to be quite different from the official sample diagram in order to make the graphics look good. As I’ve seen, with a bar chart as a background, each bar corresponds to the data of each point on the line chart and is displayed. As shown below, we will explain how to achieve it.
Second, graphic implementation
First of all, since I developed on the mobile side, I used the library ANTV/F2 for development. Because F2 is a visualization solution for mobile terminals, it is very convenient.
1. Install
npm install @antv/f2 --save
Copy the code
2. The introduction of
import F2 from '@antv/f2';
Copy the code
After F2 introduced the page, we were ready to create a chart.
3. Create charts
Create a
<canvas id="chart" style={{ width: "90%".height: "200px"}} / >Copy the code
1) Create a Chart object and specify the Chart ID, width, height, margin and other information
In my demo, I only set pixelRatio below, and other attributes can be set according to your own needs, please refer to Chart
const lineChart = new F2.Chart({
id: `chart`.// Specify the id of the canvas
// pixelRatio pixelRatio of the screen canvas
// Since the canvas will be blurred on the HD screen, 'pixelRatio' needs to be set. In general, the Settings are as follows
pixelRatio: window.devicePixelRatio
});
Copy the code
2) Data source processing
Because of the particularity of the graph, the data source needs special processing before use. Let’s look at the data source format we’re going to use:
const resData = [
{
date: "02.01".// Date: February 1st
number: 0./ / value
isDisplay: false // mark whether the point is displayed
},
{
date: "02.02".number: 119.isDisplay: true}... ]Copy the code
First we need to find the maximum value from the data source. If the returned data is empty, we need to set a default maximum value, 20 in this case, and override the value we found if the maximum value exists.
import { maxBy } from "lodash"; ./ / array
let newDataArr = [];
let maxDataItem = maxBy(resData, (o) = > o.number); // Find the maximum value
let maximum = 20; // Default maximum value
if (maxDataItem && maxDataItem.number) {
maximum = maxDataItem.number; // If the maximum value exists, take the maximum value
}
Copy the code
After this preparation, you must wonder what the maximum is used for.
Because when the data is returned blank, we only display the bar graph with gray background by default. The default maximum value is actually used to fill the gray background data, and the effect is shown below.
If the returned data exists, we need to modify the data and fill the grey histogram data with backupNumber:
// Return data is not null
if (resData.length) {
resData.map((item) = > {
// Add gray background data to each data source, where 10 is added to make the bar graph a little farther than the maximum point of the line graphnewDataArr.push({ ... item,backupNumber: maximum + 10 });
});
}
Copy the code
If the data is empty, newDataArr is an empty array. To display a gray bar background as the default, populate the data manually. The default display is 14 columns.
// Data is empty using grey data fields
if(! newDataArr.length) {for (let i = 0; i < 14; i++) {
newDataArr.push({
date: i,
isDisplay: false.backupNumber: maximum + 10}); }}Copy the code
The above data processing, the following for some special date display effect to do a processing:
We use the array xAxisTicks to record the x-coordinate display points, which will be used later when loading the data source.
-
The dates of the first and last days are shown on the diagram
- When the data source exists, the first day (
[resData[0].date]
) and the last day (resData[arrLength - 1].date
) into the arrayxAxisTicks
.
- When the data source exists, the first day (
-
Dates are displayed for points where isDisplay is true and marked on the line chart
- To the data source
map
Traverse, index each data homeindex
Field, useful for the next step - And then filter it out
isDisplay
为true
Is obtaineddisplayDotArr
.
- To the data source
-
If multiple consecutive dates need to be displayed, only the last consecutive date is displayed
- To implement a
getDisplayDotSort
Method that returns only the most pointy date after processing consecutive dates
- To implement a
The concrete implementation is as follows:
// Implement it
let arrLength; // Array length
let xAxisTicks = []; // the abscissa displays the point
// The data source exists
if (resData.length) {
// Record the data source length
arrLength = resData.length;
// Date of the first day
xAxisTicks = [resData[0].date];
// Find the array of points to display
let displayDotArr = resData
.map((item, i) = > ({ ...item, index: i }))
.filter((d) = > d.isDisplay);
// The date array of the points to display
getDisplayDotSort(displayDotArr).forEach((d) = > {
xAxisTicks.push(d.date);
});
// The date of last day
xAxisTicks.push(resData[arrLength - 1].date);
}
Copy the code
getDisplayDotSort
export const getDisplayDotSort = (array) = > {
let res = [];
// Iterate over the date array to display
array.forEach((item, i) = > {
// Set a temporary variable that can fetch the last 1 bit of the array
let temp = res[res.length - 1] | | [];Temp temp temp temp temp temp temp temp temp temp temp temp temp temp temp temp temp temp temp
if (item.index - temp[temp.length - 1].index === 1 ) {
// All contiguous data are placed in an array
temp.push(item);
}
// The other cases are placed in the array res
else {
[] is used to store each consecutive point as a group of data in an array, separated from non-adjacent points, and finally form a 2-dimensional arrayres.push([item]); }});// Cut consecutive points into arrays and return the last point of each array
return res.map((v) = > v[v.length - 1]);
};
Copy the code
Last processedres
It’s a two-dimensional array, and you can see thatres[2]
It’s a set of adjacent dates, and for adjacent dates, we just take the last date.
Processed data source:
const newDataArr = [
{
date: "02.01".// Date: February 1st
number: 0./ / value
backupNumber: 432.// Maximum gray background
isDisplay: false // mark whether the point is displayed
},
{
date: "02.02".number: 119.isDisplay: true.backupNumber: 432}... ]Copy the code
The x-coordinate data of xAxisTicks after processing is as follows:
const xAxisTicks = ["02.01"."02.03"."02.07"."02.15"."02.18"]
Copy the code
So we’re done with the point we want to display on the x-coordinate.
3) Load the data source
For data Settings, refer to scale
// newDataArr processed data
lineChart.source(newDataArr, {
// Configure each attribute
number: {
tickCount: 5.// The number of scale points on the coordinate axis. Different metric types correspond to different default values.
min: 0 // Specify the minimum value manually
},
date: {
type: "cat".// category, [' male ',' female '];
range: [0.1].// The range of output data, the default value of numeric type is [0, 1],
tickCount: 3.// Define the number of scale lines on the axis
ticks: xAxisTicks // Specifies the text information used to specify the scale points on the coordinate axis. Here is the beginning, end and last point of continuous points}});Copy the code
4) Chart other configurations
Refer to the documentation for axis and Tooltip
lineChart.tooltip(false); // Hide the configuration information
lineChart.axis("number".false); // Close the Y axis corresponding to number. Line chart to display values
lineChart.axis("backupNumber".false); // Close the Y-axis corresponding to backupNumber. Gray bar graph
lineChart.axis("date", {
label: (text, index, total) = > { // Set the bottom date x coordinate text
const config = {};
if (index === 0) {
config.textAlign = "left"; // The first one is displayed on the left
} else if (index === total - 1) {
config.textAlign = "right"; // The last one is displayed on the right
}
return config;
},
line: null.// The axis is hidden
labelOffset: 1 // Coordinate axis text distance axis distance
});
Copy the code
5) Create graphical syntax
Refer to document geometry notation and diagram types,
1. interval
Create a histogram background
The geometric tag interval creates the bar chart, position determines the x – and Y-axis data fields, and color gradient Settings.
Color is a linear gradient:
lineChart
.interval()
// Map the 'date' data value to the x coordinate point and the 'backupNumber' data value to the y coordinate point
.position("date*backupNumber")
.color("L (90) 0: rgba (245245245,0.18) 1: # eee");
Copy the code
The effect is as follows:
2. line
Create a line chart
The attributes used here are the same as above, style refer to here, and set fixed styles for all shapes. For specific Settings, see drawing properties
lineChart
.line()
.position("date*number")
.color("#096dd9")
.style({
lineWidth: 1 // Set the line thickness property
});
Copy the code
After superimposing the line chart, the effect is as follows:
3. point
Create some figure
The size attribute here is the way to map data values to the size of the graph
Note: Different graphics have different meanings of size:
- Size of the point graph affects the radius of the point.
- Size in line, area, and path affects the thickness of the line.
- The size of interval affects the width of the bar chart.
lineChart
.point()
.position("date*number")
.color("#096dd9")
.size("date*isDisplay".(date, isDisplay) = > {
if (isDisplay) return 3; // The size of the point to display
return 0; // Do not show the band you size is 0
})
.style({
// Set a fixed style for all shapes
lineWidth: 1.stroke: "#fff" // Draw the color of the graph
});
Copy the code
The effect is as follows:
4. area
Create area map
lineChart
.area()
.position("date*number")
.color("L (90) : 0 # 096 dd9 1: rgba (9109217, 4)");
Copy the code
After superimposed area diagram:
6) Render charts
Render the chart, called at the end, so our chart is drawn:
lineChart.render();
Copy the code
The final result is as shown:
Click to see the full demo code above
reference
- antv/f2
- F2 Basic line chart example