• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

naver / billboard.js / 27122665529

08 Jun 2026 07:32AM UTC coverage: 92.54% (-1.1%) from 93.621%
27122665529

push

github

web-flow
feat(canvas): add canvas rendering mode

Add canvas entry, renderer engine, axis renderer, theme probing, and hit detection.
Support canvas flow, subchart, zoom, selection, grid/regions, export, tooltip, and focus.
Add tests, benchmarks, types, and docs for canvas mode limitations.

10455 of 11840 branches covered (88.3%)

Branch coverage included in aggregate %.

5094 of 5363 new or added lines in 68 files covered. (94.98%)

19 existing lines in 3 files now uncovered.

13349 of 13883 relevant lines covered (96.15%)

26556.19 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.92
/src/ChartInternal/internals/transform.ts
1
/**
2
 * Copyright (c) 2017 ~ present NAVER Corp.
3
 * billboard.js project is licensed under the MIT license
4
 */
5
import {$ARC, $AXIS} from "../../config/classes";
6
import {asHalfPixel} from "../../module/util";
7

8
type TranslateParam = "main" | "context" | "legend" | "x" | "y" | "y2" | "subX" | "arc" | "radar"
9
        | "polar";
10

11
export default {
12
        getTranslate(target: TranslateParam, index = 0): string {
137,304✔
13
                const $$ = this;
137,424✔
14
                const {config, state} = $$;
137,424✔
15
                const isRotated = config.axis_rotated;
137,424✔
16
                let padding = 0;
137,424✔
17
                let x;
18
                let y;
19

20
                if (index && /^(x|y2?)$/.test(target)) {
137,424✔
21
                        padding = $$.getAxisSize(target) * index;
120✔
22
                }
23

24
                if (target === "main") {
137,424✔
25
                        x = asHalfPixel(state.margin.left);
24,714✔
26
                        y = asHalfPixel(state.margin.top);
24,714✔
27
                } else if (target === "context") {
112,710✔
28
                        x = asHalfPixel(state.margin2.left);
855✔
29
                        y = asHalfPixel(state.margin2.top);
855✔
30
                } else if (target === "legend") {
111,855✔
31
                        x = state.margin3.left;
24,102✔
32
                        y = state.margin3.top;
24,102✔
33
                } else if (target === "x") {
87,753✔
34
                        x = isRotated ? -padding : 0;
23,952✔
35
                        y = isRotated ? 0 : state.height + padding;
23,952✔
36
                } else if (target === "y") {
63,801✔
37
                        x = isRotated ? 0 : -padding;
23,982✔
38
                        y = isRotated ? state.height + padding : 0;
23,982✔
39
                } else if (target === "y2") {
39,819✔
40
                        x = isRotated ? 0 : state.width + padding;
19,488✔
41
                        y = isRotated ? -padding - 1 : 0;
19,488✔
42
                } else if (target === "subX") {
20,331✔
43
                        x = 0;
855✔
44
                        y = isRotated ? 0 : state.height2;
855✔
45
                } else if (target === "arc") {
19,476✔
46
                        x = state.arcWidth / 2;
19,365✔
47
                        y = state.arcHeight / 2;
19,365✔
48

49
                        if (config.arc_rangeText_values?.length) {
19,365✔
50
                                y += 5 + ($$.hasType("gauge") && config.title_text ? 10 : 0);
168✔
51
                        }
52
                } else if (target === "polar") {
111!
53
                        x = state.arcWidth / 2;
×
54
                        y = state.arcHeight / 2;
×
55
                } else if (target === "radar") {
111!
56
                        const [width, height] = $$.getRadarSize();
111✔
57

58
                        x = state.width / 2 - width;
111✔
59
                        y = state.height / 2 - height;
111✔
60
                }
61

62
                return `translate(${x}, ${y})`;
137,424✔
63
        },
64

65
        transformMain(withTransition: boolean, transitions): void {
66
                const $$ = this;
18,675✔
67
                const {$el: {main}, $T} = $$;
18,675✔
68

69
                const xAxis = transitions?.axisX ?
18,675✔
70
                        transitions.axisX :
71
                        $T(main.select(`.${$AXIS.axisX}`), withTransition);
72

73
                const yAxis = transitions?.axisY ?
18,675✔
74
                        transitions.axisY :
75
                        $T(main.select(`.${$AXIS.axisY}`), withTransition);
76

77
                const y2Axis = transitions?.axisY2 ?
18,675✔
78
                        transitions.axisY2 :
79
                        $T(main.select(`.${$AXIS.axisY2}`), withTransition);
80

81
                $T(main, withTransition)
18,675✔
82
                        .attr("transform", $$.getTranslate("main"));
83

84
                xAxis.attr("transform", $$.getTranslate("x"));
18,675✔
85
                yAxis.attr("transform", $$.getTranslate("y"));
18,675✔
86
                y2Axis.attr("transform", $$.getTranslate("y2"));
18,675✔
87

88
                main.select(`.${$ARC.chartArcs}`)
18,675✔
89
                        .attr("transform", $$.getTranslate("arc"));
90
        },
91

92
        transformAll(withTransition: boolean, transitions): void {
93
                const $$ = this;
19,206✔
94
                const {config, state: {hasAxis, hasFunnel, hasTreemap, isCanvasMode}, $el} = $$;
19,206✔
95

96
                if (isCanvasMode) {
19,206!
NEW
97
                        return;
×
98
                }
99

100
                !hasFunnel && !hasTreemap && $$.transformMain(withTransition, transitions);
19,206✔
101

102
                hasAxis && config.subchart_show &&
19,206✔
103
                        $$.transformContext(withTransition, transitions);
104

105
                $el.legend && $$.transformLegend(withTransition);
19,206✔
106
        }
107
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc