Previously, I used React + AntDesign to implement a simple timing chart, but later I had more complex requirements and required the display of 2,000 tasks at the same time, which involved performance issues. I first used React + antd+ts to implement it. A demo that basically meets the following needs, but react's rendering mechanism has caused major performance problems. Using Chrome's own Performance, the test found that the first rendering of demo is as high as 10 seconds, and subsequent operations will also make the entire page very stuck. After thinking about it, I decided to use original soundtrack js+css+html to implement it, because the performance under original soundtrack js is the best. Let’s talk about the requirements of the new version:
The task is displayed in a tree structure on the left, foldable
The right side shows the length of time the task takes to run
Need to use lines to link the relationship between tasks
You can zoom on the right to view detailed task status
When zooming, the graphics remain in a certain proportion to both ends with the mouse as the center. The text description inside is not affected when zooming.
When scaling the graph, it means that the time taken for the task and the coordinates need to change accordingly accordingly according to the proportion of image enlargement.
When the mouse moves on the timing chart, a line appears to prompt the current time and information.
Implementation difficulties
Mouse zoom, x-axis zoom
Mouse zoom generates the scaling of the X-axis of the timing chart. Scaling of timing charts provides three ideas here:
Do data interception, intercept the data before and after according to a certain algorithm, and then re-render the entire page
Use css3's scaleX to scale the dom of the timing chart
The actual change of the width of the timing chart dom, the length of the task running, the length of the connecting lines, and the expected time required for the task running are all displayed in percentages.
Advantages and disadvantages of three ideas:
Advantages: There is no need to operate the dom's css attributes, and it is more convenient to re-render it between them. Disadvantages: For using dom redraw, it consumes severe performance and is very slow when rendering with a large number of tasks.
Advantages: Just change the dom's css, load quickly and process more. Disadvantages: Computing is troublesome. Friends who have used scaleX will find that when I zoom in on the X-axis, the vertical connection line will become wider, and the font will be stretched horizontally, and all need to be reversely reduced.
Advantages: Fast loading and very smooth. Calculate the percentage of the width of the element at one time, and there is no need to calculate the subsequent operations. Disadvantages: There will be certain errors when using percentage calculations, and you will see them when you zoom in to a certain extent. (All the matter is considered, I am using the third type)
// Function that calculates the width percentage // endTime: end time of the task // startTime: start time of the task // maxTime: maximum value of all tasks // minTime: minimum value of all tasks start time // time: all Ascending order of task start time and end time // task_width: length of task, length of horizontal connection line, left value of vertical connection line const widthFun = function (endTime, startTime, maxTime, minTime) { const task_width = (((Number (endTime) - Number (startTime)) / ((maxTime || time[time.length - 1]) - (minTime || time[0])) * (body_width - tree_box_dom.offsetWidth)) / dom.offset Width)* 100; return task_width> 100 ? 100 : task_width; };
Mouse zoom, keep the mouse as the center, zoom in on both sides
Let’s put the inference process diagram first:
// Explanation of the above figure// dom = dom element of the timing chart// domL1, domeL2 = dom.scrollLeft;// domeL1 represents the previous dom.scrollLeft;// domeL2 represents the current dom.scrollLeft;// scale represents the current The scale of the magnification // scale1 represents the magnification of the last time // tree_dom.offsetWidth represents the width of the tree on the left // clientX1 represents the distance from the left side of the mouse position of the last time = e.clientX - tree_dom.offsetWidth// clientX2 represents the distance from the current mouse position to the timing chart // Scaling with the mouse as the center, the formula is: domL2 = domeL1(scale/scale1) + clientX1(scale/scale1) - e.clientX + tree_dom.offsetWidth// Formula explanation: // 1. scale/scale1 represents the scaling ratio of this time except for the scaling ratio of the previous one, indicating the current scaling ratio// The width of the left volume will also scale during the second scaling, so the width on the left needs to be Multiply by the scaling scale // The width on the left side of the mouse position distance from the timing chart will also be scaled when zooming, so you should also multiply by the scaling scale // The actual distance on the left side of the mouse position distance from the timing chart at the end is equal to the scaling The length of the left scroll // Page code time_box_parent.scrollLeft = (time_box_parent.scrollLeft + e.clientX - tree_box_dom.offsetWidth) * (scale_x / scale_x1) - e.clien tX + tree_box_dom.offsetWidth;
Use connections to represent relationships between tasks
plan:
When used, css3 + js + html5 is drawn with pseudo-elements.
Wrap right-angle pictures with dom and set their position and height.
Draw with labels
Pros and cons:
Advantages: No extra tags are added, which is beneficial for rendering. Disadvantages: The parent task generates multiple child tasks, and it is difficult to add pseudo-classes and set the height and width of the pseudo-classes.
Advantages: Convenient, just calculate the height of the child task from the parent task. Disadvantages: When there are too many tasks, there will be many pictures, which will greatly affect performance.
Advantages: The height and position of each element are individually controlled, with high controllability and feedback color can be added. Disadvantages: Added more elements, which have an impact on rendering (I am using the third type, which is a stupid method. A big guy with a better method can provide suggestions, thank you)
Implementation ideas:
Use a variable to record the hierarchy depth of each task. The hierarchy depth starts with the parent task of the current task, that is, the current task generated from which task is, and the subtasks of the same level perform the accumulated operation. Use the accumulated variables to obtain the height of the vertical line and the top value of the horizontal line in a certain proportion. The length of the horizontal line is determined by the creation time and start time of the task. (Use the width percentage function above)
Time unit: day, hour, minute, second
This is relatively simple, implementation idea:
Because the time 4 scale of this demo is a scale, determine whether the difference between the minimum time stamp and the maximum time stamp is divided by 4, whether there is still one day (60 * 60 * 24, converted to seconds), descending order from large to small Get the time unit.