@gravity-ui/charts 1.3.0 → 1.4.0

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.
@@ -58,8 +58,9 @@ function getDefaultValueFormat({ axis }) {
58
58
  }
59
59
  export const DefaultContent = ({ hovered, xAxis, yAxis, valueFormat }) => {
60
60
  const measureValue = getMeasureValue({ data: hovered, xAxis, yAxis });
61
- return (React.createElement(React.Fragment, null,
62
- measureValue && React.createElement("div", null, measureValue),
61
+ return (React.createElement("div", { className: b('content') },
62
+ measureValue && React.createElement("div", { className: b('series-name') }, measureValue),
63
+ // eslint-disable-next-line complexity
63
64
  hovered.map((seriesItem, i) => {
64
65
  var _a;
65
66
  const { data, series, closest } = seriesItem;
@@ -79,9 +80,10 @@ export const DefaultContent = ({ hovered, xAxis, yAxis, valueFormat }) => {
79
80
  series.name,
80
81
  ": ",
81
82
  formattedValue));
82
- return (React.createElement("div", { key: id, className: b('content-row') },
83
+ const active = closest && hovered.length > 1;
84
+ return (React.createElement("div", { key: id, className: b('content-row', { active }) },
83
85
  React.createElement("div", { className: b('color'), style: { backgroundColor: color } }),
84
- React.createElement("div", null, closest ? React.createElement("b", null, value) : React.createElement("span", null, value))));
86
+ React.createElement("div", null, value)));
85
87
  }
86
88
  case 'waterfall': {
87
89
  const isTotal = get(data, 'total', false);
@@ -119,9 +121,10 @@ export const DefaultContent = ({ hovered, xAxis, yAxis, valueFormat }) => {
119
121
  series.name,
120
122
  ": ",
121
123
  formattedValue));
122
- return (React.createElement("div", { key: id, className: b('content-row') },
124
+ const active = closest && hovered.length > 1;
125
+ return (React.createElement("div", { key: id, className: b('content-row', { active }) },
123
126
  React.createElement("div", { className: b('color'), style: { backgroundColor: color } }),
124
- React.createElement("div", null, closest ? React.createElement("b", null, value) : React.createElement("span", null, value))));
127
+ React.createElement("div", null, value)));
125
128
  }
126
129
  case 'pie':
127
130
  case 'treemap': {
@@ -152,7 +155,8 @@ export const DefaultContent = ({ hovered, xAxis, yAxis, valueFormat }) => {
152
155
  React.createElement("span", null, "\u2192"),
153
156
  " ", target === null || target === void 0 ? void 0 :
154
157
  target.name,
155
- ": ",
158
+ ":",
159
+ ' ',
156
160
  formattedValue)));
157
161
  }
158
162
  case 'radar': {
@@ -167,9 +171,10 @@ export const DefaultContent = ({ hovered, xAxis, yAxis, valueFormat }) => {
167
171
  radarSeries.name || radarSeries.id,
168
172
  "\u00A0"),
169
173
  React.createElement("span", null, formattedValue)));
170
- return (React.createElement("div", { key: id, className: b('content-row') },
174
+ const active = closest && hovered.length > 1;
175
+ return (React.createElement("div", { key: id, className: b('content-row', { active }) },
171
176
  React.createElement("div", { className: b('color'), style: { backgroundColor: color } }),
172
- React.createElement("div", null, closest ? React.createElement("b", null, value) : React.createElement("span", null, value))));
177
+ React.createElement("div", null, value)));
173
178
  }
174
179
  default: {
175
180
  return null;
@@ -22,6 +22,6 @@ export const Tooltip = (props) => {
22
22
  window.dispatchEvent(new CustomEvent('scroll'));
23
23
  }, [left, top]);
24
24
  return (hovered === null || hovered === void 0 ? void 0 : hovered.length) ? (React.createElement(Popup, { anchorElement: anchor, className: b({ pinned: tooltipPinned }), disableTransition: true, floatingStyles: tooltipPinned ? undefined : { pointerEvents: 'none' }, offset: { mainAxis: 20 }, onOpenChange: tooltipPinned ? handleOnOpenChange : undefined, open: true, placement: ['right', 'left', 'top', 'bottom'] },
25
- React.createElement("div", { className: b('content') },
25
+ React.createElement("div", { className: b('popup-content') },
26
26
  React.createElement(ChartTooltipContent, { hovered: hovered, xAxis: xAxis, yAxis: yAxis, renderer: tooltip.renderer, valueFormat: tooltip.valueFormat })))) : null;
27
27
  };
