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

naver / billboard.js / 5829678459

pending completion
5829678459

push

github

web-flow
chore(build): Rename plugin packaged file name (#3335)

- Set plugin dist files name to contain 'pkgd' as postfix.
- Remove '@babel/plugin-transform-block-scoping' plugin wich transpiles incorrectly

Fix #3334

5739 of 6614 branches covered (86.77%)

Branch coverage included in aggregate %.

7566 of 7934 relevant lines covered (95.36%)

20583.74 hits per line

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

74.58
/src/Chart/api/flow.ts
1
/**
2
 * Copyright (c) 2017 ~ present NAVER Corp.
3
 * billboard.js project is licensed under the MIT license
4
 */
5
import {isDefined, isTabVisible, isValue, parseDate} from "../../module/util";
6

7
export default {
8
        /**
9
         * Flow data to the chart.<br><br>
10
         * By this API, you can append new data points to the chart.
11
         * @function flow
12
         * @instance
13
         * @memberof Chart
14
         * @param {object} args The object can consist with following members:<br>
15
         *
16
         *    | Key | Type | Description |
17
         *    | --- | --- | --- |
18
         *    | json | Object | Data as JSON format (@see [data․json](Options.html#.data%25E2%2580%25A4json)) |
19
         *    | rows | Array | Data in array as row format (@see [data․rows](Options.html#.data%25E2%2580%25A4json)) |
20
         *    | columns | Array | Data in array as column format (@see [data․columns](Options.html#.data%25E2%2580%25A4columns)) |
21
         *    | to | String | The lower x edge will move to that point. If not given, the lower x edge will move by the number of given data points |
22
         *    | length | Number | The lower x edge will move by the number of this argument |
23
         *    | duration | Number | The duration of the transition will be specified value. If not given, transition.duration will be used as default |
24
         *    | done | Function | The specified function will be called when flow ends |
25
         *
26
         * - **NOTE:**
27
         *   - If json, rows and columns given, the data will be loaded.
28
         *   - If data that has the same target id is given, the chart will be appended.
29
         *   - Otherwise, new target will be added. One of these is required when calling.
30
         *   - If json specified, keys is required as well as data.json.
31
         *          - If tab isn't visible(by evaluating `document.hidden`), will not be executed to prevent unnecessary work.
32
         * @example
33
         * // 2 data points will be apprended to the tail and popped from the head.
34
         * // After that, 4 data points will be appended and no data points will be poppoed.
35
         * chart.flow({
36
         *  columns: [
37
         *    ["x", "2018-01-11", "2018-01-21"],
38
         *    ["data1", 500, 200],
39
         *    ["data2", 100, 300],
40
         *    ["data3", 200, 120]
41
         *  ],
42
         *  to: "2013-01-11",
43
         *  done: function () {
44
         *    chart.flow({
45
         *      columns: [
46
         *        ["x", "2018-02-11", "2018-02-12", "2018-02-13", "2018-02-14"],
47
         *        ["data1", 200, 300, 100, 250],
48
         *        ["data2", 100, 90, 40, 120],
49
         *        ["data3", 100, 100, 300, 500]
50
         *      ],
51
         *      length: 2,
52
         *      duration: 1500
53
         *    });
54
         *  }
55
         * });
56
         */
57
        flow(args): void {
24✔
58
                const $$ = this.internal;
24✔
59
                let data;
60

61
                if (args.json || args.rows || args.columns) {
24!
62
                        $$.convertData(args, res => {
24✔
63
                                data = res;
24✔
64
                                _();
24✔
65
                        });
66
                }
67

68
                /**
69
                 * Process flows
70
                 * @private
71
                 */
72
                function _(): void {
24✔
73
                        let domain;
74
                        let length: number = 0;
24✔
75
                        let tail = 0;
24✔
76
                        let diff;
77
                        let to;
78

79
                        if ($$.state.redrawing || !data || !isTabVisible()) {
24✔
80
                                return;
3✔
81
                        }
82

83
                        const notfoundIds: string[] = [];
21✔
84
                        const orgDataCount = $$.getMaxDataCount();
21✔
85
                        const targets = $$.convertDataToTargets(data, true);
21✔
86
                        const isTimeSeries = $$.axis.isTimeSeries();
21✔
87

88
                        // Update/Add data
89
                        $$.data.targets.forEach(t => {
42✔
90
                                let found = false;
42✔
91

92
                                for (let i = 0; i < targets.length; i++) {
42✔
93
                                        if (t.id === targets[i].id) {
33!
94
                                                found = true;
33✔
95

96
                                                if (t.values[t.values.length - 1]) {
33!
97
                                                        tail = t.values[t.values.length - 1].index + 1;
33✔
98
                                                }
99

100
                                                length = targets[i].values.length;
33✔
101

102
                                                for (let j = 0; j < length; j++) {
33✔
103
                                                        targets[i].values[j].index = tail + j;
63✔
104

105
                                                        if (!isTimeSeries) {
63✔
106
                                                                targets[i].values[j].x = tail + j;
15✔
107
                                                        }
108
                                                }
109

110
                                                t.values = t.values.concat(targets[i].values);
33✔
111
                                                targets.splice(i, 1);
33✔
112
                                                break;
33✔
113
                                        }
114
                                }
115

116
                                !found && notfoundIds.push(t.id);
42✔
117
                        });
118

119
                        // Append null for not found targets
120
                        $$.data.targets.forEach(t => {
42✔
121
                                for (let i = 0; i < notfoundIds.length; i++) {
42✔
122
                                        if (t.id === notfoundIds[i]) {
24✔
123
                                                tail = t.values[t.values.length - 1].index + 1;
9✔
124

125
                                                for (let j = 0; j < length; j++) {
9✔
126
                                                        t.values.push({
15✔
127
                                                                id: t.id,
128
                                                                index: tail + j,
129
                                                                x: isTimeSeries ? $$.getOtherTargetX(tail + j) : tail + j,
15✔
130
                                                                value: null
131
                                                        });
132
                                                }
133
                                        }
134
                                }
135
                        });
136

137
                        // Generate null values for new target
138
                        if ($$.data.targets.length) {
21!
139
                                targets.forEach(t => {
21✔
140
                                        const missing: any[] = [];
3✔
141

142
                                        for (let i = $$.data.targets[0].values[0].index; i < tail; i++) {
3✔
143
                                                missing.push({
9✔
144
                                                        id: t.id,
145
                                                        index: i,
146
                                                        x: isTimeSeries ? $$.getOtherTargetX(i) : i,
9!
147
                                                        value: null
148
                                                });
149
                                        }
150

151
                                        t.values.forEach(v => {
6✔
152
                                                v.index += tail;
6✔
153

154
                                                if (!isTimeSeries) {
6!
155
                                                        v.x += tail;
×
156
                                                }
157
                                        });
158

159
                                        t.values = missing.concat(t.values);
3✔
160
                                });
161
                        }
162

163
                        $$.data.targets = $$.data.targets.concat(targets); // add remained
21✔
164

165
                        // check data count because behavior needs to change when it"s only one
166
                        // const dataCount = $$.getMaxDataCount();
167
                        const baseTarget = $$.data.targets[0];
21✔
168
                        const baseValue = baseTarget.values[0];
21✔
169

170
                        // Update length to flow if needed
171
                        if (isDefined(args.to)) {
21!
172
                                length = 0;
×
173
                                to = isTimeSeries ? parseDate.call($$, args.to) : args.to;
×
174

175
                                baseTarget.values.forEach(v => {
×
176
                                        v.x < to && length++;
×
177
                                });
178
                        } else if (isDefined(args.length)) {
21✔
179
                                length = args.length;
6✔
180
                        }
181

182
                        // If only one data, update the domain to flow from left edge of the chart
183
                        if (!orgDataCount) {
21!
184
                                if (isTimeSeries) {
×
185
                                        diff = baseTarget.values.length > 1 ?
×
186
                                                baseTarget.values[baseTarget.values.length - 1].x - baseValue.x :
×
187
                                                baseValue.x - $$.getXDomain($$.data.targets)[0];
188
                                } else {
189
                                        diff = 1;
×
190
                                }
191

192
                                domain = [baseValue.x - diff, baseValue.x];
×
193
                        } else if (orgDataCount === 1 && isTimeSeries) {
21!
194
                                diff = (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2;
×
195
                                domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)];
×
196
                        }
197

198
                        domain && $$.updateXDomain(null, true, true, false, domain);
21!
199

200
                        // Set targets
201
                        $$.updateTargets($$.data.targets);
21✔
202

203
                        // Redraw with new targets
204
                        $$.redraw({
21✔
205
                                flow: {
206
                                        index: baseValue.index,
207
                                        length: length,
208
                                        duration: isValue(args.duration) ? args.duration : $$.config.transition_duration,
21✔
209
                                        done: args.done,
210
                                        orgDataCount: orgDataCount,
211
                                },
212
                                withLegend: true,
213
                                withTransition: orgDataCount > 1,
214
                                withTrimXDomain: false,
215
                                withUpdateXAxis: true
216
                        });
217
                }
218
        }
219
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc