@longline/aqua-ui 1.0.225 → 1.0.227

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.
@@ -4,12 +4,12 @@ import { IGradientStop } from "../../Types";
4
4
  */
5
5
  declare class PresetGradients {
6
6
  /** Green gradient from light lime to dark teal */
7
- static readonly Green: readonly IGradientStop[];
7
+ static Green: IGradientStop[];
8
8
  /** Blue gradient from pale cyan to deep navy */
9
- static readonly Blue: readonly IGradientStop[];
9
+ static Blue: IGradientStop[];
10
10
  /** Red gradient from dark maroon to bright red */
11
- static readonly Red: readonly IGradientStop[];
11
+ static Red: IGradientStop[];
12
12
  /** Rainbow gradient from teal to yellow */
13
- static readonly Rainbow: readonly IGradientStop[];
13
+ static Rainbow: IGradientStop[];
14
14
  }
15
15
  export { PresetGradients };
@@ -1,15 +1,14 @@
1
1
  import * as React from 'react';
2
2
  import { Selector } from '../../../inputs/Selector';
3
3
  var Body = React.forwardRef(function (props, ref) {
4
- var _a;
5
4
  // The scrolling container's height is necessary to determine how many
6
5
  // rows must be rendered.
7
- var _b = React.useState(0), height = _b[0], setHeight = _b[1];
6
+ var _a = React.useState(0), height = _a[0], setHeight = _a[1];
8
7
  // Current container scrollTop. This is updated by polling it using
9
8
  // animation frames.
10
9
  var scrollTop = React.useRef(0);
11
10
  // This state is only used to trigger renders
12
- var _c = React.useState(0), setTick = _c[1];
11
+ var _b = React.useState(0), setTick = _b[1];
13
12
  // Watch resize of scrolling container using ResizeObserver.
14
13
  React.useEffect(function () {
15
14
  if (!props.container)
@@ -67,7 +66,6 @@ var Body = React.forwardRef(function (props, ref) {
67
66
  var getRows = function () {
68
67
  var rows = [];
69
68
  var _a = getOffsets(), startIndex = _a[0], endIndex = _a[1];
70
- var offset = startIndex * props.rowHeight;
71
69
  var _loop_1 = function (i) {
72
70
  var item = props.data[i];
73
71
  rows.push(React.createElement("div", { key: i,
@@ -77,9 +75,7 @@ var Body = React.forwardRef(function (props, ref) {
77
75
  props.active == item ? 'active' : null,
78
76
  props.expanded && props.active == item ? 'expanded' : null,
79
77
  (props.onClick || props.onDoubleClick) ? 'clickable' : null
80
- ].join(' '), style: {
81
- top: (props.expanded && props.active == item) ? "48px" : "".concat(offset, "px")
82
- }, onClick: props.onClick ? function () { return props.onClick(item); } : null, onDoubleClick: props.onDoubleClick ? function () { return props.onDoubleClick(item); } : null },
78
+ ].join(' '), onClick: props.onClick ? function () { return props.onClick(item); } : null, onDoubleClick: props.onDoubleClick ? function () { return props.onDoubleClick(item); } : null },
83
79
  props.onCheck && React.createElement("div", { className: "cell check" },
84
80
  React.createElement(Selector, { checked: !!item.checked, onChange: function () { return props.onCheck(i); } })),
85
81
  props.columns.map(function (col, index) {
@@ -93,25 +89,19 @@ var Body = React.forwardRef(function (props, ref) {
93
89
  }),
94
90
  props.columnsEditable && React.createElement("div", { className: "cell columns" })));
95
91
  if (props.expanded && props.active == item) {
96
- rows.push(React.createElement("div", { key: "".concat(i, "_expand") },
97
- React.createElement("div", { style: {
98
- position: "absolute",
99
- width: "100%",
100
- top: "".concat(offset + props.rowHeight, "px"),
101
- scrollMargin: "".concat(props.rowHeight * 2, "px")
102
- } }, props.expansion)));
103
- offset += props.rowHeight * 5;
92
+ rows.push(React.createElement("div", { key: "".concat(i, "_expand") }, props.expansion));
104
93
  }
105
- offset += props.rowHeight;
106
94
  };
107
95
  for (var i = startIndex; i <= endIndex; i++) {
108
96
  _loop_1(i);
109
97
  }
110
- return rows;
98
+ // Here we add an offset above the rows what were actually rendered:
99
+ var offset = startIndex * props.rowHeight;
100
+ return (React.createElement("div", { style: { position: "absolute", width: "100%", top: "".concat(offset, "px") } }, rows));
111
101
  };
112
102
  return (
113
103
  // Wrap the body in an element that is as tall as the number of items
114
104
  // in the list.
115
- React.createElement("div", { style: { position: 'relative', width: '100%', height: ((_a = props.data) === null || _a === void 0 ? void 0 : _a.length) * props.rowHeight } }, Array.isArray(props.data) && getRows()));
105
+ React.createElement("div", { style: { position: 'relative', width: '100%', height: (Array.isArray(props.data) ? props.data.length : 0) * props.rowHeight } }, Array.isArray(props.data) && getRows()));
116
106
  });
117
107
  export { Body };
@@ -60,7 +60,7 @@ var TableBase = function (_a) {
60
60
  options: {
61
61
  boundary: innerRef.current ? innerRef.current.getElement() : null,
62
62
  tether: false,
63
- padding: { top: HEADER_HEIGHT, bottom: 16 }
63
+ padding: { top: 0, bottom: 16 }
64
64
  }
65
65
  }
66
66
  ]
@@ -114,24 +114,25 @@ var TableBase = function (_a) {
114
114
  React.createElement(ColumnsManager, { columns: props.columns, onChange: props.onChangeColumns, onClose: props.onCloseColumns, onReset: props.onResetColumns })),
115
115
  showingNoData && React.createElement(NoData, { dark: props.dark, component: props.noData }),
116
116
  React.createElement(AuxHolder, __assign({ ref: auxRef, style: __assign({ visibility: (props.active && props.aux && Array.isArray(props.data) && props.data.includes(props.active)) ? 'visible' : 'hidden' }, styles.popper) }, attributes.popper), (props.active && props.aux && Array.isArray(props.data) && props.data.includes(props.active)) && React.cloneElement(props.aux, { value: props.active })),
117
- React.createElement(OverlayScrollbarsComponent, { ref: innerRef, defer: true, options: {
118
- scrollbars: { theme: 'os-theme-light', autoHide: 'leave' }
119
- }, style: {
120
- position: "absolute",
121
- left: 0,
122
- top: 0,
123
- right: 0,
124
- bottom: 0,
125
- overflowY: "auto",
126
- } },
127
- React.createElement("div", { className: className },
128
- props.noheader != true && React.createElement(Header, __assign({}, props, { columns: activeColumns, onOpenColumns: props.onOpenColumns })),
129
- React.createElement(Body, __assign({ ref: setActiveRef }, props, { columns: activeColumns, container: innerRef.current })))),
117
+ React.createElement("div", { className: className },
118
+ props.noheader != true && React.createElement(Header, __assign({}, props, { columns: activeColumns, onOpenColumns: props.onOpenColumns })),
119
+ React.createElement(OverlayScrollbarsComponent, { ref: innerRef, defer: true, options: {
120
+ scrollbars: { theme: 'os-theme-light', autoHide: 'leave' }
121
+ }, style: {
122
+ position: "absolute",
123
+ left: 0,
124
+ top: props.noheader ? 0 : "".concat(HEADER_HEIGHT, "px"),
125
+ right: 0,
126
+ bottom: 0,
127
+ overflowY: "auto",
128
+ } },
129
+ React.createElement("div", { className: "inner" },
130
+ React.createElement(Body, __assign({ ref: setActiveRef }, props, { columns: activeColumns, container: innerRef.current }))))),
130
131
  props.total && Array.isArray(props.data) && React.createElement(Total, { value: props.data.length, singular: props.singular, plural: props.plural })));
131
132
  };
132
133
  var AuxHolder = styled.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n z-index: 1;\n pointer-events: none;\n // Children must turn pointer-events back on.\n"], ["\n z-index: 1;\n pointer-events: none;\n // Children must turn pointer-events back on.\n"])));
133
134
  var Wrapper = styled.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n // Size and position. A table fills its container.\n position: relative;\n width: 100%;\n height: 100%;\n background-color: ", ";\n"], ["\n // Size and position. A table fills its container.\n position: relative;\n width: 100%;\n height: 100%;\n background-color: ", ";\n"])), function (p) { return p.$dark ? p.theme.colors.primary[3] : p.theme.colors.neutral[100]; });
134
- var TableStyled = styled(TableBase)(templateObject_10 || (templateObject_10 = __makeTemplateObject(["\n position: absolute;\n box-sizing: border-box;\n left: 0;\n top: 0;\n width: 100%;\n padding-bottom: 48px;\n\n // Appearance:\n font: ", ";\n color: ", ";\n background-color: ", ";\n\n .row {\n position: absolute;\n width: 100%;\n left: 0;\n right: 0;\n height: ", "px;\n display: flex;\n flex-direction: row;\n }\n .row.clickable {\n cursor: pointer;\n }\n\n // Optional row hover effect:\n ", "\n\n // Striped rows:\n ", "\n\n // General styles for cells:\n .cell {\n position: relative;\n box-sizing: border-box;\n white-space: nowrap;\n text-align: left;\n user-select: none;\n outline: none;\n padding-left: 16px;\n padding-right: 16px; \n min-width: 0; \n\n // use flexbox to vertical-align content:\n display: flex;\n align-items: center;\n justify-content: left;\n\n // Underline.\n &:after {\n content: '';\n position: absolute;\n left: 0;\n bottom: 0;\n right: 0;\n height: 1px;\n transition: background-color ", "ms ease-in-out;\n } \n }\n\n // Cell widths:\n ", "\n\n .cell.check {\n width: 48px;\n }\n\n .cell.columns {\n width: 48px;\n }\n\n .header {\n // Position and size:\n position: sticky;\n top: 0;\n z-index: 100;\n height: ", "px;\n }\n\n .header .cell {\n gap: 8px;\n justify-content: space-between;\n // Appearance\n background: ", ";\n &.sort {\n background: ", ";\n }\n &:after { \n background-color: ", "; \n }\n // Header shadow:\n ", "\n }\n // cell bottom border color:\n .cell {\n &:after {\n background-color: ", ";\n } \n }\n // Active row cells:\n .row.active .cell {\n background-color: ", ";\n }\n // Last column has double right margin:\n .cell:last-child {\n padding-right: 32px;\n }\n // Last row has no bottom border:\n .row:last-child .cell {\n &:after {\n visibility: hidden;\n } \n }\n // Spans in cells are ellipsized:\n .cell > span {\n width: 100%;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n }\n\n // Grid:\n ", "\n\n // If onColumns is present, remove last column header's hover underline:\n // Also remove last gridline.\n ", "\n\n // Expanded row makes its cells sticky:\n .row.expanded {\n position: sticky;\n top: ", "px;\n \n z-index: 100;\n }\n"], ["\n position: absolute;\n box-sizing: border-box;\n left: 0;\n top: 0;\n width: 100%;\n padding-bottom: 48px;\n\n // Appearance:\n font: ", ";\n color: ", ";\n background-color: ", ";\n\n .row {\n position: absolute;\n width: 100%;\n left: 0;\n right: 0;\n height: ", "px;\n display: flex;\n flex-direction: row;\n }\n .row.clickable {\n cursor: pointer;\n }\n\n // Optional row hover effect:\n ", "\n\n // Striped rows:\n ", "\n\n // General styles for cells:\n .cell {\n position: relative;\n box-sizing: border-box;\n white-space: nowrap;\n text-align: left;\n user-select: none;\n outline: none;\n padding-left: 16px;\n padding-right: 16px; \n min-width: 0; \n\n // use flexbox to vertical-align content:\n display: flex;\n align-items: center;\n justify-content: left;\n\n // Underline.\n &:after {\n content: '';\n position: absolute;\n left: 0;\n bottom: 0;\n right: 0;\n height: 1px;\n transition: background-color ", "ms ease-in-out;\n } \n }\n\n // Cell widths:\n ", "\n\n .cell.check {\n width: 48px;\n }\n\n .cell.columns {\n width: 48px;\n }\n\n .header {\n // Position and size:\n position: sticky;\n top: 0;\n z-index: 100;\n height: ", "px;\n }\n\n .header .cell {\n gap: 8px;\n justify-content: space-between;\n // Appearance\n background: ", ";\n &.sort {\n background: ", ";\n }\n &:after { \n background-color: ", "; \n }\n // Header shadow:\n ", "\n }\n // cell bottom border color:\n .cell {\n &:after {\n background-color: ", ";\n } \n }\n // Active row cells:\n .row.active .cell {\n background-color: ", ";\n }\n // Last column has double right margin:\n .cell:last-child {\n padding-right: 32px;\n }\n // Last row has no bottom border:\n .row:last-child .cell {\n &:after {\n visibility: hidden;\n } \n }\n // Spans in cells are ellipsized:\n .cell > span {\n width: 100%;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n }\n\n // Grid:\n ", "\n\n // If onColumns is present, remove last column header's hover underline:\n // Also remove last gridline.\n ", "\n\n // Expanded row makes its cells sticky:\n .row.expanded {\n position: sticky;\n top: ", "px;\n \n z-index: 100;\n }\n"])), function (p) { return p.theme.font.bodyMedium; }, function (p) { return p.dark ? p.theme.colors.neutral[100] : p.theme.colors.neutral[10]; }, function (p) { return p.dark ? p.theme.colors.primary[3] : p.theme.colors.neutral[100]; }, function (p) { return p.rowHeight; }, function (p) { return p.hover && css(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n .row:hover .cell { background-color: ", "; }\n "], ["\n .row:hover .cell { background-color: ", "; }\n "])), p.dark ? p.theme.colors.primary[4] : p.theme.colors.neutral[95]); }, function (p) { return p.striped && css(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n .row:nth-child(2n+2) .cell {\n background-color: ", ";\n }\n "], ["\n .row:nth-child(2n+2) .cell {\n background-color: ", ";\n }\n "])), darken(0.02, p.dark ? p.theme.colors.primary[3] : p.theme.colors.neutral[100])); }, function (p) { return p.theme.animation.duration; }, function (p) { return p.columns.filter(function (c) { return c.active; }).map(function (c, i) {
135
+ var TableStyled = styled(TableBase)(templateObject_10 || (templateObject_10 = __makeTemplateObject(["\n .inner {\n position: absolute;\n box-sizing: border-box;\n left: 0;\n top: 0;\n width: 100%;\n padding-bottom: 48px;\n }\n\n // Appearance:\n font: ", ";\n color: ", ";\n background-color: ", ";\n\n .row {\n width: 100%;\n height: ", "px;\n display: flex;\n flex-direction: row;\n }\n .row.clickable {\n cursor: pointer;\n }\n\n // Optional row hover effect:\n ", "\n\n // Striped rows:\n ", "\n\n // General styles for cells:\n .cell {\n position: relative;\n box-sizing: border-box;\n white-space: nowrap;\n text-align: left;\n user-select: none;\n outline: none;\n padding-left: 16px;\n padding-right: 16px; \n min-width: 0; \n\n // use flexbox to vertical-align content:\n display: flex;\n align-items: center;\n justify-content: left;\n\n // Underline.\n &:after {\n content: '';\n position: absolute;\n left: 0;\n bottom: 0;\n right: 0;\n height: 1px;\n transition: background-color ", "ms ease-in-out;\n } \n }\n\n // Cell widths:\n ", "\n\n .cell.check {\n width: 48px;\n }\n\n .cell.columns {\n width: 48px;\n }\n\n .header {\n // Position and size:\n position: absolute;\n top: 0;\n z-index: 200;\n height: ", "px;\n }\n\n .header .cell {\n gap: 8px;\n justify-content: space-between;\n // Appearance\n background: ", ";\n &.sort {\n background: ", ";\n }\n &:after { \n background-color: ", "; \n }\n // Header shadow:\n ", "\n }\n // cell bottom border color:\n .cell {\n &:after {\n background-color: ", ";\n } \n }\n // Active row cells:\n .row.active .cell {\n background-color: ", ";\n }\n // Last column has double right margin:\n .cell:last-child {\n padding-right: 32px;\n }\n // Last row has no bottom border:\n .row:last-child .cell {\n &:after {\n visibility: hidden;\n } \n }\n // Spans in cells are ellipsized:\n .cell > span {\n width: 100%;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n }\n\n // Grid:\n ", "\n\n // If onColumns is present, remove last column header's hover underline:\n // Also remove last gridline.\n ", "\n\n // Expanded row makes its cells sticky:\n .row.expanded {\n position: sticky;\n top: 0;\n z-index: 100;\n }\n"], ["\n .inner {\n position: absolute;\n box-sizing: border-box;\n left: 0;\n top: 0;\n width: 100%;\n padding-bottom: 48px;\n }\n\n // Appearance:\n font: ", ";\n color: ", ";\n background-color: ", ";\n\n .row {\n width: 100%;\n height: ", "px;\n display: flex;\n flex-direction: row;\n }\n .row.clickable {\n cursor: pointer;\n }\n\n // Optional row hover effect:\n ", "\n\n // Striped rows:\n ", "\n\n // General styles for cells:\n .cell {\n position: relative;\n box-sizing: border-box;\n white-space: nowrap;\n text-align: left;\n user-select: none;\n outline: none;\n padding-left: 16px;\n padding-right: 16px; \n min-width: 0; \n\n // use flexbox to vertical-align content:\n display: flex;\n align-items: center;\n justify-content: left;\n\n // Underline.\n &:after {\n content: '';\n position: absolute;\n left: 0;\n bottom: 0;\n right: 0;\n height: 1px;\n transition: background-color ", "ms ease-in-out;\n } \n }\n\n // Cell widths:\n ", "\n\n .cell.check {\n width: 48px;\n }\n\n .cell.columns {\n width: 48px;\n }\n\n .header {\n // Position and size:\n position: absolute;\n top: 0;\n z-index: 200;\n height: ", "px;\n }\n\n .header .cell {\n gap: 8px;\n justify-content: space-between;\n // Appearance\n background: ", ";\n &.sort {\n background: ", ";\n }\n &:after { \n background-color: ", "; \n }\n // Header shadow:\n ", "\n }\n // cell bottom border color:\n .cell {\n &:after {\n background-color: ", ";\n } \n }\n // Active row cells:\n .row.active .cell {\n background-color: ", ";\n }\n // Last column has double right margin:\n .cell:last-child {\n padding-right: 32px;\n }\n // Last row has no bottom border:\n .row:last-child .cell {\n &:after {\n visibility: hidden;\n } \n }\n // Spans in cells are ellipsized:\n .cell > span {\n width: 100%;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n }\n\n // Grid:\n ", "\n\n // If onColumns is present, remove last column header's hover underline:\n // Also remove last gridline.\n ", "\n\n // Expanded row makes its cells sticky:\n .row.expanded {\n position: sticky;\n top: 0;\n z-index: 100;\n }\n"])), function (p) { return p.theme.font.bodyMedium; }, function (p) { return p.dark ? p.theme.colors.neutral[100] : p.theme.colors.neutral[10]; }, function (p) { return p.dark ? p.theme.colors.primary[3] : p.theme.colors.neutral[100]; }, function (p) { return p.rowHeight; }, function (p) { return p.hover && css(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n .row:hover .cell { background-color: ", "; }\n "], ["\n .row:hover .cell { background-color: ", "; }\n "])), p.dark ? p.theme.colors.primary[4] : p.theme.colors.neutral[95]); }, function (p) { return p.striped && css(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n .row:nth-child(2n+2) .cell {\n background-color: ", ";\n }\n "], ["\n .row:nth-child(2n+2) .cell {\n background-color: ", ";\n }\n "])), darken(0.02, p.dark ? p.theme.colors.primary[3] : p.theme.colors.neutral[100])); }, function (p) { return p.theme.animation.duration; }, function (p) { return p.columns.filter(function (c) { return c.active; }).map(function (c, i) {
135
136
  var _a;
136
137
  var width_definition = (_a = c.width) !== null && _a !== void 0 ? _a : 1;
137
138
  var cellIndex = p.onCheck ? i + 2 : i + 1;
@@ -141,7 +142,7 @@ var TableStyled = styled(TableBase)(templateObject_10 || (templateObject_10 = __
141
142
  else {
142
143
  return css(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n .cell:nth-child(", ") {\n width: ", ";\n }\n "], ["\n .cell:nth-child(", ") {\n width: ", ";\n }\n "])), cellIndex, width_definition);
143
144
  }
144
- }); }, HEADER_HEIGHT, function (p) { return p.dark ? p.theme.colors.primary[5] : p.theme.colors.neutral[100]; }, function (p) { return p.dark ? p.theme.colors.neutral[10] : p.theme.colors.neutral[95]; }, function (p) { return p.dark ? p.theme.colors.primary[2] : p.theme.colors.neutral[80]; }, function (p) { return p.shadow && css(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n &:before {\n position: absolute;\n pointer-events: none;\n content: '';\n z-index: 1;\n top: calc(100%);\n left: 0;\n right: 0;\n height: 8px;\n background: linear-gradient(rgba(0,0,0,0.1), transparent);\n }\n "], ["\n &:before {\n position: absolute;\n pointer-events: none;\n content: '';\n z-index: 1;\n top: calc(100%);\n left: 0;\n right: 0;\n height: 8px;\n background: linear-gradient(rgba(0,0,0,0.1), transparent);\n }\n "]))); }, function (p) { return p.dark ? p.theme.colors.primary[2] : p.theme.colors.neutral[80]; }, function (p) { var _a; return (_a = p.activeColor) !== null && _a !== void 0 ? _a : p.theme.colors.primary[1]; }, function (p) { return p.grid && css(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n .cell:not(:last-child) {\n border-right: dashed 1px ", ";\n }\n "], ["\n .cell:not(:last-child) {\n border-right: dashed 1px ", ";\n }\n "])), p.dark ? p.theme.colors.primary[2] : p.theme.colors.neutral[80]); }, function (p) { return p.columnsEditable && css(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n .header .cell:last-child {\n &:hover {\n &:after { \n background-color: ", ";\n }\n }\n }\n .cell:nth-last-child(2) {\n border-right: none;\n }\n "], ["\n .header .cell:last-child {\n &:hover {\n &:after { \n background-color: ", ";\n }\n }\n }\n .cell:nth-last-child(2) {\n border-right: none;\n }\n "])), function (p) { return p.theme.colors.primary[2]; }); }, HEADER_HEIGHT);
145
+ }); }, HEADER_HEIGHT, function (p) { return p.dark ? p.theme.colors.primary[5] : p.theme.colors.neutral[100]; }, function (p) { return p.dark ? p.theme.colors.neutral[10] : p.theme.colors.neutral[95]; }, function (p) { return p.dark ? p.theme.colors.primary[2] : p.theme.colors.neutral[80]; }, function (p) { return p.shadow && css(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n &:before {\n position: absolute;\n pointer-events: none;\n content: '';\n z-index: 1;\n top: calc(100%);\n left: 0;\n right: 0;\n height: 8px;\n background: linear-gradient(rgba(0,0,0,0.1), transparent);\n }\n "], ["\n &:before {\n position: absolute;\n pointer-events: none;\n content: '';\n z-index: 1;\n top: calc(100%);\n left: 0;\n right: 0;\n height: 8px;\n background: linear-gradient(rgba(0,0,0,0.1), transparent);\n }\n "]))); }, function (p) { return p.dark ? p.theme.colors.primary[2] : p.theme.colors.neutral[80]; }, function (p) { var _a; return (_a = p.activeColor) !== null && _a !== void 0 ? _a : p.theme.colors.primary[1]; }, function (p) { return p.grid && css(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n .cell:not(:last-child) {\n border-right: dashed 1px ", ";\n }\n "], ["\n .cell:not(:last-child) {\n border-right: dashed 1px ", ";\n }\n "])), p.dark ? p.theme.colors.primary[2] : p.theme.colors.neutral[80]); }, function (p) { return p.columnsEditable && css(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n .header .cell:last-child {\n &:hover {\n &:after { \n background-color: ", ";\n }\n }\n }\n .cell:nth-last-child(2) {\n border-right: none;\n }\n "], ["\n .header .cell:last-child {\n &:hover {\n &:after { \n background-color: ", ";\n }\n }\n }\n .cell:nth-last-child(2) {\n border-right: none;\n }\n "])), function (p) { return p.theme.colors.primary[2]; }); });
145
146
  var Table = function (props) { return React.createElement(TableStyled, __assign({}, props)); };
146
147
  Table.displayName = "Table";
147
148
  export { Table };
@@ -0,0 +1,2 @@
1
+ declare const FragmentShader = " \n #ifdef GL_ES\n precision mediump float;\n #endif\n\n // Varyings from vertex shader\n varying vec2 v_pos; // station center in Mercator [0..1]\n varying float v_radius; // quad radius in Mercator units\n\n void main() {\n // Simply color every fragment of the quad red\n gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n }\n";
2
+ export { FragmentShader };
@@ -0,0 +1,2 @@
1
+ var FragmentShader = /*glsl*/ " \n #ifdef GL_ES\n precision mediump float;\n #endif\n\n // Varyings from vertex shader\n varying vec2 v_pos; // station center in Mercator [0..1]\n varying float v_radius; // quad radius in Mercator units\n\n void main() {\n // Simply color every fragment of the quad red\n gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n }\n";
2
+ export { FragmentShader };
@@ -0,0 +1,47 @@
1
+ import * as React from 'react';
2
+ import { IGradientStop } from '../../../Types';
3
+ interface IPoint {
4
+ latitude: number;
5
+ longitude: number;
6
+ value: number;
7
+ }
8
+ interface IIdwBlendLayerProps {
9
+ /**
10
+ * Input data.
11
+ */
12
+ data: IPoint[];
13
+ /**
14
+ * Gradient stops. A default gradient is preset.
15
+ */
16
+ gradientStops?: IGradientStop[];
17
+ /**
18
+ * Minimum zoom level at which to render layer.
19
+ * @default 0
20
+ */
21
+ minZoom?: number;
22
+ /**
23
+ * Maximum zoom level at which to render layer.
24
+ * @default 99
25
+ */
26
+ maxZoom?: number;
27
+ /**
28
+ * Maximum world distance (in -1..1 coordinate) system away from
29
+ * all stations where a pixel is still drawn.
30
+ * @default 0.0002
31
+ */
32
+ maxDistance?: number;
33
+ /**
34
+ * Thickness of fading edge of blob (value 0..1)
35
+ * @default 0.15
36
+ */
37
+ fadeFraction?: number;
38
+ }
39
+ /**
40
+ * An `IdwLayer` takes a data array of the form `{ latitude, longitude, value }`,
41
+ * and renders a colored surface using inverse distance weighting.
42
+ */
43
+ declare const IdwBlendLayer: {
44
+ ({ gradientStops, minZoom, maxZoom, maxDistance, fadeFraction, ...props }: IIdwBlendLayerProps): React.JSX.Element;
45
+ displayName: string;
46
+ };
47
+ export { IdwBlendLayer };
@@ -0,0 +1,129 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __rest = (this && this.__rest) || function (s, e) {
13
+ var t = {};
14
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
15
+ t[p] = s[p];
16
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
17
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
18
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
19
+ t[p[i]] = s[p[i]];
20
+ }
21
+ return t;
22
+ };
23
+ import * as React from 'react';
24
+ import { Layer, useMap } from 'react-map-gl/mapbox';
25
+ import { MercatorCoordinate } from 'mapbox-gl';
26
+ import { VertexShader } from './VertexShader';
27
+ import { FragmentShader } from './FragmentShader';
28
+ import { RgbColor } from '../../../helper/RgbColor';
29
+ import { PresetGradients } from '../../../controls/Gradient';
30
+ var IdwBlendLayerBase = function (props) {
31
+ var map = useMap();
32
+ var discProgram = React.useRef(null);
33
+ var discBuffer = React.useRef(null);
34
+ var texture = React.useRef(null);
35
+ var textureWidth = React.useRef(null);
36
+ var textureHeight = React.useRef(null);
37
+ var _a = React.useState(0), time = _a[0], setTime = _a[1];
38
+ // When properties change, make sure that layer is redrawn.
39
+ // Do this by varying its `key` with the current time.
40
+ React.useEffect(function () {
41
+ setTime(Date.now());
42
+ }, [props.data, props.gradientStops]);
43
+ //
44
+ // Convert a hex color (e.g. #ff0022) to an [r,g,b,a] array,
45
+ // where r,g,b,a are in the 0.0-1.0 range.
46
+ //
47
+ var colorToRGBA = function (color) {
48
+ var rgb = RgbColor.FromString(color);
49
+ return [rgb.red / 255.0, rgb.green / 255.0, rgb.blue / 255.0, rgb.alpha];
50
+ };
51
+ var createPointsBuffer = function (gl, points) {
52
+ var offsets = [
53
+ [-1, -1],
54
+ [1, -1],
55
+ [-1, 1],
56
+ [1, 1],
57
+ ];
58
+ // Flatten into Float32Array
59
+ var vertexData = [];
60
+ points.forEach(function (p) {
61
+ var _a = MercatorCoordinate.fromLngLat([p.longitude, p.latitude]), x = _a.x, y = _a.y;
62
+ offsets.forEach(function (_a) {
63
+ var ox = _a[0], oy = _a[1];
64
+ vertexData.push(x, y, p.value, ox, oy);
65
+ });
66
+ });
67
+ // Create buffer
68
+ var buffer = gl.createBuffer();
69
+ if (!buffer)
70
+ throw new Error("Failed to create WebGL buffer");
71
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
72
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW);
73
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
74
+ return buffer;
75
+ };
76
+ var onAddLayer = function (map, gl) {
77
+ // AddLayer is only called once.
78
+ // create a vertex shader
79
+ var vertexShader = gl.createShader(gl.VERTEX_SHADER);
80
+ gl.shaderSource(vertexShader, VertexShader);
81
+ gl.compileShader(vertexShader);
82
+ // create a fragment shader
83
+ var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
84
+ gl.shaderSource(fragmentShader, FragmentShader);
85
+ gl.compileShader(fragmentShader);
86
+ // link the two shaders into a WebGL program
87
+ discProgram.current = gl.createProgram();
88
+ gl.attachShader(discProgram.current, vertexShader);
89
+ gl.attachShader(discProgram.current, fragmentShader);
90
+ gl.linkProgram(discProgram.current);
91
+ // Create buffer from vertices:
92
+ discBuffer.current = createPointsBuffer(gl, props.data);
93
+ };
94
+ var onRender = function (gl, matrix, zoom, width, height) {
95
+ // Render is called many times while the map is panned/zoomed.
96
+ // You cannot have access to the map though.
97
+ if (zoom < props.minZoom)
98
+ return;
99
+ if (zoom > props.maxZoom)
100
+ return;
101
+ // Render is called many times while the map is panned/zoomed.
102
+ // You cannot have access to the map though.
103
+ gl.useProgram(discProgram.current);
104
+ // Pass a matrix uniform in:
105
+ gl.uniformMatrix4fv(gl.getUniformLocation(discProgram.current, 'u_matrix'), false, matrix);
106
+ gl.uniform1f(gl.getUniformLocation(discProgram.current, "u_radius"), 0.0001);
107
+ var aPos = gl.getAttribLocation(discProgram.current, 'a_pos');
108
+ var aOffset = gl.getAttribLocation(discProgram.current, 'a_offset');
109
+ gl.bindBuffer(gl.ARRAY_BUFFER, discBuffer.current);
110
+ gl.enableVertexAttribArray(aPos);
111
+ gl.vertexAttribPointer(aPos, 3, gl.FLOAT, false, 5 * 4, 0);
112
+ gl.enableVertexAttribArray(aOffset);
113
+ gl.vertexAttribPointer(aOffset, 2, gl.FLOAT, false, 5 * 4, 3 * 4);
114
+ //gl.enable(gl.BLEND);
115
+ //gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
116
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, props.data.length * 4);
117
+ };
118
+ return (React.createElement(Layer, { id: null, type: "custom", beforeId: "overlay", key: time, onAdd: onAddLayer, render: function (gl, matrix) { return onRender(gl, matrix, map.current.getZoom(), map.current.getContainer().clientWidth, map.current.getContainer().clientHeight); } }));
119
+ };
120
+ /**
121
+ * An `IdwLayer` takes a data array of the form `{ latitude, longitude, value }`,
122
+ * and renders a colored surface using inverse distance weighting.
123
+ */
124
+ var IdwBlendLayer = function (_a) {
125
+ var _b = _a.gradientStops, gradientStops = _b === void 0 ? PresetGradients.Blue : _b, _c = _a.minZoom, minZoom = _c === void 0 ? 0 : _c, _d = _a.maxZoom, maxZoom = _d === void 0 ? 99 : _d, _e = _a.maxDistance, maxDistance = _e === void 0 ? 0.0002 : _e, _f = _a.fadeFraction, fadeFraction = _f === void 0 ? 0.15 : _f, props = __rest(_a, ["gradientStops", "minZoom", "maxZoom", "maxDistance", "fadeFraction"]);
126
+ return React.createElement(IdwBlendLayerBase, __assign({ gradientStops: gradientStops, minZoom: minZoom, maxZoom: maxZoom, maxDistance: maxDistance, fadeFraction: fadeFraction }, props));
127
+ };
128
+ IdwBlendLayer.displayName = 'IdwBlendLayer';
129
+ export { IdwBlendLayer };
@@ -0,0 +1,2 @@
1
+ declare const VertexShader = " \n// Attributes\nattribute vec2 a_offset; // quad corner: [-1,-1], [1,-1], [-1,1], [1,1]\nattribute vec2 a_pos; // point position in Mercator [0..1]\n\n// Uniforms\nuniform mat4 u_matrix; // Mapbox projection matrix\nuniform float u_radius; // radius in Mercator units (e.g., 1 km converted)\n \n// Varyings\nvarying vec2 v_pos; // pass to fragment shader\nvarying float v_radius;\n\nvoid main() {\n // Offset the quad corner by radius in world coordinates\n vec2 offset = a_offset * u_radius;\n vec2 pos = a_pos + offset;\n\n // Pass station position & radius to fragment shader\n v_pos = a_pos;\n v_radius = u_radius;\n\n // Transform to clip space\n gl_Position = u_matrix * vec4(pos, 0.0, 1.0);\n}\n";
2
+ export { VertexShader };
@@ -0,0 +1,2 @@
1
+ var VertexShader = /*glsl*/ " \n// Attributes\nattribute vec2 a_offset; // quad corner: [-1,-1], [1,-1], [-1,1], [1,1]\nattribute vec2 a_pos; // point position in Mercator [0..1]\n\n// Uniforms\nuniform mat4 u_matrix; // Mapbox projection matrix\nuniform float u_radius; // radius in Mercator units (e.g., 1 km converted)\n \n// Varyings\nvarying vec2 v_pos; // pass to fragment shader\nvarying float v_radius;\n\nvoid main() {\n // Offset the quad corner by radius in world coordinates\n vec2 offset = a_offset * u_radius;\n vec2 pos = a_pos + offset;\n\n // Pass station position & radius to fragment shader\n v_pos = a_pos;\n v_radius = u_radius;\n\n // Transform to clip space\n gl_Position = u_matrix * vec4(pos, 0.0, 1.0);\n}\n";
2
+ export { VertexShader };
@@ -0,0 +1,2 @@
1
+ declare const CopyFragmentShader = " \n #ifdef GL_ES\n precision mediump float;\n #endif\n\n varying vec2 v_pos;\n uniform sampler2D u_src;\n void main() {\n vec4 c = texture2D(u_src, v_pos);\n // pass color as-is\n gl_FragColor = c;\n }\n";
2
+ export { CopyFragmentShader };
@@ -0,0 +1,2 @@
1
+ var CopyFragmentShader = /*glsl*/ " \n #ifdef GL_ES\n precision mediump float;\n #endif\n\n varying vec2 v_pos;\n uniform sampler2D u_src;\n void main() {\n vec4 c = texture2D(u_src, v_pos);\n // pass color as-is\n gl_FragColor = c;\n }\n";
2
+ export { CopyFragmentShader };
@@ -0,0 +1,2 @@
1
+ declare const CopyVertexShader = " \n uniform mat4 u_matrix;\n attribute vec2 a_pos;\n\n varying vec2 v_pos;\n\n void main() {\n gl_Position = vec4(a_pos.x * 2.0 - 1.0, a_pos.y * 2.0 - 1.0, 0.0, 1.0);\n v_pos = a_pos.xy;\n }\n";
2
+ export { CopyVertexShader };
@@ -0,0 +1,2 @@
1
+ var CopyVertexShader = /*glsl*/ " \n uniform mat4 u_matrix;\n attribute vec2 a_pos;\n\n varying vec2 v_pos;\n\n void main() {\n gl_Position = vec4(a_pos.x * 2.0 - 1.0, a_pos.y * 2.0 - 1.0, 0.0, 1.0);\n v_pos = a_pos.xy;\n }\n";
2
+ export { CopyVertexShader };
@@ -0,0 +1,2 @@
1
+ declare const IdwFragmentShader = " \n #ifdef GL_ES\n precision mediump float;\n #endif\n\n uniform sampler2D u_dataTexture;\n uniform vec2 u_dataTextureSize;\n uniform int u_numStations;\n varying vec2 v_pos;\n uniform float u_gradientStops[12];\n uniform vec4 u_gradientColors[12];\n uniform float u_maxDistance;\n uniform float u_fadeFraction;\n\n //\n // Given a value, find its corresponding color in the gradient stops.\n //\n vec4 getGradientColor(float position) {\n // Find left and right stop:\n float left = -1.0;\n float right = 99.0;\n vec4 leftColor;\n vec4 rightColor;\n\n for(int i = 0; i < 12; i++) {\n if (u_gradientStops[i] <= position) {\n left = u_gradientStops[i]; \n leftColor = u_gradientColors[i];\n } else break;\n }\n\n for(int i = 12 - 1; i >= 0; i--) {\n if (u_gradientStops[i] >= position) {\n right = u_gradientStops[i]; \n rightColor = u_gradientColors[i];\n } else break;\n }\n\n // Distance between stops:\n float width = right - left;\n // Distance from left stop:\n float dist = position - left;\n // Right stop weight:\n float weight;\n if(dist == 0.0) {\n weight = dist;\n } else {\n weight = dist / width;\n }\n\n float r = leftColor.x + (rightColor.x - leftColor.x) * weight;\n float g = leftColor.y + (rightColor.y - leftColor.y) * weight;\n float b = leftColor.z + (rightColor.z - leftColor.z) * weight;\n float a = leftColor.w + (rightColor.w - leftColor.w) * weight;\n return vec4(r, g, b, a); \n } \n\n // GLSL ES 1.00 compatible\n // rgba: vec4 from texture2D (values in [0..1])\n float decodeFloatRGBA(vec4 rgba) {\n // convert to 0..255 and round\n vec4 b = floor(rgba * 255.0 + 0.5);\n\n float b0 = b.r;\n float b1 = b.g;\n float b2 = b.b;\n float b3 = b.a;\n\n // sign: top bit of b3\n float sign = (b3 >= 128.0) ? -1.0 : 1.0;\n\n // exponent: 8 bits where lowest bit comes from b2's top bit\n float exp_low = floor(b2 / 128.0); // 0 or 1\n float exp_high = mod(b3, 128.0); // bits 1..7 of exponent as 0..127\n float exponent = exp_high * 2.0 + exp_low; // full 0..255\n\n // mantissa: 23 bits from b0,b1 and lower 7 bits of b2\n float mantissa = b0 + b1 * 256.0 + mod(b2, 128.0) * 65536.0;\n\n // handle special cases\n if (exponent == 0.0) {\n // zero or subnormal\n if (mantissa == 0.0) {\n return 0.0;\n } else {\n // subnormal numbers: (-1)^s * (mantissa / 2^23) * 2^-126\n return sign * (mantissa / 8388608.0) * exp2(-126.0);\n }\n } else if (exponent == 255.0) {\n // Inf or NaN -- return a large value for Inf, and 0 for NaN\n if (mantissa == 0.0) {\n return sign * 3.402823466e38; // approx FLT_MAX\n } else {\n return 0.0; // NaN -> 0 (or handle as you prefer)\n }\n } else {\n // normalized number: (-1)^s * (1 + mantissa/2^23) * 2^(exponent-127)\n float m = 1.0 + mantissa / 8388608.0;\n return sign * m * exp2(exponent - 127.0);\n }\n } \n\n vec2 texCoordForIndex(float idx, vec2 texSize) {\n float x = mod(idx, texSize.x);\n float y = floor(idx / texSize.x);\n return (vec2(x + 0.5, y + 0.5) / texSize);\n }\n\n // read triple of pixels: idx*3 + 0,1,2\n vec3 getPoint(int index) {\n float base = float(index) * 3.0;\n vec4 c0 = texture2D(u_dataTexture, texCoordForIndex(base + 0.0, u_dataTextureSize)); // x (mercator)\n vec4 c1 = texture2D(u_dataTexture, texCoordForIndex(base + 1.0, u_dataTextureSize)); // y (mercator)\n vec4 c2 = texture2D(u_dataTexture, texCoordForIndex(base + 2.0, u_dataTextureSize)); // value\n float mx = decodeFloatRGBA(c0);\n float my = decodeFloatRGBA(c1);\n float val = decodeFloatRGBA(c2);\n return vec3(mx, my, val);\n }\n\n void main() {\n float num = 0.0;\n float denom = 0.0;\n float power = 3.0; // IDW power\n float minDist = 1e9;\n\n for (int i = 0; i < 1024; i++) { // 1024 is a safe upper bound\n if (i >= u_numStations) break;\n vec3 station = getPoint(i);\n float dx = v_pos.x - station.x;\n float dy = v_pos.y - station.y;\n float d = sqrt(dx*dx + dy*dy);\n minDist = min(minDist, d);\n\n if (d < 1e-6) {\n // Exact match: use station value directly\n num = station.z;\n denom = 1.0;\n // stop looping, we\u2019re done\n break;\n }\n\n float w = 1.0 / pow(d, power);\n num += w * station.z;\n denom += w;\n }\n\n if (minDist > u_maxDistance) {\n // Too far from any station \u2192 discard pixel (transparent)\n discard;\n } \n\n float value = num / denom;\n\n // Normalize value between 0 and 1\n //float minVal = 0.0; // pass as uniform if needed\n //float maxVal = 1.0;\n //float norm = clamp((value - minVal) / (maxVal - minVal), 0.0, 1.0);\n\n // --- FADE TO TRANSPARENT ---\n float u_fadeDistance = u_maxDistance * u_fadeFraction;\n float alpha = 1.0;\n if (minDist > u_maxDistance - u_fadeDistance) {\n // fade linearly from 1 \u2192 0\n alpha = (u_maxDistance - minDist) / u_fadeDistance;\n alpha = clamp(alpha, 0.0, 1.0);\n }\n\n gl_FragColor = vec4(vec3(getGradientColor(1.0 - value)), alpha);\n }\n\n";
2
+ export { IdwFragmentShader };
@@ -0,0 +1,2 @@
1
+ var IdwFragmentShader = /*glsl*/ " \n #ifdef GL_ES\n precision mediump float;\n #endif\n\n uniform sampler2D u_dataTexture;\n uniform vec2 u_dataTextureSize;\n uniform int u_numStations;\n varying vec2 v_pos;\n uniform float u_gradientStops[12];\n uniform vec4 u_gradientColors[12];\n uniform float u_maxDistance;\n uniform float u_fadeFraction;\n\n //\n // Given a value, find its corresponding color in the gradient stops.\n //\n vec4 getGradientColor(float position) {\n // Find left and right stop:\n float left = -1.0;\n float right = 99.0;\n vec4 leftColor;\n vec4 rightColor;\n\n for(int i = 0; i < 12; i++) {\n if (u_gradientStops[i] <= position) {\n left = u_gradientStops[i]; \n leftColor = u_gradientColors[i];\n } else break;\n }\n\n for(int i = 12 - 1; i >= 0; i--) {\n if (u_gradientStops[i] >= position) {\n right = u_gradientStops[i]; \n rightColor = u_gradientColors[i];\n } else break;\n }\n\n // Distance between stops:\n float width = right - left;\n // Distance from left stop:\n float dist = position - left;\n // Right stop weight:\n float weight;\n if(dist == 0.0) {\n weight = dist;\n } else {\n weight = dist / width;\n }\n\n float r = leftColor.x + (rightColor.x - leftColor.x) * weight;\n float g = leftColor.y + (rightColor.y - leftColor.y) * weight;\n float b = leftColor.z + (rightColor.z - leftColor.z) * weight;\n float a = leftColor.w + (rightColor.w - leftColor.w) * weight;\n return vec4(r, g, b, a); \n } \n\n // GLSL ES 1.00 compatible\n // rgba: vec4 from texture2D (values in [0..1])\n float decodeFloatRGBA(vec4 rgba) {\n // convert to 0..255 and round\n vec4 b = floor(rgba * 255.0 + 0.5);\n\n float b0 = b.r;\n float b1 = b.g;\n float b2 = b.b;\n float b3 = b.a;\n\n // sign: top bit of b3\n float sign = (b3 >= 128.0) ? -1.0 : 1.0;\n\n // exponent: 8 bits where lowest bit comes from b2's top bit\n float exp_low = floor(b2 / 128.0); // 0 or 1\n float exp_high = mod(b3, 128.0); // bits 1..7 of exponent as 0..127\n float exponent = exp_high * 2.0 + exp_low; // full 0..255\n\n // mantissa: 23 bits from b0,b1 and lower 7 bits of b2\n float mantissa = b0 + b1 * 256.0 + mod(b2, 128.0) * 65536.0;\n\n // handle special cases\n if (exponent == 0.0) {\n // zero or subnormal\n if (mantissa == 0.0) {\n return 0.0;\n } else {\n // subnormal numbers: (-1)^s * (mantissa / 2^23) * 2^-126\n return sign * (mantissa / 8388608.0) * exp2(-126.0);\n }\n } else if (exponent == 255.0) {\n // Inf or NaN -- return a large value for Inf, and 0 for NaN\n if (mantissa == 0.0) {\n return sign * 3.402823466e38; // approx FLT_MAX\n } else {\n return 0.0; // NaN -> 0 (or handle as you prefer)\n }\n } else {\n // normalized number: (-1)^s * (1 + mantissa/2^23) * 2^(exponent-127)\n float m = 1.0 + mantissa / 8388608.0;\n return sign * m * exp2(exponent - 127.0);\n }\n } \n\n vec2 texCoordForIndex(float idx, vec2 texSize) {\n float x = mod(idx, texSize.x);\n float y = floor(idx / texSize.x);\n return (vec2(x + 0.5, y + 0.5) / texSize);\n }\n\n // read triple of pixels: idx*3 + 0,1,2\n vec3 getPoint(int index) {\n float base = float(index) * 3.0;\n vec4 c0 = texture2D(u_dataTexture, texCoordForIndex(base + 0.0, u_dataTextureSize)); // x (mercator)\n vec4 c1 = texture2D(u_dataTexture, texCoordForIndex(base + 1.0, u_dataTextureSize)); // y (mercator)\n vec4 c2 = texture2D(u_dataTexture, texCoordForIndex(base + 2.0, u_dataTextureSize)); // value\n float mx = decodeFloatRGBA(c0);\n float my = decodeFloatRGBA(c1);\n float val = decodeFloatRGBA(c2);\n return vec3(mx, my, val);\n }\n\n void main() {\n float num = 0.0;\n float denom = 0.0;\n float power = 3.0; // IDW power\n float minDist = 1e9;\n\n for (int i = 0; i < 1024; i++) { // 1024 is a safe upper bound\n if (i >= u_numStations) break;\n vec3 station = getPoint(i);\n float dx = v_pos.x - station.x;\n float dy = v_pos.y - station.y;\n float d = sqrt(dx*dx + dy*dy);\n minDist = min(minDist, d);\n\n if (d < 1e-6) {\n // Exact match: use station value directly\n num = station.z;\n denom = 1.0;\n // stop looping, we\u2019re done\n break;\n }\n\n float w = 1.0 / pow(d, power);\n num += w * station.z;\n denom += w;\n }\n\n if (minDist > u_maxDistance) {\n // Too far from any station \u2192 discard pixel (transparent)\n discard;\n } \n\n float value = num / denom;\n\n // Normalize value between 0 and 1\n //float minVal = 0.0; // pass as uniform if needed\n //float maxVal = 1.0;\n //float norm = clamp((value - minVal) / (maxVal - minVal), 0.0, 1.0);\n\n // --- FADE TO TRANSPARENT ---\n float u_fadeDistance = u_maxDistance * u_fadeFraction;\n float alpha = 1.0;\n if (minDist > u_maxDistance - u_fadeDistance) {\n // fade linearly from 1 \u2192 0\n alpha = (u_maxDistance - minDist) / u_fadeDistance;\n alpha = clamp(alpha, 0.0, 1.0);\n }\n\n gl_FragColor = vec4(vec3(getGradientColor(1.0 - value)), alpha);\n }\n\n";
2
+ export { IdwFragmentShader };
@@ -0,0 +1,69 @@
1
+ import * as React from 'react';
2
+ import { IGradientStop } from '../../../Types';
3
+ interface IPoint {
4
+ latitude: number;
5
+ longitude: number;
6
+ value: number;
7
+ }
8
+ interface IIdwLayerProps {
9
+ /**
10
+ * Input data.
11
+ */
12
+ data: IPoint[];
13
+ /**
14
+ * Gradient stops. A default gradient is preset.
15
+ */
16
+ gradientStops?: IGradientStop[];
17
+ /**
18
+ * Minimum zoom level at which to render layer.
19
+ * @default 0
20
+ */
21
+ minZoom?: number;
22
+ /**
23
+ * Maximum zoom level at which to render layer.
24
+ * @default 99
25
+ */
26
+ maxZoom?: number;
27
+ /**
28
+ * Maximum world distance (in -1..1 coordinate) system away from
29
+ * all stations where a pixel is still drawn.
30
+ * @default 0.0002
31
+ */
32
+ maxDistance?: number;
33
+ /**
34
+ * Thickness of fading edge of blob (value 0..1)
35
+ * @default 0.15
36
+ */
37
+ fadeFraction?: number;
38
+ /**
39
+ * Offscreen texture resolution. Higher resolution = more pixels,
40
+ * slowing down the fragment shader.
41
+ * @default 256
42
+ */
43
+ resolution: 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096;
44
+ }
45
+ /**
46
+ * An `IdwLayer` takes a data array of points of the form
47
+ * `{ latitude, longitude, value }`, and renders a colored surface using
48
+ * **inverse distance weighting**.
49
+ *
50
+ * To do this, all points are stored in a data texture, which is then read
51
+ * by the fragment shader. For each fragment, the fragment shader consults
52
+ * all points in the data texture and determines their distance to the
53
+ * fragment, the applies inverse distance weighting to calculate the value
54
+ * of the fragment.
55
+ *
56
+ * This process is _O(FxP)_, where _F_ is the number of fragments and _P_ is the
57
+ * number of data points. For a large screen (2048x1024) and a large number
58
+ * of data points (100), this will mean 209M calculations per frame. To
59
+ * reduce this, the actual calculations are done in a first pass to a frame
60
+ * buffer, using a texture of (by default) 256x256. The number of calculations
61
+ * is then reduced to 6M. The resulting texture is then upscaled to fill
62
+ * the original screen. The resolution of the offscreen texture is configurable,
63
+ * as long as it is a power of 2 (32, 64, 128, 256...).
64
+ */
65
+ declare const IdwLayer: {
66
+ ({ gradientStops, minZoom, maxZoom, maxDistance, fadeFraction, resolution, ...props }: IIdwLayerProps): React.JSX.Element;
67
+ displayName: string;
68
+ };
69
+ export { IdwLayer };
@@ -0,0 +1,285 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __rest = (this && this.__rest) || function (s, e) {
13
+ var t = {};
14
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
15
+ t[p] = s[p];
16
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
17
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
18
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
19
+ t[p[i]] = s[p[i]];
20
+ }
21
+ return t;
22
+ };
23
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
24
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
25
+ if (ar || !(i in from)) {
26
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
27
+ ar[i] = from[i];
28
+ }
29
+ }
30
+ return to.concat(ar || Array.prototype.slice.call(from));
31
+ };
32
+ import * as React from 'react';
33
+ import { Layer, useMap } from 'react-map-gl/mapbox';
34
+ import { MercatorCoordinate } from 'mapbox-gl';
35
+ import { IdwVertexShader } from './IdwVertexShader';
36
+ import { IdwFragmentShader } from './IdwFragmentShader';
37
+ import { RgbColor } from '../../../helper/RgbColor';
38
+ import { PresetGradients } from '../../../controls/Gradient';
39
+ import { CopyVertexShader } from './CopyVertexShader';
40
+ import { CopyFragmentShader } from './CopyFragmentShader';
41
+ var IdwLayerBase = function (props) {
42
+ var map = useMap();
43
+ var idwProgram = React.useRef(null);
44
+ var vertexBuffer = React.useRef(null);
45
+ var dataTexture = React.useRef(null);
46
+ var dataTextureWidth = React.useRef(null);
47
+ var dataTextureHeight = React.useRef(null);
48
+ var offscreenTexture = React.useRef(null);
49
+ var fbo = React.useRef(null);
50
+ var copyProgram = React.useRef(null);
51
+ var copyBuffer = React.useRef(null);
52
+ var _a = React.useState(0), time = _a[0], setTime = _a[1];
53
+ var data = props.data.slice(0, 50);
54
+ // When properties change, make sure that layer is redrawn.
55
+ // Do this by varying its `key` with the current time.
56
+ React.useEffect(function () {
57
+ setTime(Date.now());
58
+ }, [props.data, props.gradientStops]);
59
+ //
60
+ // Convert a hex color (e.g. #ff0022) to an [r,g,b,a] array,
61
+ // where r,g,b,a are in the 0.0-1.0 range.
62
+ //
63
+ var colorToRGBA = function (color) {
64
+ var rgb = RgbColor.FromString(color);
65
+ return [rgb.red / 255.0, rgb.green / 255.0, rgb.blue / 255.0, rgb.alpha];
66
+ };
67
+ var floatToRGBABytesLE = function (value) {
68
+ var buf = new ArrayBuffer(4);
69
+ var dv = new DataView(buf);
70
+ dv.setFloat32(0, value, true); // little-endian
71
+ return [
72
+ dv.getUint8(0),
73
+ dv.getUint8(1),
74
+ dv.getUint8(2),
75
+ dv.getUint8(3),
76
+ ];
77
+ };
78
+ var makeTexture = function (gl) {
79
+ var minVal = Math.min.apply(Math, data.map(function (p) { return p.value; }));
80
+ var maxVal = Math.max.apply(Math, data.map(function (p) { return p.value; }));
81
+ var normalized = data.map(function (m) {
82
+ var coord = MercatorCoordinate.fromLngLat({ lng: m.longitude, lat: m.latitude });
83
+ return { x: coord.x, y: coord.y, value: (m.value - minVal) / (maxVal - minVal) };
84
+ });
85
+ var texSize = 1024;
86
+ dataTextureWidth.current = texSize;
87
+ dataTextureHeight.current = texSize;
88
+ var pixels = new Uint8Array(texSize * texSize * 4);
89
+ normalized.forEach(function (p, i) {
90
+ var values = [p.x, p.y, p.value];
91
+ for (var j = 0; j < 3; j++) {
92
+ var _a = floatToRGBABytesLE(values[j]), r = _a[0], g = _a[1], b = _a[2], a = _a[3];
93
+ var pixelIndex = i * 3 + j;
94
+ var offset = pixelIndex * 4;
95
+ if (offset + 3 < pixels.length) {
96
+ pixels[offset + 0] = r;
97
+ pixels[offset + 1] = g;
98
+ pixels[offset + 2] = b;
99
+ pixels[offset + 3] = a;
100
+ }
101
+ }
102
+ });
103
+ // Create / bind / upload texture
104
+ dataTexture.current = gl.createTexture();
105
+ gl.bindTexture(gl.TEXTURE_2D, dataTexture.current);
106
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
107
+ // Use nearest sampling — we want exact pixel values
108
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
109
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
110
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
111
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
112
+ };
113
+ var onAddLayer = function (map, gl) {
114
+ // IDW PROGRAM
115
+ // create a vertex shader
116
+ var vertexShader = gl.createShader(gl.VERTEX_SHADER);
117
+ gl.shaderSource(vertexShader, IdwVertexShader);
118
+ gl.compileShader(vertexShader);
119
+ // create a fragment shader
120
+ var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
121
+ gl.shaderSource(fragmentShader, IdwFragmentShader);
122
+ gl.compileShader(fragmentShader);
123
+ // link the two shaders into a WebGL program
124
+ idwProgram.current = gl.createProgram();
125
+ gl.attachShader(idwProgram.current, vertexShader);
126
+ gl.attachShader(idwProgram.current, fragmentShader);
127
+ gl.linkProgram(idwProgram.current);
128
+ // Create vertex buffer from vertices:
129
+ vertexBuffer.current = gl.createBuffer();
130
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer.current);
131
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
132
+ 0.0, 0.0,
133
+ 1.0, 0.0,
134
+ 0.0, 1.0,
135
+ 1.0, 1.0
136
+ ]), gl.STATIC_DRAW);
137
+ // Make an OpenGL texture that contains station data (x,y,value).
138
+ // The texture dimensions are saved and will be passed into a shader
139
+ // uniform. Note that lat/lng is converted to Mercator x,y, which has
140
+ // a range of [0..1].
141
+ makeTexture(gl);
142
+ // create texture to render into
143
+ offscreenTexture.current = gl.createTexture();
144
+ gl.bindTexture(gl.TEXTURE_2D, offscreenTexture.current);
145
+ // allocate empty texture
146
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, props.resolution, props.resolution, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
147
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); // linear for smoother upsampling; you can use NEAREST if you want blocky
148
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
149
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
150
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
151
+ // create framebuffer and attach texture
152
+ fbo.current = gl.createFramebuffer();
153
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo.current);
154
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, offscreenTexture.current, 0);
155
+ // check completeness (best-effort)
156
+ var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
157
+ if (status !== gl.FRAMEBUFFER_COMPLETE) {
158
+ // Not fatal here — log to console
159
+ // eslint-disable-next-line no-console
160
+ console.warn('Framebuffer not complete: ', status);
161
+ }
162
+ // unbind
163
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
164
+ // COPY PROGRAM
165
+ // create a vertex shader
166
+ var copyVertexShader = gl.createShader(gl.VERTEX_SHADER);
167
+ gl.shaderSource(copyVertexShader, CopyVertexShader);
168
+ gl.compileShader(copyVertexShader);
169
+ // create a fragment shader
170
+ var copyFragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
171
+ gl.shaderSource(copyFragmentShader, CopyFragmentShader);
172
+ gl.compileShader(copyFragmentShader);
173
+ // link the two shaders into a WebGL program
174
+ copyProgram.current = gl.createProgram();
175
+ gl.attachShader(copyProgram.current, copyVertexShader);
176
+ gl.attachShader(copyProgram.current, copyFragmentShader);
177
+ gl.linkProgram(copyProgram.current);
178
+ // Create vertex buffer from vertices:
179
+ copyBuffer.current = gl.createBuffer();
180
+ gl.bindBuffer(gl.ARRAY_BUFFER, copyBuffer.current);
181
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
182
+ 0.0, 0.0,
183
+ 1.0, 0.0,
184
+ 0.0, 1.0,
185
+ 1.0, 1.0
186
+ ]), gl.STATIC_DRAW);
187
+ };
188
+ var onRender = function (gl, matrix, zoom, width, height) {
189
+ // Render is called many times while the map is panned/zoomed.
190
+ // You cannot have access to the map though.
191
+ if (zoom < props.minZoom)
192
+ return;
193
+ if (zoom > props.maxZoom)
194
+ return;
195
+ //
196
+ // FIRST PASS
197
+ //
198
+ gl.bindFramebuffer(gl.FRAMEBUFFER, fbo.current);
199
+ var vp = gl.getParameter(gl.VIEWPORT);
200
+ gl.viewport(0, 0, props.resolution, props.resolution);
201
+ gl.clearColor(0, 0, 0, 0);
202
+ gl.clear(gl.COLOR_BUFFER_BIT);
203
+ // Render is called many times while the map is panned/zoomed.
204
+ // You cannot have access to the map though.
205
+ gl.useProgram(idwProgram.current);
206
+ // Pass a matrix uniform in:
207
+ gl.uniformMatrix4fv(gl.getUniformLocation(idwProgram.current, 'u_matrix'), false, matrix);
208
+ // Pass in number of stations:
209
+ gl.uniform1i(gl.getUniformLocation(idwProgram.current, "u_numStations"), data.length);
210
+ // put the data texture on texture unit 0
211
+ gl.activeTexture(gl.TEXTURE0);
212
+ gl.bindTexture(gl.TEXTURE_2D, dataTexture.current);
213
+ // Pass data texture in (use texture unit 0):
214
+ gl.uniform1i(gl.getUniformLocation(idwProgram.current, "u_dataTexture"), 0);
215
+ // Pass texture size in:
216
+ // Tell the shader the size of the position texture
217
+ gl.uniform2f(gl.getUniformLocation(idwProgram.current, "u_dataTextureSize"), dataTextureWidth.current, dataTextureHeight.current);
218
+ // Stops - fill up to 12 stops by using values > 1 for filler stops.
219
+ // e.g. [0.0, 0.5, 1.0, 2.0....] means that only the first 3 stops are used.
220
+ var stops = __spreadArray([], props.gradientStops.map(function (s) { return s.pos; }), true);
221
+ while (stops.length < 12)
222
+ stops.push(2.0);
223
+ gl.uniform1fv(gl.getUniformLocation(idwProgram.current, 'u_gradientStops'), new Float32Array(stops));
224
+ var colors = props.gradientStops.map(function (s) { return colorToRGBA(s.color); }).flat();
225
+ gl.uniform4fv(gl.getUniformLocation(idwProgram.current, 'u_gradientColors'), new Float32Array(colors));
226
+ // Max distance from all stations at which a pixel is drawn:
227
+ gl.uniform1f(gl.getUniformLocation(idwProgram.current, "u_maxDistance"), props.maxDistance);
228
+ // Fraction of this max distance where fading begins:
229
+ gl.uniform1f(gl.getUniformLocation(idwProgram.current, "u_fadeFraction"), props.fadeFraction);
230
+ var aPos = gl.getAttribLocation(idwProgram.current, 'a_pos');
231
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer.current);
232
+ gl.enableVertexAttribArray(aPos);
233
+ gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
234
+ gl.enable(gl.BLEND);
235
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
236
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
237
+ //
238
+ // SECOND PASS
239
+ //
240
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
241
+ // Restore mapbox viewport:
242
+ gl.viewport(vp[0], vp[1], vp[2], vp[3]);
243
+ gl.useProgram(copyProgram.current);
244
+ // Pass a matrix uniform in:
245
+ gl.uniformMatrix4fv(gl.getUniformLocation(copyProgram.current, 'u_matrix'), false, matrix);
246
+ // bind offscreen texture into unit 0 for copy pass
247
+ gl.activeTexture(gl.TEXTURE0);
248
+ gl.bindTexture(gl.TEXTURE_2D, offscreenTexture.current);
249
+ gl.uniform1i(gl.getUniformLocation(copyProgram.current, 'u_src'), 0);
250
+ var aPos2 = gl.getAttribLocation(copyProgram.current, 'a_pos');
251
+ gl.bindBuffer(gl.ARRAY_BUFFER, copyBuffer.current);
252
+ gl.enableVertexAttribArray(aPos2);
253
+ gl.vertexAttribPointer(aPos2, 2, gl.FLOAT, false, 0, 0);
254
+ gl.enable(gl.BLEND);
255
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
256
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
257
+ };
258
+ return (React.createElement(Layer, { id: null, type: "custom", beforeId: "overlay", key: time, onAdd: onAddLayer, render: function (gl, matrix) { return onRender(gl, matrix, map.current.getZoom(), map.current.getContainer().clientWidth, map.current.getContainer().clientHeight); } }));
259
+ };
260
+ /**
261
+ * An `IdwLayer` takes a data array of points of the form
262
+ * `{ latitude, longitude, value }`, and renders a colored surface using
263
+ * **inverse distance weighting**.
264
+ *
265
+ * To do this, all points are stored in a data texture, which is then read
266
+ * by the fragment shader. For each fragment, the fragment shader consults
267
+ * all points in the data texture and determines their distance to the
268
+ * fragment, the applies inverse distance weighting to calculate the value
269
+ * of the fragment.
270
+ *
271
+ * This process is _O(FxP)_, where _F_ is the number of fragments and _P_ is the
272
+ * number of data points. For a large screen (2048x1024) and a large number
273
+ * of data points (100), this will mean 209M calculations per frame. To
274
+ * reduce this, the actual calculations are done in a first pass to a frame
275
+ * buffer, using a texture of (by default) 256x256. The number of calculations
276
+ * is then reduced to 6M. The resulting texture is then upscaled to fill
277
+ * the original screen. The resolution of the offscreen texture is configurable,
278
+ * as long as it is a power of 2 (32, 64, 128, 256...).
279
+ */
280
+ var IdwLayer = function (_a) {
281
+ var _b = _a.gradientStops, gradientStops = _b === void 0 ? PresetGradients.Blue : _b, _c = _a.minZoom, minZoom = _c === void 0 ? 0 : _c, _d = _a.maxZoom, maxZoom = _d === void 0 ? 99 : _d, _e = _a.maxDistance, maxDistance = _e === void 0 ? 0.0002 : _e, _f = _a.fadeFraction, fadeFraction = _f === void 0 ? 0.15 : _f, _g = _a.resolution, resolution = _g === void 0 ? 256 : _g, props = __rest(_a, ["gradientStops", "minZoom", "maxZoom", "maxDistance", "fadeFraction", "resolution"]);
282
+ return React.createElement(IdwLayerBase, __assign({ gradientStops: gradientStops, minZoom: minZoom, maxZoom: maxZoom, maxDistance: maxDistance, fadeFraction: fadeFraction, resolution: resolution }, props));
283
+ };
284
+ IdwLayer.displayName = 'IdwLayer';
285
+ export { IdwLayer };
@@ -0,0 +1,2 @@
1
+ declare const IdwVertexShader = " \n uniform mat4 u_matrix;\n attribute vec2 a_pos;\n\n varying vec2 v_pos;\n\n void main() {\n gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);\n v_pos = a_pos.xy;\n }\n";
2
+ export { IdwVertexShader };
@@ -0,0 +1,2 @@
1
+ var IdwVertexShader = /*glsl*/ " \n uniform mat4 u_matrix;\n attribute vec2 a_pos;\n\n varying vec2 v_pos;\n\n void main() {\n gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);\n v_pos = a_pos.xy;\n }\n";
2
+ export { IdwVertexShader };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@longline/aqua-ui",
3
- "version": "1.0.225",
3
+ "version": "1.0.227",
4
4
  "description": "AquaUI",
5
5
  "author": "Alexander van Oostenrijk / Longline Environment",
6
6
  "license": "Commercial",