sea-chart 2.0.60 → 2.0.62

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.
@@ -0,0 +1,15 @@
1
+ .sea-chart-clear-icon {
2
+ height: 20px;
3
+ width: 20px;
4
+ display: flex;
5
+ align-items: center;
6
+ justify-content: center;
7
+ cursor: pointer;
8
+ color: var(--bs-icon-color);
9
+ pointer-events: all;
10
+ }
11
+
12
+ .sea-chart-clear-icon:hover {
13
+ background-color: var(--bs-icon-btn-hover-bg-color, var(--rc-calendar-icon-btn-hover-bg-color, rgba(0, 0, 0, 0.04)));
14
+ border-radius: 4px;
15
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+ var _DTableToolTip2 = _interopRequireDefault(require("dtable-ui-component/lib/DTableToolTip"));
10
+ var _DTableIcon2 = _interopRequireDefault(require("dtable-ui-component/lib/DTableIcon"));
11
+ var _react = _interopRequireWildcard(require("react"));
12
+ var _lang = require("dtable-ui-component/lib/lang");
13
+ require("./index.css");
14
+ function ClearIcon() {
15
+ const tooltipId = `sea-chart-clear-icon-${(0, _react.useId)().replace(/:/g, '')}`;
16
+ const label = (0, _lang.getLocale)('Clear');
17
+ return /*#__PURE__*/_react.default.createElement("span", {
18
+ id: tooltipId,
19
+ className: "sea-chart-clear-icon",
20
+ "aria-label": label
21
+ }, /*#__PURE__*/_react.default.createElement(_DTableIcon2.default, {
22
+ symbol: "close",
23
+ ariaHidden: true
24
+ }), /*#__PURE__*/_react.default.createElement(_DTableToolTip2.default, {
25
+ target: tooltipId,
26
+ placement: "bottom"
27
+ }, label));
28
+ }
29
+ var _default = exports.default = ClearIcon;
package/dist/model/bar.js CHANGED
@@ -34,7 +34,7 @@ class Bar extends _baseModel.default {
34
34
  this.y_axis_show_value = (0, _utils.isBoolean)(options.y_axis_show_value) ? options.y_axis_show_value : false;
35
35
  this.y_axis_show_label = (0, _utils.isBoolean)(options.y_axis_show_label) ? options.y_axis_show_label : false;
36
36
  this.y_axis_label_position = options.y_axis_label_position;
37
- this.y_axis_auto_range = options.y_axis_auto_range;
37
+ this.y_axis_auto_range = (0, _utils.isBoolean)(options.y_axis_auto_range) ? options.y_axis_auto_range : true;
38
38
  this.y_axis_min = options.y_axis_min;
39
39
  this.y_axis_max = options.y_axis_max;
40
40
  this.y_axis_label_color = options.y_axis_label_color;
@@ -10,6 +10,7 @@ var _react = _interopRequireWildcard(require("react"));
10
10
  var _dayjs = _interopRequireDefault(require("dayjs"));
11
11
  var _seafileCalendar = _interopRequireDefault(require("@seafile/seafile-calendar"));
12
12
  var _Picker = _interopRequireDefault(require("@seafile/seafile-calendar/lib/Picker"));
13
+ var _clearIcon = _interopRequireDefault(require("../../components/clear-icon"));
13
14
  require("dayjs/locale/zh-cn");
14
15
  require("dayjs/locale/en-gb");
15
16
  var _utils = require("../../utils");
@@ -116,18 +117,6 @@ class TimePicker extends _react.Component {
116
117
  value: value && value.format(DATE_FORMAT) || '',
117
118
  disabled: true
118
119
  });
119
- const clearStyle = {
120
- position: 'absolute',
121
- top: '15px',
122
- left: '225px',
123
- color: 'gray',
124
- fontSize: '12px',
125
- cursor: 'pointer'
126
- };
127
- const clearIcon = /*#__PURE__*/_react.default.createElement('i', {
128
- className: 'item-icon dtable-font dtable-icon-x',
129
- style: clearStyle
130
- });
131
120
  const calendar = /*#__PURE__*/_react.default.createElement(_seafileCalendar.default, {
132
121
  className: "dtable-rc-calendar",
133
122
  locale: (0, _utils.translateCalendar)(),
@@ -140,7 +129,7 @@ class TimePicker extends _react.Component {
140
129
  showDateInput: true,
141
130
  focusablePanel: false,
142
131
  onClear: this.onClear,
143
- clearIcon: clearIcon,
132
+ clearIcon: /*#__PURE__*/_react.default.createElement(_clearIcon.default, null),
144
133
  showHourAndMinute: false,
145
134
  defaultMinutesTime: minutesTime,
146
135
  onClickRightPanelTime: this.onClickRightPanelTime
@@ -355,6 +355,34 @@ BaseUtils.isValidValue = function (value) {
355
355
  if (value === 0 && !display_empty) return true;
356
356
  return Boolean(value);
357
357
  };
358
+ BaseUtils.parseAxisBound = value => {
359
+ if (value === null || value === undefined || value === '') return NaN;
360
+ return Number(value);
361
+ };
362
+ BaseUtils.getValueAxisRange = (autoRange, min, max, autoDomain) => {
363
+ const autoRangeResult = {
364
+ domain: autoDomain,
365
+ isManual: false
366
+ };
367
+ if (autoRange !== false) return autoRangeResult;
368
+ const minValue = _BaseUtils.parseAxisBound(min);
369
+ const maxValue = _BaseUtils.parseAxisBound(max);
370
+ const isValidRange = Number.isFinite(minValue) && Number.isFinite(maxValue) && minValue < maxValue;
371
+ if (!isValidRange) return autoRangeResult;
372
+ return {
373
+ domain: [minValue, maxValue],
374
+ isManual: true
375
+ };
376
+ };
377
+ BaseUtils.getValueClamper = _ref => {
378
+ let {
379
+ domain,
380
+ isManual
381
+ } = _ref;
382
+ if (!isManual) return value => value;
383
+ const [min, max] = domain;
384
+ return value => Math.min(Math.max(value, min), max);
385
+ };
358
386
  BaseUtils.getSummaryValueDisplayString = function (summaryColumn, summaryValue) {
359
387
  let summaryMethod = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'count';
360
388
  if (!summaryColumn) return summaryValue;
@@ -393,11 +421,11 @@ BaseUtils.isDateSummaryColumn = summaryColumn => {
393
421
  } = summaryColumn;
394
422
  return type !== _dtableUtils.CellType.LINK && (0, _dtableUtils.isDateColumn)(summaryColumn);
395
423
  };
396
- BaseUtils.getSummaryValue = (_ref, currentValue, nextValue, isPivotCalculator) => {
424
+ BaseUtils.getSummaryValue = (_ref2, currentValue, nextValue, isPivotCalculator) => {
397
425
  let {
398
426
  summaryMethod,
399
427
  summaryColumn
400
- } = _ref;
428
+ } = _ref2;
401
429
  if (_BaseUtils.isDateSummaryColumn(summaryColumn)) {
402
430
  if (summaryMethod === 'MAX') {
403
431
  if (currentValue && nextValue) {
@@ -90,7 +90,10 @@ class AreaGroup extends _chartComponent.default {
90
90
 
91
91
  // Y axis
92
92
  const niceEnd = d3.nice(0, d3.max(data, d => d.value), 5)[1];
93
- const y = d3.scaleLinear().domain(y_axis_auto_range ? [0, niceEnd] : [y_axis_min || 0, y_axis_max || niceEnd]).range([chartHeight - insertPadding, insertPadding + marginTop]);
93
+ const yAxisRange = _utils.BaseUtils.getValueAxisRange(y_axis_auto_range, y_axis_min, y_axis_max, [0, niceEnd]);
94
+ const y = d3.scaleLinear().domain(yAxisRange.domain).range([chartHeight - insertPadding, insertPadding + marginTop]);
95
+ const yBaseline = yAxisRange.domain[0];
96
+ const clampYValue = _utils.BaseUtils.getValueClamper(yAxisRange);
94
97
  this.chart.append('g').attr('class', 'y-axis-wrapper').attr('transform', `translate(${insertPadding}, 0)`).call(d3.axisLeft(y).tickSizeInner(0).ticks(5).tickFormat(d => _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, d, y_axis_summary_method))).call(g => this.drawYaxis(g, theme));
95
98
 
96
99
  // X axis
@@ -138,7 +141,7 @@ class AreaGroup extends _chartComponent.default {
138
141
  const area = d3.area().x(d => {
139
142
  const xVal = x(d.name) + x.bandwidth() / 2;
140
143
  return xVal;
141
- }).y0(y(0)).y1(d => y(d.value)).curve(line_type === _constants.CHART_LINE_TYPES[1] ? d3.curveBumpX : d3.curveLinear);
144
+ }).y0(y(yBaseline)).y1(d => y(clampYValue(d.value))).curve(line_type === _constants.CHART_LINE_TYPES[1] ? d3.curveBumpX : d3.curveLinear);
142
145
  contentWrapper.append('path').attr('class', 'area').attr('fill', this.colorMap[group_name]).attr('d', () => area(data)).attr('opacity', '0.3');
143
146
  });
144
147
 
@@ -202,7 +205,7 @@ class AreaGroup extends _chartComponent.default {
202
205
  });
203
206
  });
204
207
  if (display_goal_line && goal_label && goal_value) {
205
- this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y);
208
+ this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y, yAxisRange.isManual);
206
209
  }
207
210
  this.setLegend({
208
211
  legendName: 'group_name',
@@ -82,7 +82,10 @@ class Area extends _chartComponent.default {
82
82
 
83
83
  // Y axis
84
84
  const niceEnd = d3.nice(0, d3.max(data, d => d.value), 5)[1];
85
- const y = d3.scaleLinear().domain(y_axis_auto_range ? [0, niceEnd] : [y_axis_min || 0, y_axis_max || niceEnd]).range([chartHeight - insertPadding, insertPadding + marginTop]);
85
+ const yAxisRange = _utils.BaseUtils.getValueAxisRange(y_axis_auto_range, y_axis_min, y_axis_max, [0, niceEnd]);
86
+ const y = d3.scaleLinear().domain(yAxisRange.domain).range([chartHeight - insertPadding, insertPadding + marginTop]);
87
+ const yBaseline = yAxisRange.domain[0];
88
+ const clampYValue = _utils.BaseUtils.getValueClamper(yAxisRange);
86
89
  this.chart.append('g').attr('class', 'y-axis-wrapper').attr('transform', `translate(${insertPadding}, 0)`).call(d3.axisLeft(y).tickSizeInner(0).ticks(5).tickFormat(d => _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, d, y_axis_summary_method))).call(g => this.drawYaxis(g, theme));
87
90
 
88
91
  // X axis
@@ -118,7 +121,7 @@ class Area extends _chartComponent.default {
118
121
  const area = d3.area().x(d => {
119
122
  const xVal = x(d.name) + x.bandwidth() / 2;
120
123
  return xVal;
121
- }).y0(y(0)).y1(d => y(d.value)).curve(line_type === _constants.CHART_LINE_TYPES[1] ? d3.curveBumpX : d3.curveLinear);
124
+ }).y0(y(yBaseline)).y1(d => y(clampYValue(d.value))).curve(line_type === _constants.CHART_LINE_TYPES[1] ? d3.curveBumpX : d3.curveLinear);
122
125
  this.Area = contentWrapper.append('path').attr('fill', this.getAreaColor()).attr('d', () => area(data)).attr('opacity', '0.3').call(g => this.animateFadeIn(g, this.transitionDuration));
123
126
 
124
127
  // circle
@@ -171,7 +174,7 @@ class Area extends _chartComponent.default {
171
174
  });
172
175
  });
173
176
  if (display_goal_line && goal_label && goal_value) {
174
- this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y);
177
+ this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y, yAxisRange.isManual);
175
178
  }
176
179
  };
177
180
  this.updateCircleAndTickStyle = _ref => {
@@ -66,7 +66,10 @@ class BarCompare extends _chartComponent.default {
66
66
  insertPadding
67
67
  } = this.chartBoundingClientRect;
68
68
  data = data.sort((a, b) => d3.ascending(a.name, b.name));
69
- const y = d3.scaleLinear().domain(y_axis_auto_range ? [0, d3.max(data, d => d.value)] : [y_axis_min, y_axis_max]).range([chartHeight - insertPadding, insertPadding]);
69
+ const yAxisRange = _chartUtils.BaseUtils.getValueAxisRange(y_axis_auto_range, y_axis_min, y_axis_max, [0, d3.max(data, d => d.value)]);
70
+ const y = d3.scaleLinear().domain(yAxisRange.domain).range([chartHeight - insertPadding, insertPadding]);
71
+ const yBaseline = yAxisRange.domain[0];
72
+ const clampYValue = _chartUtils.BaseUtils.getValueClamper(yAxisRange);
70
73
 
71
74
  // Y axis
72
75
  this.chart.append('g').attr('class', 'y-axis-wrapper').attr('transform', `translate(${insertPadding},0)`).call(d3.axisLeft(y).tickSizeInner(0).ticks(5).tickFormat(d => _chartUtils.BaseUtils.getSummaryValueDisplayString(columnGroupbyColumn, d, y_axis_summary_method))).call(g => this.drawYaxis(g, theme));
@@ -94,7 +97,7 @@ class BarCompare extends _chartComponent.default {
94
97
  .selectAll().data(_ref2 => {
95
98
  let [a, d] = _ref2;
96
99
  return d;
97
- }).join('rect').attr('opacity', 1).attr('x', (d, index) => index * x.bandwidth()).attr('y', d => y(d.value)).attr('width', x.bandwidth()).attr('height', d => y(0) - y(d.value) === 0 ? 0 : y(0) - y(d.value)).attr('fill', d => color(d.group_name)).attr('data-value', d => d.value).attr('data-groupName', d => d.name).call(g => {
100
+ }).join('rect').attr('opacity', 1).attr('x', (d, index) => index * x.bandwidth()).attr('y', d => y(clampYValue(d.value))).attr('width', x.bandwidth()).attr('height', d => y(yBaseline) - y(clampYValue(d.value))).attr('fill', d => color(d.group_name)).attr('data-value', d => d.value).attr('data-groupName', d => d.name).call(g => {
98
101
  g.nodes().forEach(rect => {
99
102
  // add rect borderRadius
100
103
  this.addClipPath({
@@ -197,8 +200,6 @@ class BarCompare extends _chartComponent.default {
197
200
  const theme = _constants.CHART_THEME_COLOR[globalTheme];
198
201
  const {
199
202
  label_font_size,
200
- y_axis_min,
201
- y_axis_max,
202
203
  increase_line_color,
203
204
  display_increase_percentage
204
205
  } = chart.config;
@@ -212,14 +213,8 @@ class BarCompare extends _chartComponent.default {
212
213
  const lineX = d3.scaleBand().domain(increaseData.map(d => d.name)).range([insertPadding + this.horizontalOverflowOffset, chartWidth - insertPadding]).paddingInner(0.5).paddingOuter(0.1);
213
214
  const autoMin = d3.min(increaseData, d => d.value);
214
215
  const autoMax = d3.max(increaseData, d => d.value);
215
- let min, max;
216
- if (!(y_axis_min && y_axis_max)) {
217
- min = autoMin;
218
- max = autoMax;
219
- } else {
220
- min = y_axis_min;
221
- max = y_axis_max;
222
- }
216
+ const min = autoMin;
217
+ const max = autoMax;
223
218
  let yDomain = [min, max];
224
219
  // avoid y axis range is invalid
225
220
  if (min === max) {
@@ -94,7 +94,10 @@ class BarGroup extends _chartComponent.default {
94
94
  const useSingleSelectColumnColor = ((column_groupby_column === null || column_groupby_column === void 0 ? void 0 : column_groupby_column.type) === _dtableUtils.CellType.SINGLE_SELECT || (column_groupby_column === null || column_groupby_column === void 0 ? void 0 : column_groupby_column.type) === _dtableUtils.CellType.MULTIPLE_SELECT) && color_theme === _colorRules.SUPPORT_SINGLE_SELECT_THEMES_OPTIONS.SINGLE_SELECT_COLUMN_COLORS;
95
95
  useSingleSelectColumnColor ? this.setSingleSelectColorMap(fullData) : this.setColorMap(fullData, chartColorTheme, 'group_name', columnGroupbyColumn, chart); // use single select column color
96
96
 
97
- const y = d3.scaleLinear().domain(y_axis_auto_range ? [0, d3.max(data, d => d.value)] : [y_axis_min, y_axis_max]).range([chartHeight - insertPadding, insertPadding + marginTop]);
97
+ const yAxisRange = _utils.BaseUtils.getValueAxisRange(y_axis_auto_range, y_axis_min, y_axis_max, [0, d3.max(data, d => d.value)]);
98
+ const y = d3.scaleLinear().domain(yAxisRange.domain).range([chartHeight - insertPadding, insertPadding + marginTop]);
99
+ const yBaseline = yAxisRange.domain[0];
100
+ const clampYValue = _utils.BaseUtils.getValueClamper(yAxisRange);
98
101
 
99
102
  // Y axis
100
103
  this.chart.append('g').attr('class', 'y-axis-wrapper').attr('transform', `translate(${insertPadding},0)`).call(d3.axisLeft(y).tickSizeInner(0).ticks(5).tickFormat(d => _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, d, y_axis_summary_method))).call(g => this.drawYaxis(g, theme));
@@ -121,7 +124,7 @@ class BarGroup extends _chartComponent.default {
121
124
  let [, dum] = _ref2;
122
125
  const groupNode = groupNodes[groupIndex];
123
126
  const localX = d3.scaleBand().domain(dum.map(d => d.group_name)).range([0, fx.bandwidth()]).paddingInner(0).paddingOuter(0);
124
- const rectSelection = d3.select(groupNode).selectAll('rect').data(dum).join('rect').attr('opacity', 1).attr('x', d => localX(d.group_name)).attr('y', d => y(d.value)).attr('width', localX.bandwidth()).attr('height', d => y(0) - y(d.value)).attr('fill', d => {
127
+ const rectSelection = d3.select(groupNode).selectAll('rect').data(dum).join('rect').attr('opacity', 1).attr('x', d => localX(d.group_name)).attr('y', d => y(clampYValue(d.value))).attr('width', localX.bandwidth()).attr('height', d => y(yBaseline) - y(clampYValue(d.value))).attr('fill', d => {
125
128
  var _this$colorMap$colorK;
126
129
  const colorKey = d.group_name || d.group_name === 0 ? d.group_name : '';
127
130
  return (_this$colorMap$colorK = this.colorMap[colorKey]) !== null && _this$colorMap$colorK !== void 0 ? _this$colorMap$colorK : _constants.CHART_STYLE_COLORS[0];
@@ -159,7 +162,7 @@ class BarGroup extends _chartComponent.default {
159
162
  this.animateFadeIn(contentWrapper.selectAll('text'), this.transitionDuration, this.transitionDuration * 0.5);
160
163
  });
161
164
  if (display_goal_line && goal_label && goal_value) {
162
- this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y);
165
+ this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y, yAxisRange.isManual);
163
166
  }
164
167
  this.setLegend({
165
168
  legendName: 'group_name',
@@ -102,7 +102,9 @@ class BarStack extends _chartComponent.default {
102
102
  return ((_group$get = group.get(key)) === null || _group$get === void 0 ? void 0 : _group$get.value) || 0;
103
103
  })(d3.index(sortedData, d => d.name, d => d.group_name));
104
104
  const niceEnd = d3.nice(0, d3.max(series, d => d3.max(d, d => d[1])), 5)[1];
105
- const y = d3.scaleLinear().domain(y_axis_auto_range ? [0, niceEnd] : [y_axis_min, y_axis_max]).range([chartHeight - insertPadding, insertPadding + marginTop]);
105
+ const yAxisRange = _utils.BaseUtils.getValueAxisRange(y_axis_auto_range, y_axis_min, y_axis_max, [0, niceEnd]);
106
+ const y = d3.scaleLinear().domain(yAxisRange.domain).range([chartHeight - insertPadding, insertPadding + marginTop]);
107
+ const clampYValue = _utils.BaseUtils.getValueClamper(yAxisRange);
106
108
 
107
109
  // Y axis
108
110
  this.chart.append('g').attr('class', 'y-axis-wrapper').attr('transform', `translate(${insertPadding},0)`).call(d3.axisLeft(y).tickSizeInner(0).ticks(5).tickFormat(d => _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, d, y_axis_summary_method))).call(g => this.drawYaxis(g, theme));
@@ -125,8 +127,8 @@ class BarStack extends _chartComponent.default {
125
127
  return d;
126
128
  });
127
129
  return data;
128
- }).join('rect').attr('opacity', 1).attr('x', d => x(d.data[0])).attr('y', d => y(d[1])).attr('height', d => {
129
- const height = y(d[0]) - y(d[1]);
130
+ }).join('rect').attr('opacity', 1).attr('x', d => x(d.data[0])).attr('y', d => y(clampYValue(d[1]))).attr('height', d => {
131
+ const height = y(clampYValue(d[0])) - y(clampYValue(d[1]));
130
132
  return (0, _lodashEs.isNaN)(height) ? 0 : height;
131
133
  }).attr('width', x.bandwidth()).attr('fill', d => this.colorMap[d.key] || _constants.CHART_STYLE_COLORS[0]).attr('data-value', d => {
132
134
  const {
@@ -177,7 +179,7 @@ class BarStack extends _chartComponent.default {
177
179
  this.handleAcitveAndInActiveState('active', event);
178
180
  });
179
181
  if (display_goal_line && goal_label && goal_value) {
180
- this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y);
182
+ this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y, yAxisRange.isManual);
181
183
  }
182
184
  this.setLegend({
183
185
  legendName: 'group_name',
@@ -155,7 +155,10 @@ class Bar extends _chartComponent.default {
155
155
  insertPadding,
156
156
  marginTop
157
157
  } = this.chartBoundingClientRect;
158
- const y = d3.scaleLinear().domain(y_axis_auto_range ? [0, d3.max(data, d => d.value)] : [y_axis_min, y_axis_max]).range([chartHeight - insertPadding, insertPadding + marginTop]);
158
+ const yAxisRange = _utils.BaseUtils.getValueAxisRange(y_axis_auto_range, y_axis_min, y_axis_max, [0, d3.max(data, d => d.value)]);
159
+ const y = d3.scaleLinear().domain(yAxisRange.domain).range([chartHeight - insertPadding, insertPadding + marginTop]);
160
+ const yBaseline = yAxisRange.domain[0];
161
+ const clampYValue = _utils.BaseUtils.getValueClamper(yAxisRange);
159
162
 
160
163
  // Y axis
161
164
  this.chart.append('g').attr('class', 'y-axis-wrapper').attr('transform', `translate(${insertPadding}, 0)`).call(d3.axisLeft(y).tickSizeInner(0).ticks(5).tickFormat(d => _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, d, y_axis_summary_method))).call(g => this.drawYaxis(g, theme));
@@ -170,7 +173,7 @@ class Bar extends _chartComponent.default {
170
173
  this.checkTickOverlap(g);
171
174
  });
172
175
  const contentWrapper = this.chart.append('g').attr('class', 'content-wrapper');
173
- contentWrapper.selectAll().data(data).join('rect').attr('opacity', 1).attr('fill', d => d3.color(this.getFillColor(d))).attr('data-x', d => x(d.name)).attr('data-y', d => y(d.value)).attr('data-width', x.bandwidth()).attr('data-value', d => d.value).attr('data-groupName', d => d.name).attr('x', d => x(d.name)).attr('y', d => y(d.value)).attr('width', x.bandwidth()).attr('height', d => y(0) - y(d.value)).call(g => {
176
+ contentWrapper.selectAll().data(data).join('rect').attr('opacity', 1).attr('fill', d => d3.color(this.getFillColor(d))).attr('data-x', d => x(d.name)).attr('data-y', d => y(clampYValue(d.value))).attr('data-width', x.bandwidth()).attr('data-value', d => d.value).attr('data-groupName', d => d.name).attr('x', d => x(d.name)).attr('y', d => y(clampYValue(d.value))).attr('width', x.bandwidth()).attr('height', d => y(yBaseline) - y(clampYValue(d.value))).call(g => {
174
177
  g.nodes().forEach(path => {
175
178
  // Add label
176
179
  if (y_axis_show_value) {
@@ -204,7 +207,7 @@ class Bar extends _chartComponent.default {
204
207
  this.animateFadeIn(contentWrapper.selectAll('text'), this.transitionDuration, this.transitionDuration * 0.5);
205
208
  });
206
209
  if (display_goal_line && goal_label && goal_value) {
207
- this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y);
210
+ this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y, yAxisRange.isManual);
208
211
  }
209
212
  };
210
213
  this.chart = null;
@@ -1178,11 +1178,17 @@ class ChartComponent extends _react.Component {
1178
1178
  }
1179
1179
  return themeColors || _constants.CHART_THEME_COLOR[_constants.THEME_NAME_MAP.LIGHT];
1180
1180
  };
1181
- this.setDispalyGoalLine = (goal_label, goal_value, insertPadding, yScale) => {
1181
+ this.setDispalyGoalLine = function (goal_label, goal_value, insertPadding, yScale) {
1182
+ let isManualRange = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
1183
+ if (isManualRange) {
1184
+ const goalValue = Number(goal_value);
1185
+ const [domainMin, domainMax] = yScale.domain();
1186
+ if (goalValue < domainMin || goalValue > domainMax) return;
1187
+ }
1182
1188
  const {
1183
1189
  width: chartWidth
1184
- } = this.chartBoundingClientRect;
1185
- const annotationWrapper = this.chart.append('g').attr('class', `annotation-wrapper`);
1190
+ } = _this.chartBoundingClientRect;
1191
+ const annotationWrapper = _this.chart.append('g').attr('class', `annotation-wrapper`);
1186
1192
  annotationWrapper.append('line').attr('stroke', '#aaa').attr('x1', insertPadding).attr('y1', yScale(goal_value)).attr('x2', chartWidth - insertPadding).attr('y2', yScale(goal_value)).attr('stroke-dasharray', '8,3').call(g => {
1187
1193
  annotationWrapper.append('text').attr('x', chartWidth - insertPadding - 30).attr('y', yScale(goal_value) - 10).attr('fill', '#666').text(goal_label);
1188
1194
  });
@@ -112,7 +112,9 @@ class Combination extends _chartComponent.default {
112
112
  dataLeft = [];
113
113
  }
114
114
  const rightNiceEnd = d3.nice(0, d3.max(data, d => d.value_right) || 0, 5)[1];
115
- const rightY = d3.scaleLinear().domain(y_axis_auto_range_right ? [d3.min(data, d => d.value_right), rightNiceEnd] : [y_axis_min_right, y_axis_max_right]).range([chartHeight - insertPadding, insertPadding + marginTop]);
115
+ const rightYAxisRange = _utils.BaseUtils.getValueAxisRange(y_axis_auto_range_right, y_axis_min_right, y_axis_max_right, [d3.min(data, d => d.value_right), rightNiceEnd]);
116
+ const rightY = d3.scaleLinear().domain(rightYAxisRange.domain).range([chartHeight - insertPadding, insertPadding + marginTop]);
117
+ const clampRightYValue = _utils.BaseUtils.getValueClamper(rightYAxisRange);
116
118
 
117
119
  // Y axis (right)
118
120
  const rightAxisWrapper = this.chart.append('g').attr('class', 'y-axis-wrapper-right').attr('transform', `translate(${chartWidth - insertPadding},0)`).call(d3.axisRight(rightY).tickSizeInner(0).ticks(5).tickFormat(d => _utils.BaseUtils.getSummaryValueDisplayString(rightSummaryColumn, d, y_axis_right_summary_column))).call(g => {
@@ -122,7 +124,10 @@ class Combination extends _chartComponent.default {
122
124
  });
123
125
  const rightAxisOffset = this.getRightAxisOffset(rightAxisWrapper);
124
126
  const leftNiceEnd = d3.nice(0, d3.max(dataLeft, d => d.value_left) || 0, 5)[1];
125
- const leftY = d3.scaleLinear().domain(y_axis_auto_range_left ? [0, leftNiceEnd] : [y_axis_min_left, y_axis_max_left]).range([chartHeight - insertPadding, insertPadding + marginTop]);
127
+ const leftYAxisRange = _utils.BaseUtils.getValueAxisRange(y_axis_auto_range_left, y_axis_min_left, y_axis_max_left, [0, leftNiceEnd]);
128
+ const leftY = d3.scaleLinear().domain(leftYAxisRange.domain).range([chartHeight - insertPadding, insertPadding + marginTop]);
129
+ const leftYBaseline = leftYAxisRange.domain[0];
130
+ const clampLeftYValue = _utils.BaseUtils.getValueClamper(leftYAxisRange);
126
131
 
127
132
  // Y axis (left)
128
133
  this.chart.append('g').attr('class', 'y-axis-wrapper-left').attr('transform', `translate(${insertPadding},0)`).call(d3.axisLeft(leftY).tickSizeInner(0).ticks(5).tickFormat(d => _utils.BaseUtils.getSummaryValueDisplayString(leftSummaryColumn, d, y_axis_left_summary_method))).call(g => this.drawYaxis(g, theme, rightAxisOffset));
@@ -152,7 +157,7 @@ class Combination extends _chartComponent.default {
152
157
  return x(d.group_name);
153
158
  }
154
159
  return 0;
155
- }).attr('y', d => leftY(d.value_left)).attr('width', x.bandwidth()).attr('height', d => leftY(0) - leftY(d.value_left)).attr('fill', d => {
160
+ }).attr('y', d => leftY(clampLeftYValue(d.value_left))).attr('width', x.bandwidth()).attr('height', d => leftY(leftYBaseline) - leftY(clampLeftYValue(d.value_left))).attr('fill', d => {
156
161
  if (!y_axis_left_group_by_multiple_numeric_column) {
157
162
  return currentTheme.colors[0];
158
163
  }
@@ -201,10 +206,10 @@ class Combination extends _chartComponent.default {
201
206
 
202
207
  // Line group
203
208
  if (!rightHidden) {
204
- this.drawRightContent(data, fx, rightY, showRightValue, rightSummaryColumn, rightTitle);
209
+ this.drawRightContent(data, fx, rightY, showRightValue, rightSummaryColumn, rightTitle, clampRightYValue);
205
210
  }
206
211
  if (display_goal_line && goal_label && goal_value) {
207
- this.setDispalyGoalLine(goal_label, goal_value, insertPadding, rightY);
212
+ this.setDispalyGoalLine(goal_label, goal_value, insertPadding, rightY, rightYAxisRange.isManual);
208
213
  }
209
214
  const legendData = this.getCombinatinoLegendData(data, leftSummaryColumn, rightSummaryColumn);
210
215
  this.setLegend({
@@ -292,7 +297,7 @@ class Combination extends _chartComponent.default {
292
297
  const name = rightSummaryColumn.name + ' '; // Add a space character to avoid merging with the previous left legend
293
298
  this.colorMap[name] = currentTheme.colors[1];
294
299
  };
295
- this.drawRightContent = (data, fx, rightY, showRightValue, rightSummaryColumn, rightTitle) => {
300
+ this.drawRightContent = (data, fx, rightY, showRightValue, rightSummaryColumn, rightTitle, clampRightYValue) => {
296
301
  const {
297
302
  chart,
298
303
  chartColorTheme,
@@ -312,7 +317,7 @@ class Combination extends _chartComponent.default {
312
317
  circleData[index]['name'] = d.name;
313
318
  return x;
314
319
  }).y((d, index) => {
315
- const y = rightY(d.value_right);
320
+ const y = rightY(clampRightYValue(d.value_right));
316
321
  circleData[index]['y'] = y;
317
322
  circleData[index]['value'] = d.value_right;
318
323
  return y;
@@ -97,7 +97,9 @@ class Completeness extends _chartComponent.default {
97
97
  // X axis
98
98
  const allSeries = this.getAllSeries(newSeries);
99
99
  const niceEnd = d3.nice(0, d3.max(allSeries, d => d.sumValue), 5)[1];
100
- const x = d3.scaleLinear().domain(y_axis_auto_range ? [0, niceEnd] : [y_axis_min || 0, y_axis_max || niceEnd]).range([Number(yAxis.node().getAttribute('data-axisWidth')), chartWidth - insertPadding - marginRight]);
100
+ const xAxisRange = _utils.BaseUtils.getValueAxisRange(y_axis_auto_range, y_axis_min, y_axis_max, [0, niceEnd]);
101
+ const x = d3.scaleLinear().domain(xAxisRange.domain).range([Number(yAxis.node().getAttribute('data-axisWidth')), chartWidth - insertPadding - marginRight]);
102
+ const clampXValue = _utils.BaseUtils.getValueClamper(xAxisRange);
101
103
  this.chart.append('g').attr('class', 'x-axis-wrapper').attr('transform', `translate(0, ${chartHeight - insertPadding})`).call(d3.axisBottom(x).tickSizeInner(0).ticks(5)).call(g => {
102
104
  g.selectAll('.domain').remove();
103
105
  g.selectAll('.tick line').node() && g.selectAll('.tick line').node().remove(); // delete the first line
@@ -143,7 +145,7 @@ class Completeness extends _chartComponent.default {
143
145
  }).selectAll().data(_ref6 => {
144
146
  let [_, d] = _ref6;
145
147
  return d;
146
- }).join('rect').attr('class', 'rect').attr('opacity', 1).attr('x', d => x(d[0]) - Number(yAxis.node().getAttribute('data-axisWidth'))).attr('y', d => localY(d.groupby)).attr('width', d => x(d[1]) - x(d[0])).attr('height', localY.bandwidth()).attr('fill', d => {
148
+ }).join('rect').attr('class', 'rect').attr('opacity', 1).attr('x', d => x(clampXValue(d[0])) - Number(yAxis.node().getAttribute('data-axisWidth'))).attr('y', d => localY(d.groupby)).attr('width', d => x(clampXValue(d[1])) - x(clampXValue(d[0]))).attr('height', localY.bandwidth()).attr('fill', d => {
147
149
  const key = d.key;
148
150
  const groupby = d.groupby;
149
151
  if (key === 'rest') {
@@ -87,7 +87,9 @@ class Completeness extends _chartComponent.default {
87
87
 
88
88
  // X axis
89
89
  const niceEnd = d3.nice(0, d3.max(newSeries, d => d[1].sumValue) || 0, 5)[1];
90
- const x = d3.scaleLinear().domain(y_axis_auto_range ? [0, niceEnd] : [y_axis_min || 0, y_axis_max || niceEnd]).range([Number(yAxis.node().getAttribute('data-axisWidth')), chartWidth - insertPadding - marginRight]);
90
+ const xAxisRange = _utils.BaseUtils.getValueAxisRange(y_axis_auto_range, y_axis_min, y_axis_max, [0, niceEnd]);
91
+ const x = d3.scaleLinear().domain(xAxisRange.domain).range([Number(yAxis.node().getAttribute('data-axisWidth')), chartWidth - insertPadding - marginRight]);
92
+ const clampXValue = _utils.BaseUtils.getValueClamper(xAxisRange);
91
93
  this.chart.append('g').attr('class', 'x-axis-wrapper').attr('transform', `translate(0, ${chartHeight - insertPadding})`).call(d3.axisBottom(x).tickSizeInner(0).ticks(5)).call(g => {
92
94
  g.selectAll('.domain').remove();
93
95
  g.selectAll('.tick line').node() && g.selectAll('.tick line').node().remove(); // delete the first line
@@ -108,8 +110,8 @@ class Completeness extends _chartComponent.default {
108
110
  d.forEach(item => item['groupKey'] = groupKey);
109
111
  return d;
110
112
  }).join('rect').attr('opacity', 1).attr('x', (d, index) => {
111
- return x(d[0]) - Number(yAxis.node().getAttribute('data-axisWidth'));
112
- }).attr('y', (d, index) => y(d.groupKey)).attr('width', d => x(d[1]) - x(d[0])).attr('height', y.bandwidth()).attr('fill', d => {
113
+ return x(clampXValue(d[0])) - Number(yAxis.node().getAttribute('data-axisWidth'));
114
+ }).attr('y', (d, index) => y(d.groupKey)).attr('width', d => x(clampXValue(d[1])) - x(clampXValue(d[0]))).attr('height', y.bandwidth()).attr('fill', d => {
113
115
  return d.key === 'rest' ? '#bdbdbd' : colors[0];
114
116
  }).attr('data-value', d => d.data.value).attr('data-groupName', d => d.data.slugId).attr('data-tooltipTitle', d => d.groupKey).attr('data-tooltipName', d => d.key).call(g => {
115
117
  // add rect borderRadius
@@ -55,7 +55,8 @@ class Dashboard extends _chartComponent.default {
55
55
  height: chartHeight,
56
56
  insertPadding
57
57
  } = this.chartBoundingClientRect;
58
- const value = (Number(data) || 0) * 100;
58
+ const rawValue = data && typeof data === 'object' && 'value' in data ? data.value : data;
59
+ const value = (Number(rawValue) || 0) * 100;
59
60
  const formatValue = value >= 100 ? 100 : value.toFixed(1);
60
61
  const innerRadius = Math.min(chartWidth, chartHeight) / 2 * 0.7;
61
62
  const outerRadius = Math.min(chartWidth, chartHeight) / 2 * 0.75;
@@ -127,7 +127,10 @@ class HorizontalBarGroup extends _chartComponent.default {
127
127
  this.checkTickOverlap(g, 'yAxis');
128
128
  });
129
129
  const niceEnd = d3.nice(0, d3.max(data, d => d.value), 5)[1];
130
- const x = d3.scaleLinear().domain(horizontal_axis_auto_range ? [0, niceEnd] : [horizontal_axis_min || 0, horizontal_axis_max || niceEnd]).range([Number(yAxis.node().getAttribute('data-axisWidth')), chartWidth - insertPadding - marginRight]);
130
+ const xAxisRange = _utils.BaseUtils.getValueAxisRange(horizontal_axis_auto_range, horizontal_axis_min, horizontal_axis_max, [0, niceEnd]);
131
+ const x = d3.scaleLinear().domain(xAxisRange.domain).range([Number(yAxis.node().getAttribute('data-axisWidth')), chartWidth - insertPadding - marginRight]);
132
+ const xBaseline = xAxisRange.domain[0];
133
+ const clampXValue = _utils.BaseUtils.getValueClamper(xAxisRange);
131
134
 
132
135
  // X axis
133
136
  this.chart.append('g').attr('class', 'x-axis-wrapper').attr('transform', `translate(0, ${chartHeight - insertPadding})`).call(d3.axisBottom(x).tickSizeInner(0).ticks(5).tickFormat(d => _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, d, horizontal_axis_summary_method))).call(g => {
@@ -149,7 +152,7 @@ class HorizontalBarGroup extends _chartComponent.default {
149
152
  .selectAll().data(_ref2 => {
150
153
  let [_, d] = _ref2;
151
154
  return d;
152
- }).join('rect').attr('opacity', 1).attr('x', 0).attr('y', (d, index) => index * y.bandwidth()).attr('width', d => x(d.value) - x(0)).attr('height', y.bandwidth()).attr('fill', d => {
155
+ }).join('rect').attr('opacity', 1).attr('x', 0).attr('y', (d, index) => index * y.bandwidth()).attr('width', d => x(clampXValue(d.value)) - x(xBaseline)).attr('height', y.bandwidth()).attr('fill', d => {
153
156
  var _this$colorMap$colorK;
154
157
  const colorKey = d.group_name || d.group_name === 0 ? d.group_name : '';
155
158
  return (_this$colorMap$colorK = this.colorMap[colorKey]) !== null && _this$colorMap$colorK !== void 0 ? _this$colorMap$colorK : _constants.CHART_STYLE_COLORS[0];
@@ -112,7 +112,9 @@ class HorizontalBarStack extends _chartComponent.default {
112
112
 
113
113
  // X axis
114
114
  const niceEnd = d3.nice(0, d3.max(newSeries, d => d[1].sumValue), 5)[1];
115
- const x = d3.scaleLinear().domain(horizontal_axis_auto_range ? [0, niceEnd] : [horizontal_axis_min || 0, horizontal_axis_max || niceEnd]).range([Number(yAxis.node().getAttribute('data-axisWidth')), chartWidth - insertPadding]);
115
+ const xAxisRange = _utils.BaseUtils.getValueAxisRange(horizontal_axis_auto_range, horizontal_axis_min, horizontal_axis_max, [0, niceEnd]);
116
+ const x = d3.scaleLinear().domain(xAxisRange.domain).range([Number(yAxis.node().getAttribute('data-axisWidth')), chartWidth - insertPadding]);
117
+ const clampXValue = _utils.BaseUtils.getValueClamper(xAxisRange);
116
118
  this.chart.append('g').attr('class', 'x-axis-wrapper').attr('transform', `translate(0, ${chartHeight - insertPadding})`).call(d3.axisBottom(x).tickSizeInner(0).ticks(5).tickFormat(d => _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, d, horizontal_axis_summary_method))).call(g => {
117
119
  g.selectAll('.domain').remove();
118
120
  g.selectAll('.tick line').node() && g.selectAll('.tick line').node().remove(); // delete the first line
@@ -130,8 +132,8 @@ class HorizontalBarStack extends _chartComponent.default {
130
132
  d.forEach(item => item['groupKey'] = groupKey);
131
133
  return d;
132
134
  }).join('rect').attr('opacity', 1).attr('x', (d, index) => {
133
- return x(d[0]) - Number(yAxis.node().getAttribute('data-axisWidth'));
134
- }).attr('y', (d, index) => y(d.groupKey)).attr('width', d => x(d[1]) - x(d[0])).attr('height', y.bandwidth()).attr('fill', d => {
135
+ return x(clampXValue(d[0])) - Number(yAxis.node().getAttribute('data-axisWidth'));
136
+ }).attr('y', (d, index) => y(d.groupKey)).attr('width', d => x(clampXValue(d[1])) - x(clampXValue(d[0]))).attr('height', y.bandwidth()).attr('fill', d => {
135
137
  return this.colorMap[d.data.group_name] || _constants.CHART_STYLE_COLORS[0];
136
138
  }).attr('data-value', d => d.data.value).attr('data-groupName', d => d.data.name).attr('data-stackKey', d => d.key).call(g => {
137
139
  const allGroup = this.getAllGroup(contentWrapper);
@@ -99,7 +99,10 @@ class HorizontalBar extends _chartComponent.default {
99
99
  this.checkTickOverlap(g, 'yAxis');
100
100
  });
101
101
  const niceEnd = d3.nice(0, d3.max(data, d => d.value), 5)[1];
102
- const x = d3.scaleLinear().domain(horizontal_axis_auto_range ? [0, niceEnd] : [horizontal_axis_min || 0, horizontal_axis_max || niceEnd]).range([Number(yAxis.node().getAttribute('data-axisWidth')), chartWidth - insertPadding - marginRight]);
102
+ const xAxisRange = _utils.BaseUtils.getValueAxisRange(horizontal_axis_auto_range, horizontal_axis_min, horizontal_axis_max, [0, niceEnd]);
103
+ const x = d3.scaleLinear().domain(xAxisRange.domain).range([Number(yAxis.node().getAttribute('data-axisWidth')), chartWidth - insertPadding - marginRight]);
104
+ const xBaseline = xAxisRange.domain[0];
105
+ const clampXValue = _utils.BaseUtils.getValueClamper(xAxisRange);
103
106
 
104
107
  // X axis
105
108
  this.chart.append('g').attr('class', 'x-axis-wrapper').attr('transform', `translate(0, ${chartHeight - insertPadding})`).call(d3.axisBottom(x).tickSizeInner(0).ticks(5).tickFormat(d => _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, d, horizontal_axis_summary_method))).call(g => {
@@ -110,7 +113,7 @@ class HorizontalBar extends _chartComponent.default {
110
113
  g.selectAll('text').attr('fill', theme.textColor);
111
114
  });
112
115
  const contentWrapper = this.chart.append('g').attr('class', 'content-wrapper').attr('transform', `translate(${Number(yAxis.node().getAttribute('data-axisWidth'))}, 0)`);
113
- contentWrapper.selectAll().data(data).join('rect').attr('opacity', 1).attr('x', 0).attr('y', d => y(d.name)).attr('width', d => x(d.value) - x(0)).attr('height', y.bandwidth()).attr('fill', d => {
116
+ contentWrapper.selectAll().data(data).join('rect').attr('opacity', 1).attr('x', 0).attr('y', d => y(d.name)).attr('width', d => x(clampXValue(d.value)) - x(xBaseline)).attr('height', y.bandwidth()).attr('fill', d => {
114
117
  const color = (0, _colorUtils.getLabelColor)({
115
118
  chart: chart.config,
116
119
  colorRules,
@@ -165,7 +165,9 @@ class LineGroup extends _chartComponent.default {
165
165
 
166
166
  // Y axis
167
167
  const niceEnd = d3.nice(0, d3.max(data, d => d.value), 5)[1];
168
- const y = d3.scaleLinear().domain(y_axis_auto_range ? [0, niceEnd] : [y_axis_min || 0, y_axis_max || niceEnd]).range([chartHeight - insertPadding, insertPadding + marginTop]);
168
+ const yAxisRange = _utils.BaseUtils.getValueAxisRange(y_axis_auto_range, y_axis_min, y_axis_max, [0, niceEnd]);
169
+ const y = d3.scaleLinear().domain(yAxisRange.domain).range([chartHeight - insertPadding, insertPadding + marginTop]);
170
+ const clampYValue = _utils.BaseUtils.getValueClamper(yAxisRange);
169
171
  this.chart.append('g').attr('class', 'y-axis-wrapper').attr('transform', `translate(${insertPadding}, 0)`).call(d3.axisLeft(y).tickSizeInner(0).ticks(5).tickFormat(d => _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, d, y_axis_summary_method))).call(g => this.drawYaxis(g, theme));
170
172
 
171
173
  // X axis
@@ -193,7 +195,7 @@ class LineGroup extends _chartComponent.default {
193
195
  circleData[index]['originalData'] = d;
194
196
  return xVal;
195
197
  }).y((d, index) => {
196
- const yVal = y(d.value);
198
+ const yVal = y(clampYValue(d.value));
197
199
  circleData[index]['y'] = yVal;
198
200
  circleData[index]['value'] = d.value;
199
201
  return yVal;
@@ -269,7 +271,7 @@ class LineGroup extends _chartComponent.default {
269
271
  });
270
272
  });
271
273
  if (display_goal_line && goal_label && goal_value) {
272
- this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y);
274
+ this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y, yAxisRange.isManual);
273
275
  }
274
276
  this.setLegend({
275
277
  legendName: 'group_name',
@@ -149,7 +149,9 @@ class Line extends _chartComponent.default {
149
149
 
150
150
  // Y axis
151
151
  const niceEnd = d3.nice(0, d3.max(data, d => d.value), 5)[1];
152
- const y = d3.scaleLinear().domain(y_axis_auto_range ? [0, niceEnd] : [y_axis_min || 0, y_axis_max || niceEnd]).range([chartHeight - insertPadding, insertPadding + marginTop]);
152
+ const yAxisRange = _utils.BaseUtils.getValueAxisRange(y_axis_auto_range, y_axis_min, y_axis_max, [0, niceEnd]);
153
+ const y = d3.scaleLinear().domain(yAxisRange.domain).range([chartHeight - insertPadding, insertPadding + marginTop]);
154
+ const clampYValue = _utils.BaseUtils.getValueClamper(yAxisRange);
153
155
  this.chart.append('g').attr('class', 'y-axis-wrapper').attr('transform', `translate(${insertPadding}, 0)`).call(d3.axisLeft(y).tickSizeInner(0).ticks(5).tickFormat(d => _utils.BaseUtils.getSummaryValueDisplayString(summaryColumn, d, y_axis_summary_method))).call(g => this.drawYaxis(g, theme));
154
156
 
155
157
  // X axis
@@ -173,7 +175,7 @@ class Line extends _chartComponent.default {
173
175
  circleData[index]['originalData'] = d;
174
176
  return xVal;
175
177
  }).y((d, index) => {
176
- const yVal = y(d.value);
178
+ const yVal = y(clampYValue(d.value));
177
179
  circleData[index]['y'] = yVal;
178
180
  circleData[index]['value'] = d.value;
179
181
  return yVal;
@@ -230,7 +232,7 @@ class Line extends _chartComponent.default {
230
232
  });
231
233
  });
232
234
  if (display_goal_line && goal_label && goal_value) {
233
- this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y);
235
+ this.setDispalyGoalLine(goal_label, goal_value, insertPadding, y, yAxisRange.isManual);
234
236
  }
235
237
  };
236
238
  this.updateCircleAndTickStyle = _ref => {
@@ -207,7 +207,9 @@ class Scatter extends _chartComponent.default {
207
207
  const selectedYAxisColumn = (0, _dtableUtils.getTableColumnByKey)(selectedTable, y_axis_column_key);
208
208
 
209
209
  // Y axis
210
- const y = d3.scaleLinear().domain(y_axis_auto_range ? [0, d3.max(data, d => d.value)] : [y_axis_min, y_axis_max]).range([chartHeight - insertPadding - bottomLegendSpace, insertPadding + marginTop]);
210
+ const yAxisRange = _utils.BaseUtils.getValueAxisRange(y_axis_auto_range, y_axis_min, y_axis_max, [0, d3.max(data, d => d.value)]);
211
+ const y = d3.scaleLinear().domain(yAxisRange.domain).range([chartHeight - insertPadding - bottomLegendSpace, insertPadding + marginTop]);
212
+ const clampYValue = _utils.BaseUtils.getValueClamper(yAxisRange);
211
213
  this.chart.append('g').attr('class', 'y-axis-wrapper').attr('transform', `translate(${insertPadding}, 0)`).call(d3.axisLeft(y).tickSizeInner(0).ticks(5).tickFormat(d => d)).call(g => this.drawYaxis(g, theme));
212
214
 
213
215
  // X axis
@@ -237,7 +239,7 @@ class Scatter extends _chartComponent.default {
237
239
  return _utils.BaseUtils.getCurrentTheme(chartColorTheme).colors[0];
238
240
  }
239
241
  return colorMap[d.groupby];
240
- }).attr('data-x', d => x(d.name)).attr('data-y', d => y(d.value)).attr('data-value', d => d.value).attr('data-width', 3.5).attr('data-groupName', d => d.name).attr('cx', d => x(d.name)).attr('cy', d => y(d.value)).attr('r', 3.5).attr('opacity', 0.85).call(g => {
242
+ }).attr('data-x', d => x(d.name)).attr('data-y', d => y(clampYValue(d.value))).attr('data-value', d => d.value).attr('data-width', 3.5).attr('data-groupName', d => d.name).attr('cx', d => x(d.name)).attr('cy', d => y(clampYValue(d.value))).attr('r', 3.5).attr('opacity', 0.85).call(g => {
241
243
  g.nodes().forEach(path => {
242
244
  // Add label
243
245
  if (y_axis_show_value) {
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "sea-chart",
3
- "version": "2.0.60",
3
+ "version": "2.0.62",
4
4
  "main": "./dist/index.js",
5
5
  "dependencies": {
6
6
  "@dnd-kit/core": "^6.1.0",
7
7
  "@dnd-kit/modifiers": "^7.0.0",
8
8
  "@dnd-kit/sortable": "^8.0.0",
9
9
  "@dnd-kit/utilities": "^3.2.2",
10
- "@seafile/seafile-calendar": "^1.0.8",
10
+ "@seafile/seafile-calendar": "^1.0.33",
11
11
  "@seafile/seafile-editor": "^3.0.26",
12
12
  "axios": "^1.19.0",
13
13
  "classnames": "^2.3.2",