@yuneta/gobj-ui 7.23.96 → 7.23.98

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.
@@ -9683,9 +9683,27 @@ function load_devices(gobj) {
9683
9683
  source: "devices",
9684
9684
  filter: ["has", "point_count"],
9685
9685
  layout: {
9686
- "text-field": "{point_count_abbreviated}",
9686
+ "text-field": [
9687
+ "case",
9688
+ [
9689
+ "<",
9690
+ ["get", "connected"],
9691
+ ["get", "point_count"]
9692
+ ],
9693
+ [
9694
+ "concat",
9695
+ ["get", "point_count_abbreviated"],
9696
+ " !"
9697
+ ],
9698
+ ["get", "point_count_abbreviated"]
9699
+ ],
9687
9700
  "text-font": ["Noto Sans Regular"],
9688
9701
  "text-size": 14
9702
+ },
9703
+ paint: {
9704
+ "text-color": "#ffffff",
9705
+ "text-halo-color": "rgba(0,0,0,0.35)",
9706
+ "text-halo-width": 1
9689
9707
  }
9690
9708
  });
9691
9709
  map.addLayer({
@@ -9700,12 +9718,16 @@ function load_devices(gobj) {
9700
9718
  "text-offset": [0, -2.5],
9701
9719
  "text-anchor": "top"
9702
9720
  },
9703
- paint: { "text-color": [
9704
- "case",
9705
- ["get", "connected"],
9706
- "green",
9707
- "red"
9708
- ] }
9721
+ paint: {
9722
+ "text-color": [
9723
+ "case",
9724
+ ["get", "connected"],
9725
+ "#1e7a3c",
9726
+ "#b3243a"
9727
+ ],
9728
+ "text-halo-color": "#ffffff",
9729
+ "text-halo-width": 1.4
9730
+ }
9709
9731
  });
9710
9732
  map.addLayer({
9711
9733
  id: "unclustered-point",
@@ -9724,6 +9746,28 @@ function load_devices(gobj) {
9724
9746
  "circle-stroke-color": "#fff"
9725
9747
  }
9726
9748
  });
9749
+ map.addLayer({
9750
+ id: "unclustered-alert",
9751
+ type: "symbol",
9752
+ source: "devices",
9753
+ filter: [
9754
+ "all",
9755
+ ["!", ["has", "point_count"]],
9756
+ ["!", ["get", "connected"]]
9757
+ ],
9758
+ layout: {
9759
+ "text-field": "!",
9760
+ "text-font": ["Noto Sans Regular"],
9761
+ "text-size": 18,
9762
+ "text-allow-overlap": true,
9763
+ "text-ignore-placement": true
9764
+ },
9765
+ paint: {
9766
+ "text-color": "#ffffff",
9767
+ "text-halo-color": "rgba(0,0,0,0.45)",
9768
+ "text-halo-width": 1
9769
+ }
9770
+ });
9727
9771
  center_map(gobj);
9728
9772
  map.on("click", "clusters", async (e) => {
9729
9773
  const features = map.queryRenderedFeatures(e.point, { layers: ["clusters"] });
@@ -10019,6 +10063,66 @@ function register_c_yui_map() {
10019
10063
  * All Rights Reserved.
10020
10064
  ***********************************************************************/
10021
10065
  /***************************************************************
10066
+ * The ink of a chart, and its palette.
10067
+ *
10068
+ * uPlot is built for a white page: its axis labels are `#000`
10069
+ * and its grid `rgba(0,0,0,0.07)`, which on the dark scheme are
10070
+ * 1.16:1 and 1.04 -- an axis nobody can read and a grid that is
10071
+ * not there. And the series were CSS colour names: `blue` is
10072
+ * 2.11:1 on the dark ground, `orange` 1.97 on the light one, so
10073
+ * whichever scheme you were in, one of the lines was a rumour.
10074
+ *
10075
+ * These are given to uPlot as FUNCTIONS: it calls them when it
10076
+ * draws, so the value can never be stale -- what goes stale is
10077
+ * the canvas, and that is what EV_THEME redraws.
10078
+ *
10079
+ * The palette is six colours that clear 3:1 on BOTH grounds
10080
+ * (worst 3.39 on white, 3.71 on near-black), ordered so the
10081
+ * first two are the pair that survives colour blindness -- blue
10082
+ * and orange, never red and green as the opening pair.
10083
+ ***************************************************************/
10084
+ function axis_ink() {
10085
+ return yui_is_dark() ? "#c7cdd8" : "#2e333d";
10086
+ }
10087
+ function grid_ink() {
10088
+ return yui_is_dark() ? "rgba(199,205,216,0.16)" : "rgba(46,51,61,0.12)";
10089
+ }
10090
+ var CHART_PALETTE = [
10091
+ {
10092
+ stroke: "#2f6fd0",
10093
+ fill: "rgba(47,111,208,0.10)"
10094
+ },
10095
+ {
10096
+ stroke: "#b8620a",
10097
+ fill: "rgba(184,98,10,0.10)"
10098
+ },
10099
+ {
10100
+ stroke: "#2f8f4e",
10101
+ fill: "rgba(47,143,78,0.10)"
10102
+ },
10103
+ {
10104
+ stroke: "#8b5cf6",
10105
+ fill: "rgba(139,92,246,0.10)"
10106
+ },
10107
+ {
10108
+ stroke: "#0e9aa7",
10109
+ fill: "rgba(14,154,167,0.10)"
10110
+ },
10111
+ {
10112
+ stroke: "#d1344b",
10113
+ fill: "rgba(209,52,75,0.10)"
10114
+ }
10115
+ ];
10116
+ function themed_axes(axes) {
10117
+ return (Array.isArray(axes) ? axes : [axes || {}]).map((ax) => {
10118
+ let a = Object.assign({}, ax || {});
10119
+ if (a.stroke === void 0) a.stroke = axis_ink;
10120
+ a.grid = Object.assign({ stroke: grid_ink }, a.grid || {});
10121
+ a.ticks = Object.assign({ stroke: grid_ink }, a.ticks || {});
10122
+ return a;
10123
+ });
10124
+ }
10125
+ /***************************************************************
10022
10126
  * Constants
10023
10127
  ***************************************************************/
10024
10128
  var GCLASS_NAME$14 = "C_YUI_UPLOT";
@@ -10035,24 +10139,7 @@ var attrs_table$14 = [
10035
10139
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_JSON, "axes", 0, [{}], "Chart axes"),
10036
10140
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_JSON, "scales", 0, {}, "Chart scales"),
10037
10141
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_JSON, "data", 0, [[]], "Chart data"),
10038
- (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_JSON, "colors", 0, [
10039
- {
10040
- stroke: "red",
10041
- fill: "rgba(255,0,0,0.05)"
10042
- },
10043
- {
10044
- stroke: "green",
10045
- fill: "rgba(0,255,0,0.07)"
10046
- },
10047
- {
10048
- stroke: "blue",
10049
- fill: "rgba(0,0,255,0.05)"
10050
- },
10051
- {
10052
- stroke: "orange",
10053
- fill: "rgba(255,165,0,0.1)"
10054
- }
10055
- ], "Color settings"),
10142
+ (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_JSON, "colors", 0, CHART_PALETTE, "Series colours, in order. The default palette clears 3:1 on both schemes and opens with the colour-blind-safe pair (blue, orange)"),
10056
10143
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "$container", 0, null, "HTML container for the chart"),
10057
10144
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_BOOLEAN, "own_container", 0, false, "If true, container is gobj-managed"),
10058
10145
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_POINTER, "uplot", 0, null, "uPlot instance"),
@@ -10060,7 +10147,7 @@ var attrs_table$14 = [
10060
10147
  (0, _yuneta_gobj_js.SDATA)(_yuneta_gobj_js.data_type_t.DTP_INTEGER, "timeout_idle", 0, 5, "Idle timeout (seconds)"),
10061
10148
  (0, _yuneta_gobj_js.SDATA_END)()
10062
10149
  ];
10063
- var PRIVATE_DATA$14 = {};
10150
+ var PRIVATE_DATA$14 = { theme_observer: null };
10064
10151
  var __gclass__$14 = null;
10065
10152
  /******************************
10066
10153
  * Framework Methods
@@ -10070,6 +10157,7 @@ var __gclass__$14 = null;
10070
10157
  ***************************************************************/
10071
10158
  function mt_create$14(gobj) {
10072
10159
  build_ui$13(gobj);
10160
+ gobj.priv.theme_observer = yui_watch_theme(gobj);
10073
10161
  let subscriber = (0, _yuneta_gobj_js.gobj_read_pointer_attr)(gobj, "subscriber");
10074
10162
  if (!subscriber) subscriber = (0, _yuneta_gobj_js.gobj_parent)(gobj);
10075
10163
  (0, _yuneta_gobj_js.gobj_subscribe_event)(gobj, null, {}, subscriber);
@@ -10086,6 +10174,10 @@ function mt_stop$14(gobj) {}
10086
10174
  * Framework Method: Destroy
10087
10175
  ***************************************************************/
10088
10176
  function mt_destroy$14(gobj) {
10177
+ if (gobj.priv.theme_observer) {
10178
+ gobj.priv.theme_observer.disconnect();
10179
+ gobj.priv.theme_observer = null;
10180
+ }
10089
10181
  let uplot$1 = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "uplot");
10090
10182
  if (uplot$1) {
10091
10183
  uplot$1.destroy();
@@ -10114,7 +10206,7 @@ function build_ui$13(gobj) {
10114
10206
  width: (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "width"),
10115
10207
  height: (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "height"),
10116
10208
  series: (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "series"),
10117
- axes: (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "axes"),
10209
+ axes: themed_axes((0, _yuneta_gobj_js.gobj_read_attr)(gobj, "axes")),
10118
10210
  scales: (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "scales")
10119
10211
  };
10120
10212
  let uplot$2 = new uplot.default(uPlot_options, (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "data"), $container);
@@ -10214,29 +10306,40 @@ function ac_add_serie(gobj, event, kw, src) {
10214
10306
  return -1;
10215
10307
  }
10216
10308
  }
10217
- let color = {
10218
- stroke: "Orange",
10219
- fill: "rgb(255, 165, 0, 0.05)"
10220
- };
10221
10309
  let colors = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "colors");
10222
- if (idx < colors.length) color = colors[idx];
10310
+ if (!Array.isArray(colors) || !colors.length) colors = CHART_PALETTE;
10311
+ let color = colors[Math.max(0, idx - 1) % colors.length];
10223
10312
  (0, _yuneta_gobj_js.kw_get_str)(gobj, kw, "stroke", color.stroke, _yuneta_gobj_js.kw_flag_t.KW_CREATE);
10224
10313
  (0, _yuneta_gobj_js.kw_get_str)(gobj, kw, "fill", color.fill, _yuneta_gobj_js.kw_flag_t.KW_CREATE);
10225
10314
  uplot$4.addSeries(kw);
10226
10315
  return 0;
10227
10316
  }
10228
10317
  /******************************************************
10318
+ * The scheme changed: the ink functions answer the new
10319
+ * one already, the canvas is what has to be painted again.
10320
+ ******************************************************/
10321
+ function ac_theme$4(gobj, event, kw, src) {
10322
+ let uplot$5 = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "uplot");
10323
+ if (!uplot$5) return 0;
10324
+ try {
10325
+ uplot$5.redraw();
10326
+ } catch (e) {
10327
+ (0, _yuneta_gobj_js.log_error)(`${(0, _yuneta_gobj_js.gobj_short_name)(gobj)}: cannot redraw the chart: ${e}`);
10328
+ }
10329
+ return 0;
10330
+ }
10331
+ /******************************************************
10229
10332
  *
10230
10333
  ******************************************************/
10231
10334
  function ac_del_serie(gobj, event, kw, src) {
10232
- let uplot$5 = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "uplot");
10233
- for (let idx = 1; idx < uplot$5.series.length; idx++) {
10234
- let serie = uplot$5.series[idx];
10335
+ let uplot$6 = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "uplot");
10336
+ for (let idx = 1; idx < uplot$6.series.length; idx++) {
10337
+ let serie = uplot$6.series[idx];
10235
10338
  if (serie.id && serie.id === kw.id) {
10236
- uplot$5.delSeries(idx);
10237
- let data = uplot$5.data.splice(idx, 1);
10339
+ uplot$6.delSeries(idx);
10340
+ let data = uplot$6.data.splice(idx, 1);
10238
10341
  if (data.length === 1) data = [[]];
10239
- uplot$5.setData(data);
10342
+ uplot$6.setData(data);
10240
10343
  return 0;
10241
10344
  }
10242
10345
  }
@@ -10246,9 +10349,9 @@ function ac_del_serie(gobj, event, kw, src) {
10246
10349
  *
10247
10350
  ******************************************************/
10248
10351
  function ac_clear(gobj, event, kw, src) {
10249
- let uplot$6 = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "uplot");
10250
- uplot$6.setData([[]]);
10251
- for (let idx = uplot$6.series.length - 1; idx > 0; idx--) uplot$6.delSeries(idx);
10352
+ let uplot$7 = (0, _yuneta_gobj_js.gobj_read_attr)(gobj, "uplot");
10353
+ uplot$7.setData([[]]);
10354
+ for (let idx = uplot$7.series.length - 1; idx > 0; idx--) uplot$7.delSeries(idx);
10252
10355
  return 0;
10253
10356
  }
10254
10357
  /***************************
@@ -10272,7 +10375,8 @@ function create_gclass$14(gclass_name) {
10272
10375
  ["EV_LOAD_DATA", 0],
10273
10376
  ["EV_ADD_SERIE", 0],
10274
10377
  ["EV_DEL_SERIE", 0],
10275
- ["EV_CLEAR", 0]
10378
+ ["EV_CLEAR", 0],
10379
+ ["EV_THEME", 0]
10276
10380
  ], [["ST_IDLE", [
10277
10381
  [
10278
10382
  "EV_LOAD_DATA",
@@ -10293,6 +10397,11 @@ function create_gclass$14(gclass_name) {
10293
10397
  "EV_CLEAR",
10294
10398
  ac_clear,
10295
10399
  null
10400
+ ],
10401
+ [
10402
+ "EV_THEME",
10403
+ ac_theme$4,
10404
+ null
10296
10405
  ]
10297
10406
  ]]], gmt$14, 0, attrs_table$14, PRIVATE_DATA$14, 0, 0, 0, 0);
10298
10407
  if (!__gclass__$14) return -1;
@@ -9678,9 +9678,27 @@ function load_devices(gobj) {
9678
9678
  source: "devices",
9679
9679
  filter: ["has", "point_count"],
9680
9680
  layout: {
9681
- "text-field": "{point_count_abbreviated}",
9681
+ "text-field": [
9682
+ "case",
9683
+ [
9684
+ "<",
9685
+ ["get", "connected"],
9686
+ ["get", "point_count"]
9687
+ ],
9688
+ [
9689
+ "concat",
9690
+ ["get", "point_count_abbreviated"],
9691
+ " !"
9692
+ ],
9693
+ ["get", "point_count_abbreviated"]
9694
+ ],
9682
9695
  "text-font": ["Noto Sans Regular"],
9683
9696
  "text-size": 14
9697
+ },
9698
+ paint: {
9699
+ "text-color": "#ffffff",
9700
+ "text-halo-color": "rgba(0,0,0,0.35)",
9701
+ "text-halo-width": 1
9684
9702
  }
9685
9703
  });
9686
9704
  map.addLayer({
@@ -9695,12 +9713,16 @@ function load_devices(gobj) {
9695
9713
  "text-offset": [0, -2.5],
9696
9714
  "text-anchor": "top"
9697
9715
  },
9698
- paint: { "text-color": [
9699
- "case",
9700
- ["get", "connected"],
9701
- "green",
9702
- "red"
9703
- ] }
9716
+ paint: {
9717
+ "text-color": [
9718
+ "case",
9719
+ ["get", "connected"],
9720
+ "#1e7a3c",
9721
+ "#b3243a"
9722
+ ],
9723
+ "text-halo-color": "#ffffff",
9724
+ "text-halo-width": 1.4
9725
+ }
9704
9726
  });
9705
9727
  map.addLayer({
9706
9728
  id: "unclustered-point",
@@ -9719,6 +9741,28 @@ function load_devices(gobj) {
9719
9741
  "circle-stroke-color": "#fff"
9720
9742
  }
9721
9743
  });
9744
+ map.addLayer({
9745
+ id: "unclustered-alert",
9746
+ type: "symbol",
9747
+ source: "devices",
9748
+ filter: [
9749
+ "all",
9750
+ ["!", ["has", "point_count"]],
9751
+ ["!", ["get", "connected"]]
9752
+ ],
9753
+ layout: {
9754
+ "text-field": "!",
9755
+ "text-font": ["Noto Sans Regular"],
9756
+ "text-size": 18,
9757
+ "text-allow-overlap": true,
9758
+ "text-ignore-placement": true
9759
+ },
9760
+ paint: {
9761
+ "text-color": "#ffffff",
9762
+ "text-halo-color": "rgba(0,0,0,0.45)",
9763
+ "text-halo-width": 1
9764
+ }
9765
+ });
9722
9766
  center_map(gobj);
9723
9767
  map.on("click", "clusters", async (e) => {
9724
9768
  const features = map.queryRenderedFeatures(e.point, { layers: ["clusters"] });
@@ -10014,6 +10058,66 @@ function register_c_yui_map() {
10014
10058
  * All Rights Reserved.
10015
10059
  ***********************************************************************/
10016
10060
  /***************************************************************
10061
+ * The ink of a chart, and its palette.
10062
+ *
10063
+ * uPlot is built for a white page: its axis labels are `#000`
10064
+ * and its grid `rgba(0,0,0,0.07)`, which on the dark scheme are
10065
+ * 1.16:1 and 1.04 -- an axis nobody can read and a grid that is
10066
+ * not there. And the series were CSS colour names: `blue` is
10067
+ * 2.11:1 on the dark ground, `orange` 1.97 on the light one, so
10068
+ * whichever scheme you were in, one of the lines was a rumour.
10069
+ *
10070
+ * These are given to uPlot as FUNCTIONS: it calls them when it
10071
+ * draws, so the value can never be stale -- what goes stale is
10072
+ * the canvas, and that is what EV_THEME redraws.
10073
+ *
10074
+ * The palette is six colours that clear 3:1 on BOTH grounds
10075
+ * (worst 3.39 on white, 3.71 on near-black), ordered so the
10076
+ * first two are the pair that survives colour blindness -- blue
10077
+ * and orange, never red and green as the opening pair.
10078
+ ***************************************************************/
10079
+ function axis_ink() {
10080
+ return yui_is_dark() ? "#c7cdd8" : "#2e333d";
10081
+ }
10082
+ function grid_ink() {
10083
+ return yui_is_dark() ? "rgba(199,205,216,0.16)" : "rgba(46,51,61,0.12)";
10084
+ }
10085
+ var CHART_PALETTE = [
10086
+ {
10087
+ stroke: "#2f6fd0",
10088
+ fill: "rgba(47,111,208,0.10)"
10089
+ },
10090
+ {
10091
+ stroke: "#b8620a",
10092
+ fill: "rgba(184,98,10,0.10)"
10093
+ },
10094
+ {
10095
+ stroke: "#2f8f4e",
10096
+ fill: "rgba(47,143,78,0.10)"
10097
+ },
10098
+ {
10099
+ stroke: "#8b5cf6",
10100
+ fill: "rgba(139,92,246,0.10)"
10101
+ },
10102
+ {
10103
+ stroke: "#0e9aa7",
10104
+ fill: "rgba(14,154,167,0.10)"
10105
+ },
10106
+ {
10107
+ stroke: "#d1344b",
10108
+ fill: "rgba(209,52,75,0.10)"
10109
+ }
10110
+ ];
10111
+ function themed_axes(axes) {
10112
+ return (Array.isArray(axes) ? axes : [axes || {}]).map((ax) => {
10113
+ let a = Object.assign({}, ax || {});
10114
+ if (a.stroke === void 0) a.stroke = axis_ink;
10115
+ a.grid = Object.assign({ stroke: grid_ink }, a.grid || {});
10116
+ a.ticks = Object.assign({ stroke: grid_ink }, a.ticks || {});
10117
+ return a;
10118
+ });
10119
+ }
10120
+ /***************************************************************
10017
10121
  * Constants
10018
10122
  ***************************************************************/
10019
10123
  var GCLASS_NAME$14 = "C_YUI_UPLOT";
