@dhis2/analytics 27.0.1 → 28.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/__demo__/ScatterPlotPdfExport.stories.js +46 -0
- package/build/cjs/__demo__/SingleValue.stories.js +34 -2
- package/build/cjs/__fixtures__/scatterPlotData.js +863 -0
- package/build/cjs/components/FileMenu/__tests__/utils.spec.js +18 -91
- package/build/cjs/components/FileMenu/utils.js +5 -29
- package/build/cjs/locales/ar/translations.json +3 -1
- package/build/cjs/visualizations/config/adapters/dhis_highcharts/customSVGOptions/singleValue/getSingleValueBackgroundColor.js +2 -1
- package/build/cjs/visualizations/config/adapters/dhis_highcharts/events/loadCustomSVG/singleValue/addIconElement.js +2 -2
- package/build/cjs/visualizations/config/adapters/dhis_highcharts/events/loadCustomSVG/singleValue/index.js +13 -16
- package/build/cjs/visualizations/config/adapters/dhis_highcharts/events/loadCustomSVG/singleValue/positionElements.js +2 -5
- package/build/cjs/visualizations/config/adapters/dhis_highcharts/events/loadCustomSVG/singleValue/styles.js +13 -2
- package/build/cjs/visualizations/config/adapters/dhis_highcharts/exporting.js +33 -17
- package/build/cjs/visualizations/config/adapters/dhis_highcharts/index.js +1 -1
- package/build/cjs/visualizations/config/adapters/dhis_highcharts/title/index.js +2 -1
- package/build/cjs/visualizations/config/generators/highcharts/index.js +30 -16
- package/build/cjs/visualizations/util/colors/colorSets.js +1 -2
- package/build/es/__demo__/ScatterPlotPdfExport.stories.js +37 -0
- package/build/es/__demo__/SingleValue.stories.js +35 -3
- package/build/es/__fixtures__/scatterPlotData.js +857 -0
- package/build/es/components/FileMenu/__tests__/utils.spec.js +18 -91
- package/build/es/components/FileMenu/utils.js +6 -30
- package/build/es/locales/ar/translations.json +3 -1
- package/build/es/visualizations/config/adapters/dhis_highcharts/customSVGOptions/singleValue/getSingleValueBackgroundColor.js +2 -1
- package/build/es/visualizations/config/adapters/dhis_highcharts/events/loadCustomSVG/singleValue/addIconElement.js +2 -2
- package/build/es/visualizations/config/adapters/dhis_highcharts/events/loadCustomSVG/singleValue/index.js +13 -16
- package/build/es/visualizations/config/adapters/dhis_highcharts/events/loadCustomSVG/singleValue/positionElements.js +2 -5
- package/build/es/visualizations/config/adapters/dhis_highcharts/events/loadCustomSVG/singleValue/styles.js +13 -2
- package/build/es/visualizations/config/adapters/dhis_highcharts/exporting.js +33 -17
- package/build/es/visualizations/config/adapters/dhis_highcharts/index.js +1 -1
- package/build/es/visualizations/config/adapters/dhis_highcharts/title/index.js +2 -1
- package/build/es/visualizations/config/generators/highcharts/index.js +30 -16
- package/build/es/visualizations/util/colors/colorSets.js +1 -2
- package/package.json +4 -3
|
@@ -89,92 +89,37 @@ describe('utils', () => {
|
|
|
89
89
|
});
|
|
90
90
|
});
|
|
91
91
|
describe('preparePayloadForSave', () => {
|
|
92
|
-
|
|
93
|
-
query: jest.fn()
|
|
94
|
-
};
|
|
95
|
-
beforeEach(() => {
|
|
96
|
-
jest.clearAllMocks();
|
|
97
|
-
});
|
|
98
|
-
it('fetches subscribers and adds them to the visualization', async () => {
|
|
99
|
-
const visualization = {
|
|
100
|
-
id: '123',
|
|
101
|
-
type: 'BAR',
|
|
102
|
-
name: 'Existing Name',
|
|
103
|
-
description: 'Existing Description'
|
|
104
|
-
};
|
|
105
|
-
mockEngine.query.mockResolvedValue({
|
|
106
|
-
ao: {
|
|
107
|
-
subscribers: ['user1', 'user2']
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
const result = await (0, _utils.preparePayloadForSave)({
|
|
111
|
-
visualization,
|
|
112
|
-
engine: mockEngine
|
|
113
|
-
});
|
|
114
|
-
expect(mockEngine.query).toHaveBeenCalledWith({
|
|
115
|
-
ao: {
|
|
116
|
-
resource: 'visualizations',
|
|
117
|
-
id: expect.any(Function),
|
|
118
|
-
params: {
|
|
119
|
-
fields: 'subscribers'
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}, {
|
|
123
|
-
variables: {
|
|
124
|
-
id: '123'
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
expect(result.subscribers).toEqual(['user1', 'user2']);
|
|
128
|
-
});
|
|
129
|
-
it('sets the name to the provided name', async () => {
|
|
92
|
+
it('sets the name to the provided name', () => {
|
|
130
93
|
const visualization = {
|
|
131
94
|
id: '123',
|
|
132
95
|
type: 'MAP',
|
|
133
96
|
name: 'Existing name'
|
|
134
97
|
};
|
|
135
98
|
const name = 'New Name';
|
|
136
|
-
|
|
137
|
-
ao: {
|
|
138
|
-
subscribers: []
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
const result = await (0, _utils.preparePayloadForSave)({
|
|
99
|
+
const result = (0, _utils.preparePayloadForSave)({
|
|
142
100
|
visualization,
|
|
143
|
-
name
|
|
144
|
-
engine: mockEngine
|
|
101
|
+
name
|
|
145
102
|
});
|
|
146
103
|
expect(result.name).toBe(name);
|
|
147
104
|
});
|
|
148
|
-
it('sets the name to the existing name if no new name is provided',
|
|
105
|
+
it('sets the name to the existing name if no new name is provided', () => {
|
|
149
106
|
const visualization = {
|
|
150
107
|
id: '123',
|
|
151
108
|
type: 'LINE_LIST',
|
|
152
109
|
name: 'Existing Name'
|
|
153
110
|
};
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
subscribers: []
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
const result = await (0, _utils.preparePayloadForSave)({
|
|
160
|
-
visualization,
|
|
161
|
-
engine: mockEngine
|
|
111
|
+
const result = (0, _utils.preparePayloadForSave)({
|
|
112
|
+
visualization
|
|
162
113
|
});
|
|
163
114
|
expect(result.name).toBe('Existing Name');
|
|
164
115
|
});
|
|
165
|
-
it('sets the name to a default value if no name is provided',
|
|
116
|
+
it('sets the name to a default value if no name is provided', () => {
|
|
166
117
|
const visualization = {
|
|
167
118
|
id: '123',
|
|
168
119
|
type: 'BAR'
|
|
169
120
|
};
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
subscribers: []
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
const result = await (0, _utils.preparePayloadForSave)({
|
|
176
|
-
visualization,
|
|
177
|
-
engine: mockEngine
|
|
121
|
+
const result = (0, _utils.preparePayloadForSave)({
|
|
122
|
+
visualization
|
|
178
123
|
});
|
|
179
124
|
const expectedName = `Untitled Bar, ${new Date().toLocaleDateString(undefined, {
|
|
180
125
|
year: 'numeric',
|
|
@@ -183,55 +128,37 @@ describe('utils', () => {
|
|
|
183
128
|
})}`;
|
|
184
129
|
expect(result.name).toBe(expectedName);
|
|
185
130
|
});
|
|
186
|
-
it('sets the description to the provided description',
|
|
131
|
+
it('sets the description to the provided description', () => {
|
|
187
132
|
const visualization = {
|
|
188
133
|
id: '123',
|
|
189
134
|
type: 'YEAR_OVER_YEAR_LINE',
|
|
190
135
|
description: 'Existing Description'
|
|
191
136
|
};
|
|
192
137
|
const description = 'New Description';
|
|
193
|
-
|
|
194
|
-
ao: {
|
|
195
|
-
subscribers: []
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
|
-
const result = await (0, _utils.preparePayloadForSave)({
|
|
138
|
+
const result = (0, _utils.preparePayloadForSave)({
|
|
199
139
|
visualization,
|
|
200
|
-
description
|
|
201
|
-
engine: mockEngine
|
|
140
|
+
description
|
|
202
141
|
});
|
|
203
142
|
expect(result.description).toBe(description);
|
|
204
143
|
});
|
|
205
|
-
it('keeps the existing description if no new description is provided',
|
|
144
|
+
it('keeps the existing description if no new description is provided', () => {
|
|
206
145
|
const visualization = {
|
|
207
146
|
id: '123',
|
|
208
147
|
type: 'COLUMN',
|
|
209
148
|
description: 'Existing Description'
|
|
210
149
|
};
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
subscribers: []
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
const result = await (0, _utils.preparePayloadForSave)({
|
|
217
|
-
visualization,
|
|
218
|
-
engine: mockEngine
|
|
150
|
+
const result = (0, _utils.preparePayloadForSave)({
|
|
151
|
+
visualization
|
|
219
152
|
});
|
|
220
153
|
expect(result.description).toBe('Existing Description');
|
|
221
154
|
});
|
|
222
|
-
it('sets the description to undefined if no description is provided and none exists',
|
|
155
|
+
it('sets the description to undefined if no description is provided and none exists', () => {
|
|
223
156
|
const visualization = {
|
|
224
157
|
id: '123',
|
|
225
158
|
type: 'BAR'
|
|
226
159
|
};
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
subscribers: []
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
const result = await (0, _utils.preparePayloadForSave)({
|
|
233
|
-
visualization,
|
|
234
|
-
engine: mockEngine
|
|
160
|
+
const result = (0, _utils.preparePayloadForSave)({
|
|
161
|
+
visualization
|
|
235
162
|
});
|
|
236
163
|
expect(result.description).toBeUndefined();
|
|
237
164
|
});
|
|
@@ -65,38 +65,12 @@ const preparePayloadForSaveAs = _ref => {
|
|
|
65
65
|
return visualization;
|
|
66
66
|
};
|
|
67
67
|
exports.preparePayloadForSaveAs = preparePayloadForSaveAs;
|
|
68
|
-
const
|
|
69
|
-
ao: {
|
|
70
|
-
resource: (0, _visTypes.getApiEndpointByVisType)(type),
|
|
71
|
-
id: _ref2 => {
|
|
72
|
-
let {
|
|
73
|
-
id
|
|
74
|
-
} = _ref2;
|
|
75
|
-
return id;
|
|
76
|
-
},
|
|
77
|
-
params: {
|
|
78
|
-
fields: 'subscribers'
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
const apiFetchAOSubscribers = (dataEngine, id, type) => {
|
|
83
|
-
return dataEngine.query(getSubscriberQuery(type), {
|
|
84
|
-
variables: {
|
|
85
|
-
id
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
};
|
|
89
|
-
const preparePayloadForSave = async _ref3 => {
|
|
68
|
+
const preparePayloadForSave = _ref2 => {
|
|
90
69
|
let {
|
|
91
70
|
visualization,
|
|
92
71
|
name,
|
|
93
|
-
description
|
|
94
|
-
|
|
95
|
-
} = _ref3;
|
|
96
|
-
const {
|
|
97
|
-
ao
|
|
98
|
-
} = await apiFetchAOSubscribers(engine, visualization.id, visualization.type);
|
|
99
|
-
visualization.subscribers = ao.subscribers;
|
|
72
|
+
description
|
|
73
|
+
} = _ref2;
|
|
100
74
|
visualization.name = name || visualization.name || _d2I18n.default.t('Untitled {{visualizationType}}, {{date}}', {
|
|
101
75
|
visualizationType: (0, _visTypes.getDisplayNameByVisType)(visualization.type),
|
|
102
76
|
date: new Date().toLocaleDateString(undefined, {
|
|
@@ -106,6 +80,8 @@ const preparePayloadForSave = async _ref3 => {
|
|
|
106
80
|
})
|
|
107
81
|
});
|
|
108
82
|
visualization.description = description !== undefined ? description : visualization.description;
|
|
83
|
+
delete visualization.displayName;
|
|
84
|
+
delete visualization.displayDescription;
|
|
109
85
|
return visualization;
|
|
110
86
|
};
|
|
111
87
|
exports.preparePayloadForSave = preparePayloadForSave;
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"About this event chart": "",
|
|
27
27
|
"About this event report": "",
|
|
28
28
|
"This app could not retrieve required data.": "",
|
|
29
|
-
"Network error": "",
|
|
29
|
+
"Network error": "خطأ في الشبكة",
|
|
30
30
|
"Data / Edit calculation": "",
|
|
31
31
|
"Data / New calculation": "",
|
|
32
32
|
"Remove item": "",
|
|
@@ -166,6 +166,7 @@
|
|
|
166
166
|
"line list": "",
|
|
167
167
|
"map": "خريطة",
|
|
168
168
|
"visualization": "",
|
|
169
|
+
"Untitled {{visualizationType}}, {{date}}": "",
|
|
169
170
|
"Edit": "تعديل",
|
|
170
171
|
"Write a reply": "كتابة رد",
|
|
171
172
|
"Post reply": "",
|
|
@@ -471,6 +472,7 @@
|
|
|
471
472
|
"Single value": "قيمة مفردة",
|
|
472
473
|
"Outlier table": "",
|
|
473
474
|
"All charts": "",
|
|
475
|
+
"Map": "الخريطة",
|
|
474
476
|
"{{seriesName}} (trend)": "",
|
|
475
477
|
"Trend": "الاتجاه",
|
|
476
478
|
"No legend for this series": "لا معلومات مفاتيح إيضاحية لهذه السلسلة",
|
|
@@ -7,6 +7,7 @@ exports.getSingleValueBackgroundColor = getSingleValueBackgroundColor;
|
|
|
7
7
|
var _legends = require("../../../../../../modules/legends.js");
|
|
8
8
|
var _getSingleValueLegendColor = require("./getSingleValueLegendColor.js");
|
|
9
9
|
function getSingleValueBackgroundColor(legendOptions, legendSets, value) {
|
|
10
|
+
let defaultColor = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'transparent';
|
|
10
11
|
const legendColor = (0, _getSingleValueLegendColor.getSingleValueLegendColor)(legendOptions, legendSets, value);
|
|
11
|
-
return legendColor && legendOptions.style === _legends.LEGEND_DISPLAY_STYLE_FILL ? legendColor :
|
|
12
|
+
return legendColor && legendOptions.style === _legends.LEGEND_DISPLAY_STYLE_FILL ? legendColor : defaultColor;
|
|
12
13
|
}
|
|
@@ -11,8 +11,8 @@ function addIconElement(svgString, color) {
|
|
|
11
11
|
const iconElWidth = svgIconDocument.documentElement.getAttribute('width');
|
|
12
12
|
const iconGroup = this.renderer.g('icon').attr({
|
|
13
13
|
color,
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
fill: color,
|
|
15
|
+
'data-test': 'visualization-icon',
|
|
16
16
|
visibility: 'hidden'
|
|
17
17
|
});
|
|
18
18
|
|
|
@@ -10,19 +10,22 @@ var _getAvailableSpace = require("./getAvailableSpace.js");
|
|
|
10
10
|
var _positionElements = require("./positionElements.js");
|
|
11
11
|
var _styles = require("./styles.js");
|
|
12
12
|
function loadSingleValueSVG() {
|
|
13
|
+
var _this$userOptions;
|
|
13
14
|
const {
|
|
14
15
|
formattedValue,
|
|
15
16
|
icon,
|
|
16
17
|
subText,
|
|
17
18
|
fontColor
|
|
18
19
|
} = this.userOptions.customSVGOptions;
|
|
19
|
-
const dynamicStyles = new _styles.DynamicStyles();
|
|
20
|
-
const valueElement = this.renderer.text(formattedValue).attr(
|
|
21
|
-
|
|
20
|
+
const dynamicStyles = new _styles.DynamicStyles((_this$userOptions = this.userOptions) === null || _this$userOptions === void 0 ? void 0 : _this$userOptions.isPdfExport);
|
|
21
|
+
const valueElement = this.renderer.text(formattedValue).attr({
|
|
22
|
+
'data-test': 'visualization-primary-value',
|
|
23
|
+
fill: fontColor,
|
|
22
24
|
visibility: 'hidden'
|
|
23
25
|
}).add();
|
|
24
|
-
const subTextElement = subText ? this.renderer.text(subText).attr(
|
|
25
|
-
|
|
26
|
+
const subTextElement = subText ? this.renderer.text(subText).attr({
|
|
27
|
+
'data-test': 'visualization-subtext',
|
|
28
|
+
fill: fontColor,
|
|
26
29
|
visibility: 'hidden'
|
|
27
30
|
}).add() : null;
|
|
28
31
|
const iconElement = icon ? _addIconElement.addIconElement.call(this, icon, fontColor) : null;
|
|
@@ -30,18 +33,12 @@ function loadSingleValueSVG() {
|
|
|
30
33
|
let styles = {};
|
|
31
34
|
while (!fitsWithinContainer && dynamicStyles.hasNext()) {
|
|
32
35
|
styles = dynamicStyles.next();
|
|
33
|
-
valueElement.
|
|
34
|
-
subTextElement === null || subTextElement === void 0 ? void 0 : subTextElement.
|
|
36
|
+
valueElement.attr(styles.value);
|
|
37
|
+
subTextElement === null || subTextElement === void 0 ? void 0 : subTextElement.attr(styles.subText);
|
|
35
38
|
fitsWithinContainer = (0, _checkIfFitsWithinContainer.checkIfFitsWithinContainer)(_getAvailableSpace.getAvailableSpace.call(this, styles.spacing.valueTop), valueElement, subTextElement, icon, subText, styles.spacing);
|
|
36
39
|
}
|
|
37
40
|
_positionElements.positionElements.call(this, valueElement, subTextElement, iconElement, styles.spacing);
|
|
38
|
-
valueElement.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
iconElement === null || iconElement === void 0 ? void 0 : iconElement.css({
|
|
42
|
-
visibility: 'visible'
|
|
43
|
-
});
|
|
44
|
-
subTextElement === null || subTextElement === void 0 ? void 0 : subTextElement.css({
|
|
45
|
-
visibility: 'visible'
|
|
46
|
-
});
|
|
41
|
+
valueElement.attr('visibility', 'visible');
|
|
42
|
+
iconElement === null || iconElement === void 0 ? void 0 : iconElement.attr('visibility', 'visible');
|
|
43
|
+
subTextElement === null || subTextElement === void 0 ? void 0 : subTextElement.attr('visibility', 'visible');
|
|
47
44
|
}
|
|
@@ -28,11 +28,8 @@ function positionElements(valueElement, subTextElement, iconElement, spacing) {
|
|
|
28
28
|
const iconHeight = height * scale;
|
|
29
29
|
const valueElementHeight = valueElementBox.height * _constants.ACTUAL_NUMBER_HEIGHT_FACTOR;
|
|
30
30
|
const translateY = layoutRect.y + (valueElementHeight - iconHeight) / 2;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
* These path-coordinates only scale correctly when using CSS translate */
|
|
34
|
-
iconElement.css({
|
|
35
|
-
transform: `translate(${translateX}px, ${translateY}px) scale(${scale})`
|
|
31
|
+
iconElement.attr({
|
|
32
|
+
transform: `translate(${translateX} ${translateY}) scale(${scale})`
|
|
36
33
|
});
|
|
37
34
|
}
|
|
38
35
|
if (subTextElement) {
|
|
@@ -75,11 +75,12 @@ const spacings = [{
|
|
|
75
75
|
}];
|
|
76
76
|
const MIN_SIDE_WHITESPACE = exports.MIN_SIDE_WHITESPACE = 4;
|
|
77
77
|
class DynamicStyles {
|
|
78
|
-
constructor() {
|
|
78
|
+
constructor(isPdfExport) {
|
|
79
79
|
this.currentIndex = 0;
|
|
80
|
+
this.isPdfExport = isPdfExport;
|
|
80
81
|
}
|
|
81
82
|
getStyle() {
|
|
82
|
-
|
|
83
|
+
const style = {
|
|
83
84
|
value: {
|
|
84
85
|
...valueStyles[this.currentIndex],
|
|
85
86
|
'font-weight': '300'
|
|
@@ -87,6 +88,16 @@ class DynamicStyles {
|
|
|
87
88
|
subText: subTextStyles[this.currentIndex],
|
|
88
89
|
spacing: spacings[this.currentIndex]
|
|
89
90
|
};
|
|
91
|
+
if (this.isPdfExport) {
|
|
92
|
+
/* font-weight is not supported for offline PDF export and providing
|
|
93
|
+
* a specific value will cause the PDF to show a serif font instead */
|
|
94
|
+
style.value['font-weight'] = 'normal';
|
|
95
|
+
/* letter-spacing is also not supported and providing a specific
|
|
96
|
+
* value will cause misalignment issues in the PDF */
|
|
97
|
+
style.value['letter-spacing'] = 'normal';
|
|
98
|
+
style.subText['letter-spacing'] = 'normal';
|
|
99
|
+
}
|
|
100
|
+
return style;
|
|
90
101
|
}
|
|
91
102
|
next() {
|
|
92
103
|
if (this.currentIndex === valueStyles.length - 1) {
|
|
@@ -5,26 +5,42 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = getExporting;
|
|
7
7
|
var _visTypes = require("../../../../modules/visTypes.js");
|
|
8
|
+
var _getSingleValueBackgroundColor = require("./customSVGOptions/singleValue/getSingleValueBackgroundColor.js");
|
|
8
9
|
var _index = _interopRequireDefault(require("./events/loadCustomSVG/singleValue/index.js"));
|
|
9
10
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
11
|
+
const DEFAULT_EXPORT_BACKGROUND_COLOR = '#ffffff';
|
|
12
|
+
const BASE_EXPORTING_CONFIG = {
|
|
13
|
+
// disable exporting context menu
|
|
14
|
+
enabled: false,
|
|
15
|
+
// use offline exporting only
|
|
16
|
+
fallbackToExportServer: false,
|
|
17
|
+
allowHTML: true,
|
|
18
|
+
showExportInProgress: true,
|
|
19
|
+
applyStyleSheets: true,
|
|
20
|
+
sourceHeight: 768,
|
|
21
|
+
sourceWidth: 1024,
|
|
22
|
+
scale: 1,
|
|
23
|
+
chartOptions: {
|
|
24
|
+
chart: {
|
|
25
|
+
backgroundColor: DEFAULT_EXPORT_BACKGROUND_COLOR
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
function getExporting(layout, legendSets, series) {
|
|
30
|
+
if (layout.type === _visTypes.VIS_TYPE_SINGLE_VALUE) {
|
|
31
|
+
return {
|
|
32
|
+
...BASE_EXPORTING_CONFIG,
|
|
33
|
+
chartOptions: {
|
|
34
|
+
...BASE_EXPORTING_CONFIG.chartOptions,
|
|
35
|
+
chart: {
|
|
36
|
+
...BASE_EXPORTING_CONFIG.chartOptions.chart,
|
|
37
|
+
backgroundColor: (0, _getSingleValueBackgroundColor.getSingleValueBackgroundColor)(layout.legend, legendSets, series[0], DEFAULT_EXPORT_BACKGROUND_COLOR),
|
|
38
|
+
events: {
|
|
39
|
+
load: _index.default
|
|
24
40
|
}
|
|
25
41
|
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return exporting;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
29
44
|
}
|
|
45
|
+
return BASE_EXPORTING_CONFIG;
|
|
30
46
|
}
|
|
@@ -106,7 +106,7 @@ function _default(_ref) {
|
|
|
106
106
|
enabled: false
|
|
107
107
|
},
|
|
108
108
|
// exporting
|
|
109
|
-
exporting: (0, _exporting.default)(_layout.
|
|
109
|
+
exporting: (0, _exporting.default)(_layout, _extraOptions.legendSets, series),
|
|
110
110
|
/* The config object passed to the Highcharts Chart constructor
|
|
111
111
|
* can contain arbitrary properties, which are made accessible
|
|
112
112
|
* under the Chart instance's `userOptions` member. This means
|
|
@@ -44,7 +44,8 @@ function _default(layout, metaData, extraOptions, series) {
|
|
|
44
44
|
const legendOptions = layout.legend;
|
|
45
45
|
const fontStyle = (0, _fontStyle.mergeFontStyleWithDefault)(layout.fontStyle && layout.fontStyle[_fontStyle.FONT_STYLE_VISUALIZATION_TITLE], _fontStyle.FONT_STYLE_VISUALIZATION_TITLE);
|
|
46
46
|
const title = Object.assign({
|
|
47
|
-
text: undefined
|
|
47
|
+
text: undefined,
|
|
48
|
+
minScale: 1
|
|
48
49
|
}, dashboard ? DASHBOARD_TITLE_STYLE : {
|
|
49
50
|
margin: 30,
|
|
50
51
|
align: (0, _getTextAlignOption.getTextAlignOption)(fontStyle[_fontStyle.FONT_STYLE_OPTION_TEXT_ALIGN], _fontStyle.FONT_STYLE_VISUALIZATION_TITLE, (0, _visTypes.isVerticalType)(layout.type)),
|
|
@@ -5,24 +5,38 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = _default;
|
|
7
7
|
var _highcharts = _interopRequireDefault(require("highcharts"));
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
require("highcharts/highcharts-more");
|
|
9
|
+
require("highcharts/modules/boost");
|
|
10
|
+
require("highcharts/modules/exporting");
|
|
11
|
+
require("highcharts/modules/no-data-to-display");
|
|
12
|
+
require("highcharts/modules/offline-exporting");
|
|
13
|
+
require("highcharts/modules/pattern-fill");
|
|
14
|
+
require("highcharts/modules/solid-gauge");
|
|
14
15
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
(
|
|
20
|
-
(
|
|
21
|
-
(0, _boost.default)(_highcharts.default);
|
|
16
|
+
/* Whitelist some additional SVG attributes and tags here. Without this,
|
|
17
|
+
* the PDF export for the SingleValue visualization and charts in boost-mode
|
|
18
|
+
* breaks. For more info about the boost mode issue, see:
|
|
19
|
+
* https://github.com/highcharts/highcharts/issues/8333 */
|
|
20
|
+
_highcharts.default.AST.allowedTags.push('fedropshadow', 'image');
|
|
21
|
+
_highcharts.default.AST.allowedAttributes.push('transform-origin', 'preserveAspectRatio', 'fill-rule', 'clip-rule');
|
|
22
22
|
|
|
23
|
-
/*
|
|
24
|
-
*
|
|
25
|
-
|
|
23
|
+
/* This is a workaround for https://github.com/highcharts/highcharts/issues/22008
|
|
24
|
+
* We add some transparent text in a non-ASCII script to the chart to prevent
|
|
25
|
+
* the chart from being exported in a serif font */
|
|
26
|
+
_highcharts.default.addEvent(_highcharts.default.Chart, 'load', function () {
|
|
27
|
+
this.renderer.text('모', 20, 20).attr({
|
|
28
|
+
opacity: 0
|
|
29
|
+
}).add();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
/* Workaround for https://github.com/highcharts/highcharts/issues/23049
|
|
33
|
+
* (there happen to be 10 colors and 10 patterns)*/
|
|
34
|
+
const {
|
|
35
|
+
colors
|
|
36
|
+
} = _highcharts.default.getOptions();
|
|
37
|
+
_highcharts.default.patterns.forEach((pattern, i) => {
|
|
38
|
+
pattern.color = colors[i];
|
|
39
|
+
});
|
|
26
40
|
function drawLegendSymbolWrap() {
|
|
27
41
|
const pick = _highcharts.default.pick;
|
|
28
42
|
_highcharts.default.wrap(_highcharts.default.seriesTypes.column.prototype, 'drawLegendSymbol', function (proceed, legend, item) {
|
|
@@ -5,9 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.colorSets = exports.COLOR_SET_PATTERNS = exports.COLOR_SET_GRAY = exports.COLOR_SET_EXTENDED = exports.COLOR_SET_DEFAULT = exports.COLOR_SET_DARK = exports.COLOR_SET_COLOR_BLIND = exports.COLOR_SET_BRIGHT = exports.COLOR_SET_BASIC = void 0;
|
|
7
7
|
var _highcharts = _interopRequireDefault(require("highcharts"));
|
|
8
|
-
|
|
8
|
+
require("highcharts/modules/pattern-fill");
|
|
9
9
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
-
(0, _patternFill.default)(_highcharts.default);
|
|
11
10
|
const COLOR_SET_DEFAULT = exports.COLOR_SET_DEFAULT = 'DEFAULT';
|
|
12
11
|
const COLOR_SET_BASIC = exports.COLOR_SET_BASIC = 'BASIC';
|
|
13
12
|
const COLOR_SET_EXTENDED = exports.COLOR_SET_EXTENDED = 'EXTENDED';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { extraOptions, responses, visualization } from '../__fixtures__/scatterPlotData.js';
|
|
3
|
+
import { createVisualization } from '../index.js';
|
|
4
|
+
export default {
|
|
5
|
+
title: 'ScatterPlot'
|
|
6
|
+
};
|
|
7
|
+
export const Default = () => {
|
|
8
|
+
const ref = useRef(null);
|
|
9
|
+
const [chart, setChart] = useState(null);
|
|
10
|
+
const exportToPdf = useCallback(() => {
|
|
11
|
+
chart.update({
|
|
12
|
+
exporting: {
|
|
13
|
+
chartOptions: {
|
|
14
|
+
isPdfExport: true
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
chart.exportChartLocal({
|
|
19
|
+
filename: 'PDF export',
|
|
20
|
+
type: 'application/pdf'
|
|
21
|
+
});
|
|
22
|
+
}, [chart]);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const obj = createVisualization(responses, visualization, ref.current, extraOptions, undefined, undefined, 'highcharts');
|
|
25
|
+
setChart(obj.visualization);
|
|
26
|
+
}, []);
|
|
27
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, chart && /*#__PURE__*/React.createElement("button", {
|
|
28
|
+
onClick: exportToPdf
|
|
29
|
+
}, "Export PDF"), /*#__PURE__*/React.createElement("div", {
|
|
30
|
+
style: {
|
|
31
|
+
width: 800,
|
|
32
|
+
height: 800,
|
|
33
|
+
border: '2px solid magenta'
|
|
34
|
+
},
|
|
35
|
+
ref: ref
|
|
36
|
+
}));
|
|
37
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useMemo, useRef, useEffect } from 'react';
|
|
1
|
+
import React, { useState, useMemo, useRef, useEffect, useCallback } from 'react';
|
|
2
2
|
import { createVisualization } from '../index.js';
|
|
3
3
|
const constainerStyleBase = {
|
|
4
4
|
width: 800,
|
|
@@ -585,6 +585,7 @@ export const Default = () => {
|
|
|
585
585
|
const [dashboard, setDashboard] = useState(false);
|
|
586
586
|
const [showIcon, setShowIcon] = useState(true);
|
|
587
587
|
const [indicatorType, setIndicatorType] = useState('plain');
|
|
588
|
+
const [exportAsPdf, setExportAsPdf] = useState(true);
|
|
588
589
|
const [width, setWidth] = useState(constainerStyleBase.width);
|
|
589
590
|
const [height, setHeight] = useState(constainerStyleBase.height);
|
|
590
591
|
const containerStyle = useMemo(() => ({
|
|
@@ -592,6 +593,31 @@ export const Default = () => {
|
|
|
592
593
|
width,
|
|
593
594
|
height
|
|
594
595
|
}), [width, height]);
|
|
596
|
+
const downloadOffline = useCallback(() => {
|
|
597
|
+
if (newChartRef.current) {
|
|
598
|
+
const currentBackgroundColor = newChartRef.current.userOptions.chart.backgroundColor;
|
|
599
|
+
newChartRef.current.update({
|
|
600
|
+
exporting: {
|
|
601
|
+
chartOptions: {
|
|
602
|
+
isPdfExport: exportAsPdf
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
});
|
|
606
|
+
newChartRef.current.exportChartLocal({
|
|
607
|
+
sourceHeight: 768,
|
|
608
|
+
sourceWidth: 1024,
|
|
609
|
+
scale: 1,
|
|
610
|
+
fallbackToExportServer: false,
|
|
611
|
+
filename: 'testOfflineDownload',
|
|
612
|
+
showExportInProgress: true,
|
|
613
|
+
type: exportAsPdf ? 'application/pdf' : 'image/png'
|
|
614
|
+
}, {
|
|
615
|
+
chart: {
|
|
616
|
+
backgroundColor: currentBackgroundColor === 'transparent' ? '#ffffff' : currentBackgroundColor
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}, [exportAsPdf]);
|
|
595
621
|
useEffect(() => {
|
|
596
622
|
if (newContainerRef.current) {
|
|
597
623
|
requestAnimationFrame(() => {
|
|
@@ -652,13 +678,19 @@ export const Default = () => {
|
|
|
652
678
|
checked: showIcon,
|
|
653
679
|
onChange: () => setShowIcon(!showIcon),
|
|
654
680
|
type: "checkbox"
|
|
655
|
-
}), "\xA0Show icon"), /*#__PURE__*/React.createElement("label", null, "Indicator type
|
|
681
|
+
}), "\xA0Show icon"), /*#__PURE__*/React.createElement("label", null, "Indicator type", ' ', /*#__PURE__*/React.createElement("select", {
|
|
656
682
|
onChange: event => setIndicatorType(event.target.value)
|
|
657
683
|
}, indicatorTypes.map((type, index) => {
|
|
658
684
|
return /*#__PURE__*/React.createElement("option", {
|
|
659
685
|
key: index
|
|
660
686
|
}, type);
|
|
661
|
-
})))
|
|
687
|
+
}))), /*#__PURE__*/React.createElement("label", null, /*#__PURE__*/React.createElement("input", {
|
|
688
|
+
checked: exportAsPdf,
|
|
689
|
+
onChange: () => setExportAsPdf(!exportAsPdf),
|
|
690
|
+
type: "checkbox"
|
|
691
|
+
}), ' ', "Export as PDF"), /*#__PURE__*/React.createElement("button", {
|
|
692
|
+
onClick: downloadOffline
|
|
693
|
+
}, "Download offline")), /*#__PURE__*/React.createElement("div", {
|
|
662
694
|
style: {
|
|
663
695
|
display: 'flex',
|
|
664
696
|
gap: 12
|