@@ -1,15 +1,28 @@
1
1
  .gcharts-tooltip {
2
2
  box-shadow: 0 2px 12px var(--g-color-sfx-shadow);
3
3
  }
4
- .gcharts-tooltip__content {
5
- padding: 8px 14px;
4
+ .gcharts-tooltip__popup-content {
6
5
  text-wrap: nowrap;
7
6
  border-radius: 4px;
8
7
  background-color: var(--g-color-infographics-tooltip-bg);
9
8
  }
9
+ .gcharts-tooltip__content {
10
+ padding: var(--gcharts-tooltip-content-padding, 8px 0);
11
+ }
12
+ .gcharts-tooltip__series-name {
13
+ padding: 2px 14px 6px;
14
+ font-size: 13px;
15
+ font-weight: 600;
16
+ }
10
17
  .gcharts-tooltip__content-row {
11
18
  display: flex;
12
19
  align-items: center;
20
+ padding: 2px 14px;
21
+ font-size: 12px;
22
+ }
23
+ .gcharts-tooltip__content-row_active {
24
+ font-weight: 600;
25
+ background-color: var(--g-color-base-info-medium);
13
26
  }
14
27
  .gcharts-tooltip__color {
15
28
  display: inline-block;
@@ -21,7 +21,9 @@ export function preparePieData(args) {
21
21
  ? preparedSeries[0].states.hover.halo.size
22
22
  : 0;
23
23
  const maxRadius = Math.min(boundsWidth, boundsHeight) / 2 - haloSize;
24
+ const minRadius = maxRadius * 0.3;
24
25
  const groupedPieSeries = group(preparedSeries, (pieSeries) => pieSeries.stackId);
26
+ let maxMissingWidth = 0;
25
27
  const prepareItem = (stackId, items) => {
26
28
  var _a;
27
29
  const series = items[0];
@@ -173,12 +175,16 @@ export function preparePieData(args) {
173
175
  if (dataLabels.allowOverlap || !overlap) {
174
176
  const left = getLeftPosition(label);
175
177
  if (Math.abs(left) > boundsWidth / 2) {
176
- label.maxWidth = label.size.width - (Math.abs(left) - boundsWidth / 2);
178
+ const overflow = Math.abs(left) - boundsWidth / 2;
179
+ label.maxWidth = label.size.width - overflow;
180
+ maxMissingWidth = Math.max(maxMissingWidth, overflow);
177
181
  }
178
182
  else {
179
183
  const right = left + label.size.width;
180
184
  if (right > boundsWidth / 2) {
181
- label.maxWidth = label.size.width - (right - boundsWidth / 2);
185
+ const overflow = right - boundsWidth / 2;
186
+ label.maxWidth = label.size.width - overflow;
187
+ maxMissingWidth = Math.max(maxMissingWidth, overflow);
182
188
  }
183
189
  }
184
190
  if (shouldUseHtml) {
@@ -237,6 +243,18 @@ export function preparePieData(args) {
237
243
  data.labels = labels;
238
244
  data.htmlLabels = htmlLabels;
239
245
  data.connectors = connectors;
246
+ if (maxMissingWidth > 0) {
247
+ const { dataLabels } = items[0];
248
+ if (dataLabels.enabled) {
249
+ data.segments.forEach((s) => {
250
+ s.data.radius = Math.max(minRadius, s.data.radius - maxMissingWidth);
251
+ });
252
+ const finalLabels = prepareLabels({ data, series: items });
253
+ data.labels = finalLabels.labels;
254
+ data.htmlLabels = finalLabels.htmlLabels;
255
+ data.connectors = finalLabels.connectors;
256
+ }
257
+ }
240
258
  return data;
241
259
  });
242
260
  }
@@ -60,7 +60,7 @@ function renderLabels(selection, { labels, style = {}, attrs = {}, }) {
60
60
  .append('tspan')
61
61
  .attr('x', 0)
62
62
  .attr('dy', 0)
63
- .text((d) => d);
63
+ .html((d) => d);
64
64
  return text;
65
65
  }
66
66
  export function getLabelsSize({ labels, style, rotation, html, }) {
@@ -58,8 +58,9 @@ function getDefaultValueFormat({ axis }) {
58
58
  }
59
59
  export const DefaultContent = ({ hovered, xAxis, yAxis, valueFormat }) => {
60
60
  const measureValue = getMeasureValue({ data: hovered, xAxis, yAxis });
61
- return (React.createElement(React.Fragment, null,
62
- measureValue && React.createElement("div", null, measureValue),
61
+ return (React.createElement("div", { className: b('content') },
62
+ measureValue && React.createElement("div", { className: b('series-name') }, measureValue),
63
+ // eslint-disable-next-line complexity
63
64
  hovered.map((seriesItem, i) => {
64
65
  var _a;
65
66
  const { data, series, closest } = seriesItem;
@@ -79,9 +80,10 @@ export const DefaultContent = ({ hovered, xAxis, yAxis, valueFormat }) => {
79
80
  series.name,
80
81
  ": ",
81
82
  formattedValue));
82
- return (React.createElement("div", { key: id, className: b('content-row') },
83
+ const active = closest && hovered.length > 1;
84
+ return (React.createElement("div", { key: id, className: b('content-row', { active }) },
83
85
  React.createElement("div", { className: b('color'), style: { backgroundColor: color } }),
84
- React.createElement("div", null, closest ? React.createElement("b", null, value) : React.createElement("span", null, value))));
86
+ React.createElement("div", null, value)));
85
87
  }
86
88
  case 'waterfall': {
87
89
  const isTotal = get(data, 'total', false);
@@ -119,9 +121,10 @@ export const DefaultContent = ({ hovered, xAxis, yAxis, valueFormat }) => {
119
121
  series.name,
120
122
  ": ",
121
123
  formattedValue));
122
- return (React.createElement("div", { key: id, className: b('content-row') },
124
+ const active = closest && hovered.length > 1;
125
+ return (React.createElement("div", { key: id, className: b('content-row', { active }) },
123
126
  React.createElement("div", { className: b('color'), style: { backgroundColor: color } }),
124
- React.createElement("div", null, closest ? React.createElement("b", null, value) : React.createElement("span", null, value))));
127
+ React.createElement("div", null, value)));
125
128
  }
126
129
  case 'pie':
127
130
  case 'treemap': {
@@ -152,7 +155,8 @@ export const DefaultContent = ({ hovered, xAxis, yAxis, valueFormat }) => {
152
155
  React.createElement("span", null, "\u2192"),
153
156
  " ", target === null || target === void 0 ? void 0 :
154
157
  target.name,
155
- ": ",
158
+ ":",
159
+ ' ',
156
160
  formattedValue)));
157
161
  }
158
162
  case 'radar': {
@@ -167,9 +171,10 @@ export const DefaultContent = ({ hovered, xAxis, yAxis, valueFormat }) => {
167
171
  radarSeries.name || radarSeries.id,
168
172
  "\u00A0"),
169
173
  React.createElement("span", null, formattedValue)));
170
- return (React.createElement("div", { key: id, className: b('content-row') },
174
+ const active = closest && hovered.length > 1;
175
+ return (React.createElement("div", { key: id, className: b('content-row', { active }) },
171
176
  React.createElement("div", { className: b('color'), style: { backgroundColor: color } }),
172
- React.createElement("div", null, closest ? React.createElement("b", null, value) : React.createElement("span", null, value))));
177
+ React.createElement("div", null, value)));
173
178
  }
174
179
  default: {
175
180
  return null;
@@ -22,6 +22,6 @@ export const Tooltip = (props) => {
22
22
  window.dispatchEvent(new CustomEvent('scroll'));
23
23
  }, [left, top]);
24
24
  return (hovered === null || hovered === void 0 ? void 0 : hovered.length) ? (React.createElement(Popup, { anchorElement: anchor, className: b({ pinned: tooltipPinned }), disableTransition: true, floatingStyles: tooltipPinned ? undefined : { pointerEvents: 'none' }, offset: { mainAxis: 20 }, onOpenChange: tooltipPinned ? handleOnOpenChange : undefined, open: true, placement: ['right', 'left', 'top', 'bottom'] },
25
- React.createElement("div", { className: b('content') },
25
+ React.createElement("div", { className: b('popup-content') },
26
26
  React.createElement(ChartTooltipContent, { hovered: hovered, xAxis: xAxis, yAxis: yAxis, renderer: tooltip.renderer, valueFormat: tooltip.valueFormat })))) : null;
27
27
  };
@@ -1,15 +1,28 @@
1
1
  .gcharts-tooltip {
2
2
  box-shadow: 0 2px 12px var(--g-color-sfx-shadow);
3
3
  }
4
- .gcharts-tooltip__content {
5
- padding: 8px 14px;
4
+ .gcharts-tooltip__popup-content {
6
5
  text-wrap: nowrap;
7
6
  border-radius: 4px;
8
7
  background-color: var(--g-color-infographics-tooltip-bg);
9
8
  }
9
+ .gcharts-tooltip__content {
10
+ padding: var(--gcharts-tooltip-content-padding, 8px 0);
11
+ }
12
+ .gcharts-tooltip__series-name {
13
+ padding: 2px 14px 6px;
14
+ font-size: 13px;
15
+ font-weight: 600;
16
+ }
10
17
  .gcharts-tooltip__content-row {
11
18
  display: flex;
12
19
  align-items: center;
20
+ padding: 2px 14px;
21
+ font-size: 12px;
22
+ }
23
+ .gcharts-tooltip__content-row_active {
24
+ font-weight: 600;
25
+ background-color: var(--g-color-base-info-medium);
13
26
  }
14
27
  .gcharts-tooltip__color {
15
28
  display: inline-block;
@@ -21,7 +21,9 @@ export function preparePieData(args) {
21
21
  ? preparedSeries[0].states.hover.halo.size
22
22
  : 0;
23
23
  const maxRadius = Math.min(boundsWidth, boundsHeight) / 2 - haloSize;
24
+ const minRadius = maxRadius * 0.3;
24
25
  const groupedPieSeries = group(preparedSeries, (pieSeries) => pieSeries.stackId);
26
+ let maxMissingWidth = 0;
25
27
  const prepareItem = (stackId, items) => {
26
28
  var _a;
27
29
  const series = items[0];
@@ -173,12 +175,16 @@ export function preparePieData(args) {
173
175
  if (dataLabels.allowOverlap || !overlap) {
174
176
  const left = getLeftPosition(label);
175
177
  if (Math.abs(left) > boundsWidth / 2) {
176
- label.maxWidth = label.size.width - (Math.abs(left) - boundsWidth / 2);
178
+ const overflow = Math.abs(left) - boundsWidth / 2;
179
+ label.maxWidth = label.size.width - overflow;
180
+ maxMissingWidth = Math.max(maxMissingWidth, overflow);
177
181
  }
178
182
  else {
179
183
  const right = left + label.size.width;
180
184
  if (right > boundsWidth / 2) {
181
- label.maxWidth = label.size.width - (right - boundsWidth / 2);
185
+ const overflow = right - boundsWidth / 2;
186
+ label.maxWidth = label.size.width - overflow;
187
+ maxMissingWidth = Math.max(maxMissingWidth, overflow);
182
188
  }
183
189
  }
184
190
  if (shouldUseHtml) {
@@ -237,6 +243,18 @@ export function preparePieData(args) {
237
243
  data.labels = labels;
238
244
  data.htmlLabels = htmlLabels;
239
245
  data.connectors = connectors;
246
+ if (maxMissingWidth > 0) {
247
+ const { dataLabels } = items[0];
248
+ if (dataLabels.enabled) {
249
+ data.segments.forEach((s) => {
250
+ s.data.radius = Math.max(minRadius, s.data.radius - maxMissingWidth);
251
+ });
252
+ const finalLabels = prepareLabels({ data, series: items });
253
+ data.labels = finalLabels.labels;
254
+ data.htmlLabels = finalLabels.htmlLabels;
255
+ data.connectors = finalLabels.connectors;
256
+ }
257
+ }
240
258
  return data;
241
259
  });
242
260
  }
@@ -60,7 +60,7 @@ function renderLabels(selection, { labels, style = {}, attrs = {}, }) {
60
60
  .append('tspan')
61
61
  .attr('x', 0)
62
62
  .attr('dy', 0)
63
- .text((d) => d);
63
+ .html((d) => d);
64
64
  return text;
65
65
  }
66
66
  export function getLabelsSize({ labels, style, rotation, html, }) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/charts",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "React component used to render charts",
5
5
  "license": "MIT",
6
6
  "main": "dist/cjs/index.js",