@@ -10030,24 +10134,7 @@ var attrs_table$14 = [
10030
10134
  SDATA(data_type_t.DTP_JSON, "axes", 0, [{}], "Chart axes"),
10031
10135
  SDATA(data_type_t.DTP_JSON, "scales", 0, {}, "Chart scales"),
10032
10136
  SDATA(data_type_t.DTP_JSON, "data", 0, [[]], "Chart data"),
10033
- SDATA(data_type_t.DTP_JSON, "colors", 0, [
10034
- {
10035
- stroke: "red",
10036
- fill: "rgba(255,0,0,0.05)"
10037
- },
10038
- {
10039
- stroke: "green",
10040
- fill: "rgba(0,255,0,0.07)"
10041
- },
10042
- {
10043
- stroke: "blue",
10044
- fill: "rgba(0,0,255,0.05)"
10045
- },
10046
- {
10047
- stroke: "orange",
10048
- fill: "rgba(255,165,0,0.1)"
10049
- }
10050
- ], "Color settings"),
10137
+ SDATA(data_type_t.DTP_JSON, "colors", 0, CHART_PALETTE, "Series colours, in order. The default palette clears 3:1 on both schemes and opens with the colour-blind-safe pair (blue, orange)"),
10051
10138
  SDATA(data_type_t.DTP_POINTER, "$container", 0, null, "HTML container for the chart"),
10052
10139
  SDATA(data_type_t.DTP_BOOLEAN, "own_container", 0, false, "If true, container is gobj-managed"),
10053
10140
  SDATA(data_type_t.DTP_POINTER, "uplot", 0, null, "uPlot instance"),
@@ -10055,7 +10142,7 @@ var attrs_table$14 = [
10055
10142
  SDATA(data_type_t.DTP_INTEGER, "timeout_idle", 0, 5, "Idle timeout (seconds)"),
10056
10143
  SDATA_END()
10057
10144
  ];
10058
- var PRIVATE_DATA$14 = {};
10145
+ var PRIVATE_DATA$14 = { theme_observer: null };
10059
10146
  var __gclass__$14 = null;
10060
10147
  /******************************
10061
10148
  * Framework Methods
@@ -10065,6 +10152,7 @@ var __gclass__$14 = null;
10065
10152
  ***************************************************************/
10066
10153
  function mt_create$14(gobj) {
10067
10154
  build_ui$13(gobj);
10155
+ gobj.priv.theme_observer = yui_watch_theme(gobj);
10068
10156
  let subscriber = gobj_read_pointer_attr(gobj, "subscriber");
10069
10157
  if (!subscriber) subscriber = gobj_parent(gobj);
10070
10158
  gobj_subscribe_event(gobj, null, {}, subscriber);
@@ -10081,6 +10169,10 @@ function mt_stop$14(gobj) {}
10081
10169
  * Framework Method: Destroy
10082
10170
  ***************************************************************/
10083
10171
  function mt_destroy$14(gobj) {
10172
+ if (gobj.priv.theme_observer) {
10173
+ gobj.priv.theme_observer.disconnect();
10174
+ gobj.priv.theme_observer = null;
10175
+ }
10084
10176
  let uplot = gobj_read_attr(gobj, "uplot");
10085
10177
  if (uplot) {
10086
10178
  uplot.destroy();
@@ -10109,7 +10201,7 @@ function build_ui$13(gobj) {
10109
10201
  width: gobj_read_attr(gobj, "width"),
10110
10202
  height: gobj_read_attr(gobj, "height"),
10111
10203
  series: gobj_read_attr(gobj, "series"),
10112
- axes: gobj_read_attr(gobj, "axes"),
10204
+ axes: themed_axes(gobj_read_attr(gobj, "axes")),
10113
10205
  scales: gobj_read_attr(gobj, "scales")
10114
10206
  };
10115
10207
  let uplot = new uPlot(uPlot_options, gobj_read_attr(gobj, "data"), $container);
@@ -10209,18 +10301,29 @@ function ac_add_serie(gobj, event, kw, src) {
10209
10301
  return -1;
10210
10302
  }
10211
10303
  }
10212
- let color = {
10213
- stroke: "Orange",
10214
- fill: "rgb(255, 165, 0, 0.05)"
10215
- };
10216
10304
  let colors = gobj_read_attr(gobj, "colors");
10217
- if (idx < colors.length) color = colors[idx];
10305
+ if (!Array.isArray(colors) || !colors.length) colors = CHART_PALETTE;
10306
+ let color = colors[Math.max(0, idx - 1) % colors.length];
10218
10307
  kw_get_str(gobj, kw, "stroke", color.stroke, kw_flag_t.KW_CREATE);
10219
10308
  kw_get_str(gobj, kw, "fill", color.fill, kw_flag_t.KW_CREATE);
10220
10309
  uplot.addSeries(kw);
10221
10310
  return 0;
10222
10311
  }
10223
10312
  /******************************************************
10313
+ * The scheme changed: the ink functions answer the new
10314
+ * one already, the canvas is what has to be painted again.
10315
+ ******************************************************/
10316
+ function ac_theme$4(gobj, event, kw, src) {
10317
+ let uplot = gobj_read_attr(gobj, "uplot");
10318
+ if (!uplot) return 0;
10319
+ try {
10320
+ uplot.redraw();
10321
+ } catch (e) {
10322
+ log_error(`${gobj_short_name(gobj)}: cannot redraw the chart: ${e}`);
10323
+ }
10324
+ return 0;
10325
+ }
10326
+ /******************************************************
10224
10327
  *
10225
10328
  ******************************************************/
10226
10329
  function ac_del_serie(gobj, event, kw, src) {
@@ -10267,7 +10370,8 @@ function create_gclass$14(gclass_name) {
10267
10370
  ["EV_LOAD_DATA", 0],
10268
10371
  ["EV_ADD_SERIE", 0],
10269
10372
  ["EV_DEL_SERIE", 0],
10270
- ["EV_CLEAR", 0]
10373
+ ["EV_CLEAR", 0],
10374
+ ["EV_THEME", 0]
10271
10375
  ], [["ST_IDLE", [
10272
10376
  [
10273
10377
  "EV_LOAD_DATA",
@@ -10288,6 +10392,11 @@ function create_gclass$14(gclass_name) {
10288
10392
  "EV_CLEAR",
10289
10393
  ac_clear,
10290
10394
  null
10395
+ ],
10396
+ [
10397
+ "EV_THEME",
10398
+ ac_theme$4,
10399
+ null
10291
10400
  ]
10292
10401
  ]]], gmt$14, 0, attrs_table$14, PRIVATE_DATA$14, 0, 0, 0, 0);
10293
10402
  if (!__gclass__$14) return -1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuneta/gobj-ui",
3
- "version": "7.23.96",
3
+ "version": "7.23.98",
4
4
  "type": "module",
5
5
  "main": "dist/gobj-ui.cjs.js",
6
6
  "module": "dist/gobj-ui.es.js",
package/src/c_yui_map.js CHANGED
@@ -439,9 +439,27 @@ function load_devices(gobj)
439
439
  source: 'devices',
440
440
  filter: ['has', 'point_count'],
441
441
  layout: {
442
- 'text-field': '{point_count_abbreviated}',
442
+ /* The mark travels INSIDE the count, not as a second symbol
443
+ * layer on the same point: two symbols on one feature is a
444
+ * placement question (and the badge lost it), while a
445
+ * `concat` is just the label this cluster has. */
446
+ 'text-field': ['case',
447
+ ['<', ['get', 'connected'], ['get', 'point_count']],
448
+ ['concat', ['get', 'point_count_abbreviated'], ' !'],
449
+ ['get', 'point_count_abbreviated']
450
+ ],
443
451
  'text-font': ['Noto Sans Regular'],
444
452
  'text-size': 14
453
+ },
454
+ /* It had no paint at all, which is maplibre's black -- on the
455
+ * red circle of a cluster that is 5.25:1 and on the green one
456
+ * 4.09, both of them a number read at a glance. White with a
457
+ * dark halo is 5.14 and 4.0 with the halo behind it, and it is
458
+ * the same ink whatever colour the cluster takes. */
459
+ paint: {
460
+ 'text-color': '#ffffff',
461
+ 'text-halo-color': 'rgba(0,0,0,0.35)',
462
+ 'text-halo-width': 1
445
463
  }
446
464
  });
447
465
 
@@ -459,11 +477,21 @@ function load_devices(gobj)
459
477
  'text-anchor': 'top'
460
478
  },
461
479
  paint: {
480
+ /* A label on a MAP is not text on a page: what is behind it
481
+ * is a tile, and a tile is any colour there is. `green` and
482
+ * `red` measured 4.48 and 3.48 on the beige of a typical
483
+ * street tile -- and over water, forest or an aerial layer
484
+ * the number means nothing at all. The colours are the
485
+ * stronger pair (4.69 / 5.66 on that beige), and the HALO
486
+ * is what actually carries them: it is drawn around every
487
+ * glyph, so the label reads on whatever the tile is. */
462
488
  'text-color': [
463
489
  'case',
464
- ['get', 'connected'], 'green',
465
- 'red'
466
- ]
490
+ ['get', 'connected'], '#1e7a3c',
491
+ '#b3243a'
492
+ ],
493
+ 'text-halo-color': '#ffffff',
494
+ 'text-halo-width': 1.4
467
495
  }
468
496
  });
469
497
 
@@ -484,6 +512,38 @@ function load_devices(gobj)
484
512
  }
485
513
  });
486
514
 
515
+ /* The state is a SHAPE too, and not only a colour.
516
+ *
517
+ * Connected and disconnected were told apart by green vs red
518
+ * alone -- in the circles as in the labels -- and that is the one
519
+ * pair colour blindness does not read; in greyscale the two discs
520
+ * are the same disc. A device that is DOWN carries an exclamation
521
+ * mark on it, and a CLUSTER with something down carries the same
522
+ * mark as a badge at its corner (its middle is taken by the
523
+ * count). One glyph, legible without colour at any zoom, drawn
524
+ * with the font the style already loads -- no image to fetch, so
525
+ * it works offline like the rest of the chapter.
526
+ *
527
+ * Added last, so they draw over the circles they mark. */
528
+ map.addLayer({
529
+ id: 'unclustered-alert',
530
+ type: 'symbol',
531
+ source: 'devices',
532
+ filter: ['all', ['!', ['has', 'point_count']], ['!', ['get', 'connected']]],
533
+ layout: {
534
+ 'text-field': '!',
535
+ 'text-font': ['Noto Sans Regular'],
536
+ 'text-size': 18,
537
+ 'text-allow-overlap': true,
538
+ 'text-ignore-placement': true
539
+ },
540
+ paint: {
541
+ 'text-color': '#ffffff',
542
+ 'text-halo-color': 'rgba(0,0,0,0.45)',
543
+ 'text-halo-width': 1
544
+ }
545
+ });
546
+
487
547
  center_map(gobj);
488
548
 
489
549
  // inspect a cluster on click
@@ -32,6 +32,62 @@ import {
32
32
  import uPlot from "uplot";
33
33
  import "uplot/dist/uPlot.min.css";
34
34
 
35
+ import {yui_is_dark, yui_watch_theme} from "./yui_theme.js";
36
+
37
+
38
+ /***************************************************************
39
+ * The ink of a chart, and its palette.
40
+ *
41
+ * uPlot is built for a white page: its axis labels are `#000`
42
+ * and its grid `rgba(0,0,0,0.07)`, which on the dark scheme are
43
+ * 1.16:1 and 1.04 -- an axis nobody can read and a grid that is
44
+ * not there. And the series were CSS colour names: `blue` is
45
+ * 2.11:1 on the dark ground, `orange` 1.97 on the light one, so
46
+ * whichever scheme you were in, one of the lines was a rumour.
47
+ *
48
+ * These are given to uPlot as FUNCTIONS: it calls them when it
49
+ * draws, so the value can never be stale -- what goes stale is
50
+ * the canvas, and that is what EV_THEME redraws.
51
+ *
52
+ * The palette is six colours that clear 3:1 on BOTH grounds
53
+ * (worst 3.39 on white, 3.71 on near-black), ordered so the
54
+ * first two are the pair that survives colour blindness -- blue
55
+ * and orange, never red and green as the opening pair.
56
+ ***************************************************************/
57
+ function axis_ink()
58
+ {
59
+ return yui_is_dark()? "#c7cdd8" : "#2e333d";
60
+ }
61
+
62
+ function grid_ink()
63
+ {
64
+ return yui_is_dark()? "rgba(199,205,216,0.16)" : "rgba(46,51,61,0.12)";
65
+ }
66
+
67
+ const CHART_PALETTE = [
68
+ {stroke: "#2f6fd0", fill: "rgba(47,111,208,0.10)"}, /* 4.88 / 3.71 */
69
+ {stroke: "#b8620a", fill: "rgba(184,98,10,0.10)"}, /* 4.38 / 4.13 */
70
+ {stroke: "#2f8f4e", fill: "rgba(47,143,78,0.10)"}, /* 4.07 / 4.45 */
71
+ {stroke: "#8b5cf6", fill: "rgba(139,92,246,0.10)"}, /* 4.23 / 4.28 */
72
+ {stroke: "#0e9aa7", fill: "rgba(14,154,167,0.10)"}, /* 3.39 / 5.35 */
73
+ {stroke: "#d1344b", fill: "rgba(209,52,75,0.10)"}, /* 4.88 / 3.71 */
74
+ ];
75
+
76
+ /* The axes the host asked for, with the ink it did not ask about. */
77
+ function themed_axes(axes)
78
+ {
79
+ let list = Array.isArray(axes)? axes : [axes || {}];
80
+ return list.map((ax) => {
81
+ let a = Object.assign({}, ax || {});
82
+ if(a.stroke === undefined) {
83
+ a.stroke = axis_ink;
84
+ }
85
+ a.grid = Object.assign({stroke: grid_ink}, a.grid || {});
86
+ a.ticks = Object.assign({stroke: grid_ink}, a.ticks || {});
87
+ return a;
88
+ });
89
+ }
90
+
35
91
  /***************************************************************
36
92
  * Constants
37
93
  ***************************************************************/
@@ -50,12 +106,8 @@ SDATA(data_type_t.DTP_JSON, "series", 0, [{}], "Data series"),
50
106
  SDATA(data_type_t.DTP_JSON, "axes", 0, [{}], "Chart axes"),
51
107
  SDATA(data_type_t.DTP_JSON, "scales", 0, {}, "Chart scales"),
52
108
  SDATA(data_type_t.DTP_JSON, "data", 0, [[]], "Chart data"),
53
- SDATA(data_type_t.DTP_JSON, "colors", 0, [
54
- {stroke:"red", fill: "rgba(255,0,0,0.05)"},
55
- {stroke:"green", fill: "rgba(0,255,0,0.07)"},
56
- {stroke:"blue", fill: "rgba(0,0,255,0.05)"},
57
- {stroke:"orange", fill: "rgba(255,165,0,0.1)"},
58
- ], "Color settings"),
109
+ SDATA(data_type_t.DTP_JSON, "colors", 0, CHART_PALETTE,
110
+ "Series colours, in order. The default palette clears 3:1 on both schemes and opens with the colour-blind-safe pair (blue, orange)"),
59
111
  SDATA(data_type_t.DTP_POINTER, "$container", 0, null, "HTML container for the chart"),
60
112
  SDATA(data_type_t.DTP_BOOLEAN, "own_container", 0, false, "If true, container is gobj-managed"),
61
113
  SDATA(data_type_t.DTP_POINTER, "uplot", 0, null, "uPlot instance"),
@@ -64,7 +116,9 @@ SDATA(data_type_t.DTP_INTEGER, "timeout_idle", 0, 5, "Idle timeout (s
64
116
  SDATA_END()
65
117
  ];
66
118
 
67
- let PRIVATE_DATA = {};
119
+ let PRIVATE_DATA = {
120
+ theme_observer: null, /* the DOM's data-theme, as an EV_THEME */
121
+ };
68
122
 
69
123
  let __gclass__ = null;
70
124
 
@@ -85,6 +139,11 @@ function mt_create(gobj)
85
139
  {
86
140
  build_ui(gobj);
87
141
 
142
+ /* A canvas does not restyle itself: the ink is read when uPlot
143
+ * DRAWS (see axis_ink), so a theme change only has to reach the
144
+ * machine and ask for a redraw. Same wiring as the graphs. */
145
+ gobj.priv.theme_observer = yui_watch_theme(gobj);
146
+
88
147
  /*
89
148
  * CHILD subscription model
90
149
  */
@@ -114,6 +173,10 @@ function mt_stop(gobj)
114
173
  ***************************************************************/
115
174
  function mt_destroy(gobj)
116
175
  {
176
+ if(gobj.priv.theme_observer) {
177
+ gobj.priv.theme_observer.disconnect();
178
+ gobj.priv.theme_observer = null;
179
+ }
117
180
  let uplot = gobj_read_attr(gobj, "uplot");
118
181
  if(uplot) {
119
182
  uplot.destroy();
@@ -159,7 +222,7 @@ function build_ui(gobj)
159
222
  width: gobj_read_attr(gobj, "width"),
160
223
  height: gobj_read_attr(gobj, "height"),
161
224
  series: gobj_read_attr(gobj, "series"),
162
- axes: gobj_read_attr(gobj, "axes"),
225
+ axes: themed_axes(gobj_read_attr(gobj, "axes")),
163
226
  scales: gobj_read_attr(gobj, "scales"),
164
227
  };
165
228
  let uplot = new uPlot(
@@ -381,11 +444,19 @@ function ac_add_serie(gobj, event, kw, src)
381
444
  return -1;
382
445
  }
383
446
  }
384
- let color = {stroke: "Orange", fill: "rgb(255, 165, 0, 0.05)"};
385
447
  let colors = gobj_read_attr(gobj, "colors");
386
- if(idx<colors.length) {
387
- color = colors[idx];
448
+ if(!Array.isArray(colors) || !colors.length) {
449
+ colors = CHART_PALETTE;
388
450
  }
451
+ /* `idx` counts uPlot's series, and series[0] is the X AXIS -- so
452
+ * the first line drawn was taking colours[1] and the palette's
453
+ * opener, the blue of the colour-blind-safe pair, was never used
454
+ * by anybody. The data series are counted from zero here.
455
+ *
456
+ * And it wraps around instead of falling back to one fixed
457
+ * colour: the old fallback was `Orange`, 1.97:1 on a white page,
458
+ * and it was what every series past the fourth got. */
459
+ let color = colors[Math.max(0, idx - 1) % colors.length];
389
460
  kw_get_str(gobj, kw, "stroke", color.stroke, kw_flag_t.KW_CREATE);
390
461
  kw_get_str(gobj, kw, "fill", color.fill, kw_flag_t.KW_CREATE);
391
462
  //kw["paths"] = beziercurve_path; //rectangle_path;
@@ -393,6 +464,24 @@ function ac_add_serie(gobj, event, kw, src)
393
464
  return 0;
394
465
  }
395
466
 
467
+ /******************************************************
468
+ * The scheme changed: the ink functions answer the new
469
+ * one already, the canvas is what has to be painted again.
470
+ ******************************************************/
471
+ function ac_theme(gobj, event, kw, src)
472
+ {
473
+ let uplot = gobj_read_attr(gobj, "uplot");
474
+ if(!uplot) {
475
+ return 0;
476
+ }
477
+ try {
478
+ uplot.redraw();
479
+ } catch(e) {
480
+ log_error(`${gobj_short_name(gobj)}: cannot redraw the chart: ${e}`);
481
+ }
482
+ return 0;
483
+ }
484
+
396
485
  /******************************************************
397
486
  *
398
487
  ******************************************************/
@@ -466,7 +555,8 @@ function create_gclass(gclass_name)
466
555
  ["EV_LOAD_DATA", ac_load_data, null],
467
556
  ["EV_ADD_SERIE", ac_add_serie, null],
468
557
  ["EV_DEL_SERIE", ac_del_serie, null],
469
- ["EV_CLEAR", ac_clear, null]
558
+ ["EV_CLEAR", ac_clear, null],
559
+ ["EV_THEME", ac_theme, null]
470
560
  ]]
471
561
  ];
472
562
 
@@ -477,7 +567,8 @@ function create_gclass(gclass_name)
477
567
  ["EV_LOAD_DATA", 0],
478
568
  ["EV_ADD_SERIE", 0],
479
569
  ["EV_DEL_SERIE", 0],
480
- ["EV_CLEAR", 0]
570
+ ["EV_CLEAR", 0],
571
+ ["EV_THEME", 0]
481
572
  ];
482
573
 
483
574
  __gclass__ = gclass_create(