问:
Telegraf http input panics
I try to parse an XML file via http from openhab to InfluxDB version 2.1.1, but the service restarts with following error message:

panic: runtime error: invalid memory address or nil pointer dereference

Here is the full output:

```<code>Feb 09 22:36:00 hostname.lan telegraf[2172922]: 2022-02-09T21:36:00Z I! Starting Telegraf 1.21.3
Feb 09 22:36:00 hostname.lan telegraf[2172922]: 2022-02-09T21:36:00Z I! Loaded inputs: http
Feb 09 22:36:00 hostname.lan telegraf[2172922]: 2022-02-09T21:36:00Z I! Loaded aggregators:
Feb 09 22:36:00 hostname.lan telegraf[2172922]: 2022-02-09T21:36:00Z I! Loaded processors:
Feb 09 22:36:00 hostname.lan telegraf[2172922]: 2022-02-09T21:36:00Z I! Loaded outputs: influxdb_v2
Feb 09 22:36:00 hostname.lan telegraf[2172922]: 2022-02-09T21:36:00Z I! Tags enabled:
Feb 09 22:36:00 hostname.lan telegraf[2172922]: 2022-02-09T21:36:00Z I! [agent] Config: Interval:10s, Quiet:false, Hostname:"", Flush Interval:10s
Feb 09 22:36:10 hostname.lan telegraf[2172922]: panic: runtime error: invalid memory address or nil pointer dereference
Feb 09 22:36:10 hostname.lan telegraf[2172922]: [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x94622a]
Feb 09 22:36:10 hostname.lan telegraf[2172922]: goroutine 42 [running]:
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/antchfx/xpath.eqFunc({0x5835860, 0xc00062f520}, {0x42f49a0, 0x831bd20}, {0x42fa9e0, 0xc00100a330})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/pkg/mod/github.com/antchfx/xpath@v1.2.0/operator.go:220 +0x8a
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/antchfx/xpath.(*logicalQuery).Evaluate(0xc001000b70, {0x5835860, 0xc00062f520})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/pkg/mod/github.com/antchfx/xpath@v1.2.0/query.go:724 +0x91
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/antchfx/xpath.(*logicalQuery).Select(0xc000ea1928, {0x5835860, 0xc00062f520})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/pkg/mod/github.com/antchfx/xpath@v1.2.0/query.go:711 +0x57
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/antchfx/xpath.(*NodeIterator).MoveNext(0xc00062f520)
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/pkg/mod/github.com/antchfx/xpath@v1.2.0/xpath.go:86 +0x38
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/antchfx/xmlquery.QuerySelectorAll(0xc000b28d80, 0xc00062f460)
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/pkg/mod/github.com/antchfx/xmlquery@v1.3.9/query.go:116 +0x13a
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/antchfx/xmlquery.QueryAll(0xc000ea1a18, {0xc000d3f0c1, 0x1457f})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/pkg/mod/github.com/antchfx/xmlquery@v1.3.9/query.go:98 +0x52
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/influxdata/telegraf/plugins/parsers/xpath.(*xmlDocument).QueryAll(0xc0006f9c80, {0x48daca0, 0xc000b28d80}, {0xc000d3f0c1, 0xc0006f9cd0})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/src/github.com/influxdata/telegraf/plugins/parsers/xpath/xml_document.go:18 +0x45
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/influxdata/telegraf/plugins/parsers/xpath.(*Parser).Parse(0xc000b28a00, {0xc000f12000, 0x1457f, 0x18000})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/src/github.com/influxdata/telegraf/plugins/parsers/xpath/parser.go:96 +0x2b1
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/influxdata/telegraf/plugins/inputs/http.(*HTTP).gatherURL(0xc000632000, {0x5960588, 0xc0000ad620}, {0xc000d3f001, 0x34})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/src/github.com/influxdata/telegraf/plugins/inputs/http/http.go:235 +0x80d
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/influxdata/telegraf/plugins/inputs/http.(*HTTP).Gather.func1({0xc000d3f001, 0x34})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/src/github.com/influxdata/telegraf/plugins/inputs/http/http.go:144 +0x9e
Feb 09 22:36:10 hostname.lan telegraf[2172922]: created by github.com/influxdata/telegraf/plugins/inputs/http.(*HTTP).Gather
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/src/github.com/influxdata/telegraf/plugins/inputs/http/http.go:142 +0x188
Feb 09 22:36:10 hostname.lan systemd[1]: telegraf.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
Feb 09 22:36:10 hostname.lan systemd[1]: telegraf.service: Failed with result 'exit-code'.
Feb 09 22:36:10 hostname.lan systemd[1]: telegraf.service: Service RestartSec=100ms expired, scheduling restart.
Feb 09 22:36:10 hostname.lan systemd[1]: telegraf.service: Scheduled restart job, restart counter is at 24.
Feb 09 22:36:10 hostname.lan systemd[1]: Stopped The plugin-driven server agent for reporting metrics into InfluxDB.
</code>```

Here you can see my config file as well as the XML-hirarchy I want to insert:

```<code>[global_tags]

[agent]
  interval = "10s"
  round_interval = true
  metric_batch_size = 1000
  metric_buffer_limit = 10000
  collection_jitter = "0s"
  flush_interval = "10s"
  flush_jitter = "0s"
  precision = ""
  debug = false
  quiet = false
  omit_hostname = true

[[outputs.influxdb_v2]]
  urls = ["http://hostname.lan:8086"]
  token = "..."
  organization = "Home"
  bucket = "SmartHome"

[[inputs.http]]
  urls = [
    "http://openhab.lan/addons/xmlapi/statelist.cgi"
  ]

  data_format = "xml"
  tagexclude = ["url", "host"]

  [[inputs.http.xml]]

# <stateList>
#   ...
#   <device name="Hygrometer_LR" ise_id="1555" unreach="false" sticky_unreach="false" config_pending="false">
#     <channel name="Hygrometer_LR:0" ise_id="1556" index="0" visible="" operate="">
#     ...
#     </channel>
#     <channel name="HM-WDS40-TH-I-2 OEQ0161025:1" ise_id="1576" index="1" visible="true" operate="true">
#       <datapoint name="BidCos-RF.OEQ0161025:1.TEMPERATURE" type="TEMPERATURE" ise_id="1578" value="21.700000" valuetype="4" valueunit="°C" timestamp="1644441533" operations="5"/>
#       <datapoint name="BidCos-RF.OEQ0161025:1.HUMIDITY" type="HUMIDITY" ise_id="1577" value="65" valuetype="16" valueunit="%" timestamp="1644441533" operations="5"/>
#     </channel>
#   </device>
#   ...
# </stateList>

  metric_name = "'hygrometer'"
  metric_selection = "/stateList/device/@name=Hygrometer_LR/channel/@ise_id=1576"
  timestamp = "datapoint/@type=TEMPERATURE/@timestamp"
  timestamp_format = "unix"

  [[inputs.http.xml.tags]]
    room = "LR"

  [[inputs.http.xml.fields]]
    humidity = "number(datapoint/@type=HUMIDITY/@value)"
    temperature = "number(datapoint/@type=TEMPERATURE/@value)"
</code>```

Both InfluxDB and Telegraf are running as services on CentOS 8.

And the file information from the URL:

```<code># file /tmp/statelist.cgi
/tmp/statelist.cgi: XML 1.0 document, ISO-8859 text, with very long lines, with no line terminators
</code>```

答:
I got the correct answer from the inlfuxdb-community:</p>
```<code>[[inputs.http.xpath]]
  metric_name = "'hygrometer'"
  metric_selection = "/stateList/device[@name='Hygrometer_LR']/channel[@ise_id='1576']"
  timestamp = "datapoint[@type='TEMPERATURE']/@timestamp"
  timestamp_format = "unix"
  [inputs.http.xpath.tags]
    room = "string(../@name)"
  [inputs.http.xpath.fields]
    humidity = "number(datapoint[@type='HUMIDITY']/@value)"
    temperature = "number(datapoint[@type='TEMPERATURE']/@value)"
</code>```

Title: Telegraf http input panics

Body:
I try to parse an XML file via http from openhab to InfluxDB version 2.1.1, but the service restarts with following error message:

panic: runtime error: invalid memory address or nil pointer dereference

Here is the full output:

Feb 09 22:36:00 hostname.lan telegraf[2172922]: 2022-02-09T21:36:00Z I! Starting Telegraf 1.21.3
Feb 09 22:36:00 hostname.lan telegraf[2172922]: 2022-02-09T21:36:00Z I! Loaded inputs: http
Feb 09 22:36:00 hostname.lan telegraf[2172922]: 2022-02-09T21:36:00Z I! Loaded aggregators:
Feb 09 22:36:00 hostname.lan telegraf[2172922]: 2022-02-09T21:36:00Z I! Loaded processors:
Feb 09 22:36:00 hostname.lan telegraf[2172922]: 2022-02-09T21:36:00Z I! Loaded outputs: influxdb_v2
Feb 09 22:36:00 hostname.lan telegraf[2172922]: 2022-02-09T21:36:00Z I! Tags enabled:
Feb 09 22:36:00 hostname.lan telegraf[2172922]: 2022-02-09T21:36:00Z I! [agent] Config: Interval:10s, Quiet:false, Hostname:"", Flush Interval:10s
Feb 09 22:36:10 hostname.lan telegraf[2172922]: panic: runtime error: invalid memory address or nil pointer dereference
Feb 09 22:36:10 hostname.lan telegraf[2172922]: [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x94622a]
Feb 09 22:36:10 hostname.lan telegraf[2172922]: goroutine 42 [running]:
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/antchfx/xpath.eqFunc({0x5835860, 0xc00062f520}, {0x42f49a0, 0x831bd20}, {0x42fa9e0, 0xc00100a330})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/pkg/mod/github.com/antchfx/xpath@v1.2.0/operator.go:220 +0x8a
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/antchfx/xpath.(*logicalQuery).Evaluate(0xc001000b70, {0x5835860, 0xc00062f520})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/pkg/mod/github.com/antchfx/xpath@v1.2.0/query.go:724 +0x91
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/antchfx/xpath.(*logicalQuery).Select(0xc000ea1928, {0x5835860, 0xc00062f520})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/pkg/mod/github.com/antchfx/xpath@v1.2.0/query.go:711 +0x57
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/antchfx/xpath.(*NodeIterator).MoveNext(0xc00062f520)
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/pkg/mod/github.com/antchfx/xpath@v1.2.0/xpath.go:86 +0x38
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/antchfx/xmlquery.QuerySelectorAll(0xc000b28d80, 0xc00062f460)
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/pkg/mod/github.com/antchfx/xmlquery@v1.3.9/query.go:116 +0x13a
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/antchfx/xmlquery.QueryAll(0xc000ea1a18, {0xc000d3f0c1, 0x1457f})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/pkg/mod/github.com/antchfx/xmlquery@v1.3.9/query.go:98 +0x52
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/influxdata/telegraf/plugins/parsers/xpath.(*xmlDocument).QueryAll(0xc0006f9c80, {0x48daca0, 0xc000b28d80}, {0xc000d3f0c1, 0xc0006f9cd0})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/src/github.com/influxdata/telegraf/plugins/parsers/xpath/xml_document.go:18 +0x45
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/influxdata/telegraf/plugins/parsers/xpath.(*Parser).Parse(0xc000b28a00, {0xc000f12000, 0x1457f, 0x18000})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/src/github.com/influxdata/telegraf/plugins/parsers/xpath/parser.go:96 +0x2b1
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/influxdata/telegraf/plugins/inputs/http.(*HTTP).gatherURL(0xc000632000, {0x5960588, 0xc0000ad620}, {0xc000d3f001, 0x34})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/src/github.com/influxdata/telegraf/plugins/inputs/http/http.go:235 +0x80d
Feb 09 22:36:10 hostname.lan telegraf[2172922]: github.com/influxdata/telegraf/plugins/inputs/http.(*HTTP).Gather.func1({0xc000d3f001, 0x34})
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/src/github.com/influxdata/telegraf/plugins/inputs/http/http.go:144 +0x9e
Feb 09 22:36:10 hostname.lan telegraf[2172922]: created by github.com/influxdata/telegraf/plugins/inputs/http.(*HTTP).Gather
Feb 09 22:36:10 hostname.lan telegraf[2172922]:         /go/src/github.com/influxdata/telegraf/plugins/inputs/http/http.go:142 +0x188
Feb 09 22:36:10 hostname.lan systemd[1]: telegraf.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
Feb 09 22:36:10 hostname.lan systemd[1]: telegraf.service: Failed with result 'exit-code'.
Feb 09 22:36:10 hostname.lan systemd[1]: telegraf.service: Service RestartSec=100ms expired, scheduling restart.
Feb 09 22:36:10 hostname.lan systemd[1]: telegraf.service: Scheduled restart job, restart counter is at 24.
Feb 09 22:36:10 hostname.lan systemd[1]: Stopped The plugin-driven server agent for reporting metrics into InfluxDB.

Here you can see my config file as well as the XML-hirarchy I want to insert:

[global_tags]

[agent]
  interval = "10s"
  round_interval = true
  metric_batch_size = 1000
  metric_buffer_limit = 10000
  collection_jitter = "0s"
  flush_interval = "10s"
  flush_jitter = "0s"
  precision = ""
  debug = false
  quiet = false
  omit_hostname = true

[[outputs.influxdb_v2]]
  urls = ["http://hostname.lan:8086"]
  token = "..."
  organization = "Home"
  bucket = "SmartHome"

[[inputs.http]]
  urls = [
    "http://openhab.lan/addons/xmlapi/statelist.cgi"
  ]

  data_format = "xml"
  tagexclude = ["url", "host"]

  [[inputs.http.xml]]

# <stateList>
#   ...
#   <device name="Hygrometer_LR" ise_id="1555" unreach="false" sticky_unreach="false" config_pending="false">
#     <channel name="Hygrometer_LR:0" ise_id="1556" index="0" visible="" operate="">
#     ...
#     </channel>
#     <channel name="HM-WDS40-TH-I-2 OEQ0161025:1" ise_id="1576" index="1" visible="true" operate="true">
#       <datapoint name="BidCos-RF.OEQ0161025:1.TEMPERATURE" type="TEMPERATURE" ise_id="1578" value="21.700000" valuetype="4" valueunit="°C" timestamp="1644441533" operations="5"/>
#       <datapoint name="BidCos-RF.OEQ0161025:1.HUMIDITY" type="HUMIDITY" ise_id="1577" value="65" valuetype="16" valueunit="%" timestamp="1644441533" operations="5"/>
#     </channel>
#   </device>
#   ...
# </stateList>

  metric_name = "'hygrometer'"
  metric_selection = "/stateList/device/@name=Hygrometer_LR/channel/@ise_id=1576"
  timestamp = "datapoint/@type=TEMPERATURE/@timestamp"
  timestamp_format = "unix"

  [[inputs.http.xml.tags]]
    room = "LR"

  [[inputs.http.xml.fields]]
    humidity = "number(datapoint/@type=HUMIDITY/@value)"
    temperature = "number(datapoint/@type=TEMPERATURE/@value)"

Both InfluxDB and Telegraf are running as services on CentOS 8.

And the file information from the URL:

# file /tmp/statelist.cgi
/tmp/statelist.cgi: XML 1.0 document, ISO-8859 text, with very long lines, with no line terminators

Body:
I got the correct answer from the inlfuxdb-community:

[[inputs.http.xpath]]
  metric_name = "'hygrometer'"
  metric_selection = "/stateList/device[@name='Hygrometer_LR']/channel[@ise_id='1576']"
  timestamp = "datapoint[@type='TEMPERATURE']/@timestamp"
  timestamp_format = "unix"
  [inputs.http.xpath.tags]
    room = "string(../@name)"
  [inputs.http.xpath.fields]
    humidity = "number(datapoint[@type='HUMIDITY']/@value)"
    temperature = "number(datapoint[@type='TEMPERATURE']/@value)"


来源: stackexchange

问:
How to add horizontal scroll in paginated Data Table in flutter web
I have used Paginated Data Table in flutter web. On smaller screen, the table adjust it's width but hides the data column, I want to scroll the Data table horizontally, so that I am able to go through the whole data columns, added in the Paginated Data Table. (don't want to use any package)

Thanks in advance

Here is my code

```<code>SingleChildScrollView(
      child: Container(
        padding: EdgeInsets.all(10),
        color: AppColors.grey,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
               CustomIconButton(
                buttonText: "Add School",
                onTap: () {}
              ),

            SizedBox(height: 15),

            PaginatedDataTable(
              source: _schoolData,
              dragStartBehavior: DragStartBehavior.start,

              header: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Padding(
                    padding: const EdgeInsets.all(20),
                    child: CustomText(
                      text: "School Overview",
                      fontSize: 20,
                    ),
                  ),
                  Divider(height: 0),
                ],
              ),
              columns:  [
                _createDataColumn("ID"),
                _createDataColumn("Name"),
                _createDataColumn("User Name"),
                _createDataColumn("Email"),
                _createDataColumn("City"),
                _createDataColumn("Country"),
                _createDataColumn("Grading"),
                _createDataColumn("Archive"),
                _createDataColumn("Education Level"),
                _createDataColumn(""),
              ],
              columnSpacing: 100,
              horizontalMargin: 10,
              rowsPerPage: 8,
              showCheckboxColumn: false,
              dataRowHeight: 70,
              arrowHeadColor: AppColors.darkBlue,

            ),
          ],
        ),
      ),
    );
</code>```

答:
On web You have to add custom MaterialScrollBehavior and call inside MaterialApp which will be help you to enable scroll in web.

```<code>class MyCustomScrollBehavior extends MaterialScrollBehavior {
  // Override behavior methods and getters like dragDevices
  @override
  Set<PointerDeviceKind> get dragDevices => {
        PointerDeviceKind.touch,
        PointerDeviceKind.mouse,
      };
}
</code>```

main.dart

```<code>void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      scrollBehavior: MyCustomScrollBehavior(), // <== add here
      title: 'Flutter App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Home Page'),
    );
  }
}
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have used Paginated Data Table in flutter web. On smaller screen, the table adjust it's width but hides the data column, I want to scroll the Data table horizontally, so that I am able to go through the whole data columns, added in the Paginated Data Table. (don't want to use any package)

Thanks in advance

Here is my code

SingleChildScrollView(
      child: Container(
        padding: EdgeInsets.all(10),
        color: AppColors.grey,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
               CustomIconButton(
                buttonText: "Add School",
                onTap: () {}
              ),

            SizedBox(height: 15),

            PaginatedDataTable(
              source: _schoolData,
              dragStartBehavior: DragStartBehavior.start,

              header: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Padding(
                    padding: const EdgeInsets.all(20),
                    child: CustomText(
                      text: "School Overview",
                      fontSize: 20,
                    ),
                  ),
                  Divider(height: 0),
                ],
              ),
              columns:  [
                _createDataColumn("ID"),
                _createDataColumn("Name"),
                _createDataColumn("User Name"),
                _createDataColumn("Email"),
                _createDataColumn("City"),
                _createDataColumn("Country"),
                _createDataColumn("Grading"),
                _createDataColumn("Archive"),
                _createDataColumn("Education Level"),
                _createDataColumn(""),
              ],
              columnSpacing: 100,
              horizontalMargin: 10,
              rowsPerPage: 8,
              showCheckboxColumn: false,
              dataRowHeight: 70,
              arrowHeadColor: AppColors.darkBlue,

            ),
          ],
        ),
      ),
    );

Body:
On web You have to add custom MaterialScrollBehavior and call inside MaterialApp which will be help you to enable scroll in web.

class MyCustomScrollBehavior extends MaterialScrollBehavior {
  // Override behavior methods and getters like dragDevices
  @override
  Set<PointerDeviceKind> get dragDevices => {
        PointerDeviceKind.touch,
        PointerDeviceKind.mouse,
      };
}

main.dart

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      scrollBehavior: MyCustomScrollBehavior(), // <== add here
      title: 'Flutter App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Home Page'),
    );
  }
}


问:
Opening large file (200mb) on iPhone?
want to open a large text file and then search the content of it.
I loaded the file with stringWithContentsOfFile into a NSString.
Every thing works on a 30mb file. But I am concerned what happens if I load a 200mb file, which I want to do.
Is the complete NSString in the memory? if so it wouldn't work on iPhone. is there a solution for such large files on the iPhone?</p>

答:
A good way to read a large file would be to buffer small chunks of it at a time.

Not sure of the exact API methods you could use to do this, but it is fairly standard practice for audio, video, etc to read a small amount of the file into memory, process this, and remove it from memory as you continue through the file.

ContentLicense: CC BY-SA 3.0

Title: Opening large file (200mb) on iPhone?


问:
Dynamically name x-node of networkD3 sankey
I am trying to have produce a shiny application in which a Sankey plot, produced using NetworkD3, dynamically produces x-node labels. I think this requires passing a reactive element to onRender, but I am not sure how to do this.

I see an answer here: How to add columnn titles in a Sankey chart networkD3, but this solves the dynamic naming by calling .text("Step " + (i + 1)); in the onRender function. My labels are not so generic that I can just iterate and paste (the example below uses simplified names).

Here is an example:

```<code>library('shiny')
library('tidyverse')
library('networkD3')
library(shinyWidgets)
library(htmlwidgets)

#Create the data
df <- data.frame('A' = c('a', 'b', 'b', 'c', 'a'),
                 'B' = c('1', '1', '1', '2', '3'),
                 'C' = c('red', 'blue', 'blue', 'green', 'green'))

#Create the UI
ui <- fluidPage(
  #Sidebar to select x-nodes
  sidebarLayout(
    sidebarPanel(
      pickerInput(inputId = 'var_select',
                  label = 'Variables',
                  choices = colnames(df),
                  selected = colnames(df),
                  multiple = TRUE,
                  pickerOptions(actionsBox = TRUE))
    ),
   #Mainpanel to show sankey plot
    mainPanel(
     sankeyNetworkOutput('plot',
                         height = '800px')
   )
  )
)

#Create the server
server <- function(input, session, output) {
  #create a reactive function that outputs the selected variables
  df_sankey <- reactive({
    df %>%
      select(input$var_select)
  })

  #Prepare for plotting in NetworkD3
  links1 <- reactive({
    df_sankey() %>%
      mutate(row = row_number()) %>%  # add a row id
      pivot_longer(-row, names_to = "col", values_to = "source") %>%  # gather all columns
      mutate(col = match(col, names(df_sankey()))) %>%  # convert col names to col ids
      mutate(source = paste0(source, '_', col)) %>%  # add col id to node names
      group_by(row) %>%
      mutate(target = lead(source, order_by = col)) %>%  # get target from following node in row
      ungroup() %>%
      filter(!is.na(target)) %>%  # remove links from last column in original data
      group_by(source, target) %>%
      summarise(value = n(), .groups = "drop")  # aggregate and count similar links
  })

  #Now create the nodes
  nodes <- reactive({
    data.frame(id = unique(c(links1()$source, links1()$target)),
               stringsAsFactors = F) %>%
      mutate(name = sub('_[0-9]*$', '', id))
  })

  #Mutate a soutrce id variable - have to create this as links2 to prevent endless recursion
  links2 <- reactive({
    mutate(links1(), source_id = match(links1()$source, nodes()$id) - 1)
  })

  #Do the same for target id
  links <- reactive({
    mutate(links2(), target_id = match(links2()$target, nodes()$id) - 1) %>%
      data.frame()
  })

  #Build the sankey plot
  plot1 <- reactive({
    sankeyNetwork(Links = links(), Nodes = nodes(),
                  Source = 'source_id', Target = 'target_id', Value = 'value', NodeID = 'name',
                  fontSize = 14)
  })

  #Here is the problematic code
  #under code starting var labels - i need that to be produced by a reactive element: colnames(df_sankey())
  #Without this it just take the number of var labels as there are selected variables
  output$plot <- renderSankeyNetwork({
    onRender(plot1(), '
      function(el) {
        var cols_x = this.sankey.nodes().map(d => d.x).filter((v, i, a) => a.indexOf(v) === i).sort(function(a, b){return a - b});
        var labels = ["A", "B", "C"];
        cols_x.forEach((d, i) => {
          d3.select(el).select("svg")
            .append("text")
            .attr("x", d)
            .attr("y", 12)
            .text(labels[i]);
        })
      }
    ')
  })

}

#call the application
shinyApp(ui, server)
</code>```

I call out the problem in the comments above the onRender function. Effectively I need var labels to take a reactive function generated by something like: colnames(df_sankey()). If i put that code in for var labels (which i appreciate is a wild guess), it just fails. Without the reactive function the code just loops through the var labels according to the number of variables selected. You can see the problem if you select var A and C - C gets labelled B. I also tried (another guess):

```<code>  output$plot <- renderSankeyNetwork({
    onRender(plot1(), '
      function(el, node_labels) {
        var cols_x = this.sankey.nodes().map(d => d.x).filter((v, i, a) => a.indexOf(v) === i).sort(function(a, b){return a - b});
        var labels = [node_labels];
        cols_x.forEach((d, i) => {
          d3.select(el).select("svg")
            .append("text")
            .attr("x", d)
            .attr("y", 12)
            .text(labels[i]);
        })
      }
    ', node_labels = colnames(df_sankey()))
</code>```

But that also fails. I can't seem to find an explanation for how to pass reactive functions to onRender.

How can I pass a reactive function to the onRender function so that i can dynamically name my x-nodes?

答:
The jsCode argument of htmlwidgets::onRender() is simply a character vector that happens to contain valid JavaScript code, so you can build/modify that just as you can any other string in R. If you want to set the array values of the var labels = ["A", "B", "C"]; line of the JavaScript dynamically, you could do something like this...

col_labels <- c("A", "B", "C")
col_lables_js_arrray_string <- paste0('["', paste(col_labels, collapse = '", "'), '"]')

render_js <- paste('
function(el) {
  var cols_x = this.sankey.nodes()
    .map(d => d.x)
    .filter((v, i, a) => a.indexOf(v) === i)
    .sort(function(a, b){return a - b});
  var labels = ', col_lables_js_arrray_string, ';
  cols_x.forEach((d, i) => {
    d3.select(el).select("svg")
    .append("text")
    .attr("x", d)
    .attr("y", 12)
    .text(labels[i]);
  })
}
')

htmlwidgets::onRender(x = p, jsCode = render_js)
```

Body:
I am trying to have produce a shiny application in which a Sankey plot, produced using NetworkD3, dynamically produces x-node labels. I think this requires passing a reactive element to onRender, but I am not sure how to do this.

I see an answer here: How to add columnn titles in a Sankey chart networkD3, but this solves the dynamic naming by calling .text("Step " + (i + 1)); in the onRender function. My labels are not so generic that I can just iterate and paste (the example below uses simplified names).

Here is an example:

library('shiny')
library('tidyverse')
library('networkD3')
library(shinyWidgets)
library(htmlwidgets)

#Create the data
df <- data.frame('A' = c('a', 'b', 'b', 'c', 'a'),
                 'B' = c('1', '1', '1', '2', '3'),
                 'C' = c('red', 'blue', 'blue', 'green', 'green'))

#Create the UI
ui <- fluidPage(
  #Sidebar to select x-nodes
  sidebarLayout(
    sidebarPanel(
      pickerInput(inputId = 'var_select',
                  label = 'Variables',
                  choices = colnames(df),
                  selected = colnames(df),
                  multiple = TRUE,
                  pickerOptions(actionsBox = TRUE))
    ),
   #Mainpanel to show sankey plot
    mainPanel(
     sankeyNetworkOutput('plot',
                         height = '800px')
   )
  )
)

#Create the server
server <- function(input, session, output) {
  #create a reactive function that outputs the selected variables
  df_sankey <- reactive({
    df %>%
      select(input$var_select)
  })

  #Prepare for plotting in NetworkD3
  links1 <- reactive({
    df_sankey() %>%
      mutate(row = row_number()) %>%  # add a row id
      pivot_longer(-row, names_to = "col", values_to = "source") %>%  # gather all columns
      mutate(col = match(col, names(df_sankey()))) %>%  # convert col names to col ids
      mutate(source = paste0(source, '_', col)) %>%  # add col id to node names
      group_by(row) %>%
      mutate(target = lead(source, order_by = col)) %>%  # get target from following node in row
      ungroup() %>%
      filter(!is.na(target)) %>%  # remove links from last column in original data
      group_by(source, target) %>%
      summarise(value = n(), .groups = "drop")  # aggregate and count similar links
  })

  #Now create the nodes
  nodes <- reactive({
    data.frame(id = unique(c(links1()$source, links1()$target)),
               stringsAsFactors = F) %>%
      mutate(name = sub('_[0-9]*$', '', id))
  })

  #Mutate a soutrce id variable - have to create this as links2 to prevent endless recursion
  links2 <- reactive({
    mutate(links1(), source_id = match(links1()$source, nodes()$id) - 1)
  })

  #Do the same for target id
  links <- reactive({
    mutate(links2(), target_id = match(links2()$target, nodes()$id) - 1) %>%
      data.frame()
  })

  #Build the sankey plot
  plot1 <- reactive({
    sankeyNetwork(Links = links(), Nodes = nodes(),
                  Source = 'source_id', Target = 'target_id', Value = 'value', NodeID = 'name',
                  fontSize = 14)
  })

  #Here is the problematic code
  #under code starting var labels - i need that to be produced by a reactive element: colnames(df_sankey())
  #Without this it just take the number of var labels as there are selected variables
  output$plot <- renderSankeyNetwork({
    onRender(plot1(), '
      function(el) {
        var cols_x = this.sankey.nodes().map(d => d.x).filter((v, i, a) => a.indexOf(v) === i).sort(function(a, b){return a - b});
        var labels = ["A", "B", "C"];
        cols_x.forEach((d, i) => {
          d3.select(el).select("svg")
            .append("text")
            .attr("x", d)
            .attr("y", 12)
            .text(labels[i]);
        })
      }
    ')
  })

}

#call the application
shinyApp(ui, server)

I call out the problem in the comments above the onRender function. Effectively I need var labels to take a reactive function generated by something like: colnames(df_sankey()). If i put that code in for var labels (which i appreciate is a wild guess), it just fails. Without the reactive function the code just loops through the var labels according to the number of variables selected. You can see the problem if you select var A and C - C gets labelled B. I also tried (another guess):

  output$plot <- renderSankeyNetwork({
    onRender(plot1(), '
      function(el, node_labels) {
        var cols_x = this.sankey.nodes().map(d => d.x).filter((v, i, a) => a.indexOf(v) === i).sort(function(a, b){return a - b});
        var labels = [node_labels];
        cols_x.forEach((d, i) => {
          d3.select(el).select("svg")
            .append("text")
            .attr("x", d)
            .attr("y", 12)
            .text(labels[i]);
        })
      }
    ', node_labels = colnames(df_sankey()))

But that also fails. I can't seem to find an explanation for how to pass reactive functions to onRender.

How can I pass a reactive function to the onRender function so that i can dynamically name my x-nodes?


问:
How to add condition to test http request using httptest in golang
I am beginner in golang and started working on backend RBAC application to manage access of  Kubernetes cluster, we have a monitoring stack that is behind proxy serves prometheus , thanos and grafana URL. I am not able to add conditions to check HTTP status using httptest. I have to add condition if pods are up and running else print the error.

```<code>rq := httptest.NewRequest("GET", "/", nil)
rw := httptest.NewRecorder()
proxy.ServeHTTP(rw, rq)

if rw.Code != 200 && monitoringArgs.selector == "PROMETHEUS" {

    fmt.Printf("Target pods are in error state, please check with 'oc get pods -n %s -l %s'", monitoringArgs.namespace, monitoringArgs.selector)

}
</code>```

How can I added condition for all three prometheus/grafana/Thanos

答:
You can use the restart count of POD also in logic something like</p>
```<code>pods, err := clientset.CoreV1().Pods(namespace).List(metav1.ListOptions{
    LabelSelector: "app=myapp",
})

// check status for the pods - to see Probe status
for _, pod := range pods.Items {
    pod.Status.Conditions // use your custom logic here

    for _, container := range pod.Status.ContainerStatuses {
        container.RestartCount // use this number in your logic
    }
}
</code>```

Body:
I am beginner in golang and started working on backend RBAC application to manage access of  Kubernetes cluster, we have a monitoring stack that is behind proxy serves prometheus , thanos and grafana URL. I am not able to add conditions to check HTTP status using httptest. I have to add condition if pods are up and running else print the error.

rq := httptest.NewRequest("GET", "/", nil)
rw := httptest.NewRecorder()
proxy.ServeHTTP(rw, rq)

if rw.Code != 200 && monitoringArgs.selector == "PROMETHEUS" {

    fmt.Printf("Target pods are in error state, please check with 'oc get pods -n %s -l %s'", monitoringArgs.namespace, monitoringArgs.selector)

}

How can I added condition for all three prometheus/grafana/Thanos

Body:
You can use the restart count of POD also in logic something like

pods, err := clientset.CoreV1().Pods(namespace).List(metav1.ListOptions{
    LabelSelector: "app=myapp",
})

// check status for the pods - to see Probe status
for _, pod := range pods.Items {
    pod.Status.Conditions // use your custom logic here

    for _, container := range pod.Status.ContainerStatuses {
        container.RestartCount // use this number in your logic
    }
}


问:
Manifest: Line: 1, column: 1, Syntax error
This is the hosted url: https://serviceworkerspike.azurewebsites.net/ - Doesn't work anymore

I'm using Vuejs to create a PWA as a school project, and whenever I host the website with Azure this happens, I don't have the problem on localhost...
Chrome devtools responds with this:

```<code>/manifest.json:1 Failed to load resource: the server responded with a status of 404 ()
/manifest.json:1 Manifest: Line: 1, column: 1, Syntax error.
manifest.json:1 GET https://serviceworkerspike.azurewebsites.net/manifest.json 404
manifest.json:1 Manifest: Line: 1, column: 1, Syntax error.
</code>```

I have this added in my index.html:

```<code><link rel="manifest" href="/manifest.json">
</code>```

This is my manifest.json file:

```<code>{
  "name": "MessageBoardUCN",
  "short_name": "MessageBoardUCN",
  "theme_color": "#ff095a",
  "background_color": "#feaaee",
  "display": "standalone",
  "start_url": "/index.html",
  "icons": [
    {
      "src": "images/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "splash_pages": null
}
</code>```

I have tried to do the name and shortname properties like this: "messageboarducn"

I have also tried editing the starturl to the hosted url: "https://serviceworkerspike.azurewebsites.net/" and "/"

I have also tried moving the manifest.json file in the root directory and /src directory, but other guides told me it should be in the same folder as index.html and the /public is default for that

This is my file structure

Normally you don't have a web.config file with Vuejs, but I even tried adding one which looks like this:

```<code><?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.webServer>
    <staticContent>
      <remove fileExtension=".json" />
      <mimeMap fileExtension=".json" mimeType="application/json" />
      <mimeMap fileExtension=".webmanifest" mimeType="application/manifest+json" />
    </staticContent>
  </system.webServer>
</configuration>
</code>```

How can I correct the mistake?

答:
 <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />remove this line from the index.html header file
or create the manifest.json file inside the public directory

Body:
This is the hosted url: https://serviceworkerspike.azurewebsites.net/ - Doesn't work anymore

I'm using Vuejs to create a PWA as a school project, and whenever I host the website with Azure this happens, I don't have the problem on localhost...
Chrome devtools responds with this:

/manifest.json:1 Failed to load resource: the server responded with a status of 404 ()
/manifest.json:1 Manifest: Line: 1, column: 1, Syntax error.
manifest.json:1 GET https://serviceworkerspike.azurewebsites.net/manifest.json 404
manifest.json:1 Manifest: Line: 1, column: 1, Syntax error.

I have this added in my index.html:

<link rel="manifest" href="/manifest.json">

This is my manifest.json file:

{
  "name": "MessageBoardUCN",
  "short_name": "MessageBoardUCN",
  "theme_color": "#ff095a",
  "background_color": "#feaaee",
  "display": "standalone",
  "start_url": "/index.html",
  "icons": [
    {
      "src": "images/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "images/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "splash_pages": null
}

I have tried to do the name and shortname properties like this: "messageboarducn"

I have also tried editing the starturl to the hosted url: "https://serviceworkerspike.azurewebsites.net/" and "/"

I have also tried moving the manifest.json file in the root directory and /src directory, but other guides told me it should be in the same folder as index.html and the /public is default for that

This is my file structure

Normally you don't have a web.config file with Vuejs, but I even tried adding one which looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.webServer>
    <staticContent>
      <remove fileExtension=".json" />
      <mimeMap fileExtension=".json" mimeType="application/json" />
      <mimeMap fileExtension=".webmanifest" mimeType="application/manifest+json" />
    </staticContent>
  </system.webServer>
</configuration>

How can I correct the mistake?


问:
Change
 height using CSS
I have seen a question here about the same, but I can't get any of the answers to work (at least on Chrome).

This question is only for
, I know plenty of other techniques to change the height but in this case I can't change the HTML.

```<code>bla<BR><BR>bla<BR>bla<BR><BR>bla
</code>```

CSS:

br {
  display: block;
  margin-bottom: 2px;
  font-size:2px;
  line-height: 2px;
}
```

Desired effect: smaller inter-line height.

The only thing I can get to work is display:none, but then all line break are removed.

Here's a fiddle for it using some of the techniques, but see that it renders the exact same as without any CSS.

答:
You can write br tag as show

```<code><br style="content:''; padding: 10px 0;" />
</code>```

Change padding value to 10px to anything you like.

Note: As padding is specified, height increases in both directions(top and bottom)

Title: Change <br> height using CSS

Body:
I have seen a question here about the same, but I can't get any of the answers to work (at least on Chrome).

This question is only for
, I know plenty of other techniques to change the height but in this case I can't change the HTML.

bla

bla
bla

bla

CSS:

br {
  display: block;
  margin-bottom: 2px;
  font-size:2px;
  line-height: 2px;
}

Desired effect: smaller inter-line height.

The only thing I can get to work is display:none, but then all line break are removed.

Here's a fiddle for it using some of the techniques, but see that it renders the exact same as without any CSS.

Body:
You can write br tag as show

<br style="content:''; padding: 10px 0;" />

Change padding value to 10px to anything you like.

Note: As padding is specified, height increases in both directions(top and bottom)


问:
react native navigate between screen
I have a project in react native in which I wanted to implement a feature.
I have three screens

slash screen

login screen

home screen

the slash screens last 1 second and leave on the home screen while the number of times the app has been opened does not exceed 3 times.
otherwise we display the login screen to ask for a password

答:
About how to make the splash screen last 1 second, on Splash component, put an useEffect like this:

```<code>function Splash({ navigation }) {
useEffect(() => setTimeout(navigation.navigate('Home')),[]);

  return (
    <View>
      <Image />
    </View>
  );
}
</code>```

About conditional first screen when open the app, you can pass initialRouteName as a prop of Stack.Navigator:

```<code>import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

function App() {
  return (
    <Stack.Navigator initialRouteName={times < 3 ? Slash : Login}>
      <Stack.Screen name="Slash" component={Slash} />
      <Stack.Screen name="Home" component={Home} />
      <Stack.Screen name="Login" component={Login} />
    </Stack.Navigator>
  );
}
</code>```

Note: my examples above use StackNavigator and on React Navigation v6, it works the same as TabNavigator and other versions of React Navigation.

Title: react native navigate between screen

Body:
About how to make the splash screen last 1 second, on Splash component, put an useEffect like this:

function Splash({ navigation }) {
useEffect(() => setTimeout(navigation.navigate('Home')),[]);

  return (
    <View>
      <Image />
    </View>
  );
}

About conditional first screen when open the app, you can pass initialRouteName as a prop of Stack.Navigator:

import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

function App() {
  return (
    <Stack.Navigator initialRouteName={times < 3 ? Slash : Login}>
      <Stack.Screen name="Slash" component={Slash} />
      <Stack.Screen name="Home" component={Home} />
      <Stack.Screen name="Login" component={Login} />
    </Stack.Navigator>
  );
}

Note: my examples above use StackNavigator and on React Navigation v6, it works the same as TabNavigator and other versions of React Navigation.


问:
Changing class of same id
I'm looking for a method to change the class of the same id's. I have a table with multiple rows and some parent-child 'rows'. Thus when clicked on the parent, the class of the child has to change aswell. I have the following code:

```<code>function FormTRClick(event, ctrl) {
   if (event.target.tagName == 'TD') {
       if (document.getElementById('chk' + ctrl).checked == true) {
           document.getElementById('chk' + ctrl).checked = false;
           document.getElementById('row' + ctrl).className = "invoice-tr-standard";
       } else {
           document.getElementById('chk' + ctrl).checked = true;
           document.getElementById('row' + ctrl).className = "invoice-tr-clicked";
       }
   }
}
</code>```

This script is called by:
 and each parent has a new ID (so parent + child carry the same ID).

How can I do this? Do I have to put the elements into an array and then loop through them to give them the proper classname? Or is there any other way todo so?

Thanks.

Update

I have a table, with multiple rows. I have it like this:

```<code>row1 Parent
  row1 Child
  row1 Child
row2 Parent
  row2 Child
row3 Parent
row4 Parent
  row4 Child
</code>```

I want the className of all row1 (or row2, depends on which one has been clicked on) to be changed to invoice-tr-clicked when clicked on the
 as seen above.

So, when clicked on a 'parent' the 'child' rows (since they share the same ID) have to have their classnames changed into invoice-tr-clicked or invoice-tr-standard depending on their current style.

HTML code as from the page

```<code><tr class='invoice-tr-standard' id='row1' onClick="FormTRClick(event, '1')"><td><input type='checkbox' name='strFormFactuur[]' value='19796' id='chk1'> <img src='../images/link.png' border='0'></td>
    <td>€ <input type='text' value='19.001' id='fltFormTextBedrag1'> <img src='../images/b_save.png' border='0' height='13px' style='cursor: pointer;'></td>
</tr>
<tr class='invoice-tr-standard' id='row1' onClick="FormTRClick(event, '1')"><td></td>
    <td>€ <input type='text' name='FormTextFltBedrag' value='19.000'> <img src='../images/b_save.png' border='0' height='13px' style='cursor: pointer;'></td>
</tr>
<tr class='invoice-tr-standard' id='row1' onClick="FormTRClick(event, '1')"><td></td>
    <td>€ <input type='text' name='FormTextFltBedrag' value='19.000'> <img src='../images/b_save.png' border='0' height='13px' style='cursor: pointer;'></td>
</tr>
<tr class='invoice-tr-standard' id='row2' onClick="FormTRClick(event, '2')"><td><input type='checkbox' name='strFormFactuur[]' value='19436' id='chk2'> <img src='../images/link.png' border='0'></td>
    <td>€ <input type='text' value='61.280' id='fltFormTextBedrag4'> <img src='../images/b_save.png' border='0' height='13px' style='cursor: pointer;'></td>
</tr>
<tr class='invoice-tr-standard' id='row2' onClick="FormTRClick(event, '2')"><td></td>
    <td>€ <input type='text' name='FormTextFltBedrag' value='61.280'> <img src='../images/b_save.png' border='0' height='13px' style='cursor: pointer;'></td>
</tr>
<tr class='invoice-tr-standard' id='row3' onClick="FormTRClick(event, '3')"><td><input type='checkbox' name='strFormFactuur[]' value='19718' id='chk3'></td>
    <td>€ <input type='text' value='162.340' id='fltFormTextBedrag6'> <img src='../images/b_save.png' border='0' height='13px' style='cursor: pointer;'></td>
</tr>
<tr class='invoice-tr-standard' id='row3' onClick="FormTRClick(event, '3')"><td></td>
    <td>€ <input type='text' name='FormTextFltBedrag' value='162.340'> <img src='../images/b_save.png' border='0' height='13px' style='cursor: pointer;'></td>
</tr>
</code>```

答:
Give your rows two-part unique ids like this:

```<code>row1_1 Parent
  row1_2 Child
  row1_3 Child
row2_1 Parent
  row2_2 Child
row3_1 Parent
row4_1 Parent
  row4_2 Child
</code>```

And change the class switch part of your code to:

```<code>var i = 1;
var element;
while( ( element = document.getElementById( 'chk' + ctrl + '_' + i ) ) !== null ) {
    if (element.checked == true) {
       element.checked = false;
       element.className = "invoice-tr-standard";
    } else {
       element.checked = true;
       element.className = "invoice-tr-clicked";
    }
    ++i;
}
</code>```

Title: Changing class of same id

Body:
I'm looking for a method to change the class of the same id's. I have a table with multiple rows and some parent-child 'rows'. Thus when clicked on the parent, the class of the child has to change aswell. I have the following code:

function FormTRClick(event, ctrl) {
   if (event.target.tagName == 'TD') {
       if (document.getElementById('chk' + ctrl).checked == true) {
           document.getElementById('chk' + ctrl).checked = false;
           document.getElementById('row' + ctrl).className = "invoice-tr-standard";
       } else {
           document.getElementById('chk' + ctrl).checked = true;
           document.getElementById('row' + ctrl).className = "invoice-tr-clicked";
       }
   }
}

This script is called by:
 and each parent has a new ID (so parent + child carry the same ID).

How can I do this? Do I have to put the elements into an array and then loop through them to give them the proper classname? Or is there any other way todo so?

Thanks.

Update

I have a table, with multiple rows. I have it like this:

row1 Parent
  row1 Child
  row1 Child
row2 Parent
  row2 Child
row3 Parent
row4 Parent
  row4 Child

I want the className of all row1 (or row2, depends on which one has been clicked on) to be changed to invoice-tr-clicked when clicked on the
 as seen above.

So, when clicked on a 'parent' the 'child' rows (since they share the same ID) have to have their classnames changed into invoice-tr-clicked or invoice-tr-standard depending on their current style.

HTML code as from the page

<input type='checkbox' name='strFormFactuur[]' value='19796' id='chk1'>
    € <input type='text' value='19.001' id='fltFormTextBedrag1'>

    € <input type='text' name='FormTextFltBedrag' value='19.000'>

    € <input type='text' name='FormTextFltBedrag' value='19.000'>

<input type='checkbox' name='strFormFactuur[]' value='19436' id='chk2'>
    € <input type='text' value='61.280' id='fltFormTextBedrag4'>

    € <input type='text' name='FormTextFltBedrag' value='61.280'>

<input type='checkbox' name='strFormFactuur[]' value='19718' id='chk3'>
    € <input type='text' value='162.340' id='fltFormTextBedrag6'>

    € <input type='text' name='FormTextFltBedrag' value='162.340'>

Body:
Give your rows two-part unique ids like this:

row1_1 Parent
  row1_2 Child
  row1_3 Child
row2_1 Parent
  row2_2 Child
row3_1 Parent
row4_1 Parent
  row4_2 Child

And change the class switch part of your code to:

var i = 1;
var element;
while( ( element = document.getElementById( 'chk' + ctrl + '_' + i ) ) !== null ) {
    if (element.checked == true) {
       element.checked = false;
       element.className = "invoice-tr-standard";
    } else {
       element.checked = true;
       element.className = "invoice-tr-clicked";
    }
    ++i;
}


问:
Synchronising with mutex and relaxed memory order atomic
I have a shared data structure that is already internally synchronised with a mutex. Can I use an atomic with memory order relaxed to signal changes. A very simplified view of what I mean in code

Thread 1

shared_conf.set("somekey","someval");
is_reconfigured.store(true, std::memory_order_relaxed);
```
<p>Thread 2</p>
```if (is_reconfigured.load(std::memory_order_relaxed)) {
  inspect_shared_conf();
}
```

Is it guaranteed that I'll see updates in the shared_map?; the shared map itself internally synchronises every write/read call with a mutex

答:
Your example code will work, and yes, you will see the updates.  The relaxed ordering will give you the correct behavior.  That said, it may not actually be optimal in terms of performance.

Let's look at a more concrete example, with the mutexes made explicit.

```<code>std::mutex m;
std::atomic<bool> updated;
foo shared;

void thr1() {
    m.lock();
    shared.write(new_data);
    m.unlock();
    updated.store(true, std::memory_order_relaxed);
}

void thr2() {
    if (updated.load(std::memory_order_relaxed)) {
        m.lock();
        data = shared.read();
        m.unlock();
    }
}
</code>```

Informal explanation

m.lock() is an acquire operation and m.unlock() is release.  This means that nothing prevents updated.store(true) from "floating" up into the critical section, past m.unlock() and even shared.write(). At first glance this seems bad, because the whole point of the updated flag was to signal that shared.write() had finished.  But no actual harm occurs in that case, because thr1 still holds the mutex m, and so if thr2 starts trying to read the shared data, it will just wait until thr1 drops it.

What would really be bad is if updated.store() were to float all the way up past m.lock(); then thr2 could potentially see updated.load() == true and take the mutex before thr1.  However, this cannot happen because of the acquire semantics m.lock().

There could be some related issues in thr2 (a little more complicated because they would have to be speculative) but again we are saved by the same fact: the updated.load() can sink downward into the critical section, but not past it entirely (because m.unlock() is release).

But this is an instance where a stronger memory order on the updated operations, although seemingly more expensive, might actually improve performance.  If the value true in updated becomes visible prematurely, then thr2 attempts to lock m while it is already locked by thr1, and so thr2 will have to block while it waits for m to become available.  But if you changed to updated.store(true, std::memory_order_release) and updated.load(std::memory_order_acquire), then the value true in updated can only become visible after m is truly unlocked by thr1, and so the m.lock() in thr2 should always succeed immediately (ignoring contention by any other threads that might exist).

Proof

Okay, that was an informal explanation, but we know those are always risky when thinking about memory ordering.  Let's give a proof from the formal rules of the C++ memory model.  I will follow the C++20 standard because I have it handy, but I don't believe there are any significant relevant changes from C++17.  See [intro.races] for definitions of the terms used here.

I claim that, if shared.read() executes at all, then shared.write(new_data) happens before it, and so by write-read coherence [intro.races p18] shared.read() will see the new data.

The lock and unlock operations on m are totally ordered [thread.mutex.requirements.mutex p5].  Consider two cases: either thr1's unlock precedes thr2's lock (Case I), or vice versa (Case II).

Case I

If thr1's unlock precedes thr2's lock in m's lock order, then there is no problem; they synchronize with each other [thread.mutex.requirements.mutex p11].  Since shared.write(new_data) is sequenced before thr1's m.unlock(), and thr2's m.lock() is sequenced before shared.read(), by chasing the definitions in [intro.races] we see that shared.write(new_data) indeed happens before shared.read().

Case II

Now suppose the contrary, that thr2's lock precedes thr1's unlock in m's lock order.  Since locks and unlocks of the same mutex cannot interleave (that's the whole point of a mutex, to provide mutual exclusion), the lock total order on m must be as follows:

```<code>thr2: m.lock()
thr2: m.unlock()
thr1: m.lock()
thr1: m.unlock()
</code>```

That means that thr2's m.unlock() synchronizes with thr1's m.lock().  Now updated.load() is sequenced before thr2 m.unlock(), and thr1 m.lock() is sequenced before updated.store(true), so it follows that updated.load() happens before updated.store(true).  By read-write coherence [intro.races p17], updated.load() must not take its value from updated.store(true), but from some strictly earlier side effect in the modification order of updated; presumably its initialization to false.

We conclude that updated.load() must return false in this case.  But if that were so, then thr2 would never have tried to lock the mutex in the first place.  This is a contradiction, so Case II must never occur.

Body:
I have a shared data structure that is already internally synchronised with a mutex. Can I use an atomic with memory order relaxed to signal changes. A very simplified view of what I mean in code

Thread 1

shared_conf.set("somekey","someval");
is_reconfigured.store(true, std::memory_order_relaxed);

Thread 2

if (is_reconfigured.load(std::memory_order_relaxed)) {
  inspect_shared_conf();
}

Is it guaranteed that I'll see updates in the shared_map?; the shared map itself internally synchronises every write/read call with a mutex

Body:
Your example code will work, and yes, you will see the updates.  The relaxed ordering will give you the correct behavior.  That said, it may not actually be optimal in terms of performance.

Let's look at a more concrete example, with the mutexes made explicit.

std::mutex m;
std::atomic<bool> updated;
foo shared;

void thr1() {
    m.lock();
    shared.write(new_data);
    m.unlock();
    updated.store(true, std::memory_order_relaxed);
}

void thr2() {
    if (updated.load(std::memory_order_relaxed)) {
        m.lock();
        data = shared.read();
        m.unlock();
    }
}

Informal explanation

m.lock() is an acquire operation and m.unlock() is release.  This means that nothing prevents updated.store(true) from "floating" up into the critical section, past m.unlock() and even shared.write(). At first glance this seems bad, because the whole point of the updated flag was to signal that shared.write() had finished.  But no actual harm occurs in that case, because thr1 still holds the mutex m, and so if thr2 starts trying to read the shared data, it will just wait until thr1 drops it.

What would really be bad is if updated.store() were to float all the way up past m.lock(); then thr2 could potentially see updated.load() == true and take the mutex before thr1.  However, this cannot happen because of the acquire semantics m.lock().

There could be some related issues in thr2 (a little more complicated because they would have to be speculative) but again we are saved by the same fact: the updated.load() can sink downward into the critical section, but not past it entirely (because m.unlock() is release).

But this is an instance where a stronger memory order on the updated operations, although seemingly more expensive, might actually improve performance.  If the value true in updated becomes visible prematurely, then thr2 attempts to lock m while it is already locked by thr1, and so thr2 will have to block while it waits for m to become available.  But if you changed to updated.store(true, std::memory_order_release) and updated.load(std::memory_order_acquire), then the value true in updated can only become visible after m is truly unlocked by thr1, and so the m.lock() in thr2 should always succeed immediately (ignoring contention by any other threads that might exist).

Proof

Okay, that was an informal explanation, but we know those are always risky when thinking about memory ordering.  Let's give a proof from the formal rules of the C++ memory model.  I will follow the C++20 standard because I have it handy, but I don't believe there are any significant relevant changes from C++17.  See [intro.races] for definitions of the terms used here.

I claim that, if shared.read() executes at all, then shared.write(new_data) happens before it, and so by write-read coherence [intro.races p18] shared.read() will see the new data.

The lock and unlock operations on m are totally ordered [thread.mutex.requirements.mutex p5].  Consider two cases: either thr1's unlock precedes thr2's lock (Case I), or vice versa (Case II).

Case I

If thr1's unlock precedes thr2's lock in m's lock order, then there is no problem; they synchronize with each other [thread.mutex.requirements.mutex p11].  Since shared.write(new_data) is sequenced before thr1's m.unlock(), and thr2's m.lock() is sequenced before shared.read(), by chasing the definitions in [intro.races] we see that shared.write(new_data) indeed happens before shared.read().

Case II

Now suppose the contrary, that thr2's lock precedes thr1's unlock in m's lock order.  Since locks and unlocks of the same mutex cannot interleave (that's the whole point of a mutex, to provide mutual exclusion), the lock total order on m must be as follows:

thr2: m.lock()
thr2: m.unlock()
thr1: m.lock()
thr1: m.unlock()

That means that thr2's m.unlock() synchronizes with thr1's m.lock().  Now updated.load() is sequenced before thr2 m.unlock(), and thr1 m.lock() is sequenced before updated.store(true), so it follows that updated.load() happens before updated.store(true).  By read-write coherence [intro.races p17], updated.load() must not take its value from updated.store(true), but from some strictly earlier side effect in the modification order of updated; presumably its initialization to false.

We conclude that updated.load() must return false in this case.  But if that were so, then thr2 would never have tried to lock the mutex in the first place.  This is a contradiction, so Case II must never occur.


问:
how can I filter BlockList?
First, I'm not an English speaker. I'm a beginner developer.
Please understand if my English is awkward

I'm creating a real-time chat app and filtering messages from the person I blocked
So I'm filtering through the target number of the blocked person in the entire message.
But this filter process is not working well. Can you help me?

Messages come in the form of object arrangement from the server.

like this

```<code>
Message :  [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

{type: 'message', idx: 1313231, name: '%E3%85%81%E3%84%B4%E3%85%87%E3%85%81', message: 'hello'}

</code>```

https://i.stack.imgur.com/vMur3.png

Similarly, the block list is also received in the form of an object array from the server.

idx is user's idx target is blocked idx

```<code>blockList
   [{…}]
 > 0: {idx: 1321, target: 2231, timestamp: 1644561250499}
    length: 1
[[Prototype]]: Array(0)
</code>```

https://i.stack.imgur.com/eLnYQ.png

So I want filtering that message if blockList.target !== enterMsg.idx
but it's not working so I tried some ways that is

```<code>  const blockMap = blockList.map((el) => el.target)

 const filterdMessage  = () => {enterMsg.filter((msg)=> {
   const realfiltered = enterMsg.filter((el) => {
    blockMap.map((bl) => {
      return el.idx !== bl
    })
   })
    })};
</code>```

but it is empty array How can i fix it ?

答:
I would say there is a misunderstanding of the array functions: maybe you should check the docs ;)

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Then you want to filter an array (the list of message) and the filter function must return a boolean so you probably want something like that :

```<code>const filterdMessage  = enterMsg.filter((msg)=> {
  return !blockList.some((bl) => {
     return msg.idx === bl.target
  })
})
</code>```

What we do here is :

tell that we want to filter the enterMsg array based on a condition that will be computed in the provided callback

for each message check if no entry in the block list has a target matching its idx

we use 'some' function that will return true if a matching block is found, and since we dont want matching blocks we negate the condition

Title: how can I filter BlockList?

Body:
First, I'm not an English speaker. I'm a beginner developer.
Please understand if my English is awkward

I'm creating a real-time chat app and filtering messages from the person I blocked
So I'm filtering through the target number of the blocked person in the entire message.
But this filter process is not working well. Can you help me?

Messages come in the form of object arrangement from the server.

like this

Message :  [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]

{type: 'message', idx: 1313231, name: '%E3%85%81%E3%84%B4%E3%85%87%E3%85%81', message: 'hello'}

https://i.stack.imgur.com/vMur3.png

Similarly, the block list is also received in the form of an object array from the server.

idx is user's idx target is blocked idx

blockList
   [{…}]
 > 0: {idx: 1321, target: 2231, timestamp: 1644561250499}
    length: 1
[[Prototype]]: Array(0)

https://i.stack.imgur.com/eLnYQ.png

So I want filtering that message if blockList.target !== enterMsg.idx
but it's not working so I tried some ways that is

  const blockMap = blockList.map((el) => el.target)

 const filterdMessage  = () => {enterMsg.filter((msg)=> {
   const realfiltered = enterMsg.filter((el) => {
    blockMap.map((bl) => {
      return el.idx !== bl
    })
   })
    })};

but it is empty array How can i fix it ?

Body:
I would say there is a misunderstanding of the array functions: maybe you should check the docs ;)

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

Then you want to filter an array (the list of message) and the filter function must return a boolean so you probably want something like that :

const filterdMessage  = enterMsg.filter((msg)=> {
  return !blockList.some((bl) => {
     return msg.idx === bl.target
  })
})

What we do here is :

tell that we want to filter the enterMsg array based on a condition that will be computed in the provided callback

for each message check if no entry in the block list has a target matching its idx

we use 'some' function that will return true if a matching block is found, and since we dont want matching blocks we negate the condition


问:
Loop through JSON in EJS
I have codes in EJS below,

```<code><script>
    var row =<%-JSON.stringify(data)%>
    console.log(row);
</script>
<% for(var i=0; i<JSON.stringify(data).length; i++) {%>
   <tr>
     <td>
       <%= JSON.stringify(data)[i].id%>
     </td>
   </tr>
<% } %>
</code>```

output of row is correct, an array of 3 objects, each with properties id, name etc.. I can manipulate the row to popuate the table in JS. However, I am wonderring whether there is a way to allow it be done in the above manner?

When I run the code above, JSON.stringify(data).length is not 3, but rather the length of the whole string.

Another questions is when I try to add

<% alert('t'); %> or <% window.alert('t'); %>, it gives me 'not defined' error...

Helps appreciated.

Regards
Hammer

答:
Something of this sort you may try. Not necessary you need to use Dbjson, just refer for syntax</p>
```<code>const codifyOptions = codifier.DatabaseCodifyOptions
const databaseOptions = databasifier.SqlServerDatabaseOptions
const dbJson = databasifier.getDatabaseJson(project, codifyOptions, databaseOptions)

dbJson.tables.forEach(table => {

  const tableName = codifier.codifyText(
        table.domain ? table.domain.concat("_", table.name) : table.name,
        codifyOptions

  )
</code>```

Title: Loop through JSON in EJS

Body:
I have codes in EJS below,

<% for(var i=0; i<JSON.stringify(data).length; i++) {%>

       <%= JSON.stringify(data)[i].id%>

<% } %>

output of row is correct, an array of 3 objects, each with properties id, name etc.. I can manipulate the row to popuate the table in JS. However, I am wonderring whether there is a way to allow it be done in the above manner?

When I run the code above, JSON.stringify(data).length is not 3, but rather the length of the whole string.

Another questions is when I try to add

<% alert('t'); %> or <% window.alert('t'); %>, it gives me 'not defined' error...

Helps appreciated.

Regards
Hammer

Body:
Something of this sort you may try. Not necessary you need to use Dbjson, just refer for syntax

const codifyOptions = codifier.DatabaseCodifyOptions
const databaseOptions = databasifier.SqlServerDatabaseOptions
const dbJson = databasifier.getDatabaseJson(project, codifyOptions, databaseOptions)

dbJson.tables.forEach(table => {

  const tableName = codifier.codifyText(
        table.domain ? table.domain.concat("_", table.name) : table.name,
        codifyOptions

  )


问:
Javascript, How do i check if two pseudo rectangles are colliding
Say I have two tables: rect1, and rect2.
Each one follows the format of x,y,width,height.

For x, the bigger the number, the farther right it is. for y, the bigger the number, the farther down it is.

var rect1 = [20,40,80,60];
var rect2 = [10,30,67,10];
```

How would I check if these are colliding? I know it is math related, I am just having issues thinking at the moment.

答:
It should be something along the lines of:

var rect1 = [20, 40, 80, 60];
var rect2 = [10, 30, 67, 10];
function checkCollision(rect1, rect2) {
  var x1 = rect1[0];
  var y1 = rect1[1];
  var w1 = rect1[2];
  var h1 = rect1[3];
  var x2 = rect2[0];
  var y2 = rect2[1];
  var w2 = rect2[2];
  var h2 = rect2[3];
  if (x1 < x2 + w2 && x1 + w1 > x2 && y1 < y2 + h2 && y1 + h1 > y2) {
    return true;
  } else {
    return false;
  }
}
console.log(checkCollision(rect1, rect2));```

Body:
Say I have two tables: rect1, and rect2.
Each one follows the format of x,y,width,height.

For x, the bigger the number, the farther right it is. for y, the bigger the number, the farther down it is.

var rect1 = [20,40,80,60];
var rect2 = [10,30,67,10];

How would I check if these are colliding? I know it is math related, I am just having issues thinking at the moment.


问:
Redraw canvas in Android
I am making an Android 2.2 application using Eclipse. My application should draw
images by clicking on buttons.

I have two buttons at the bottom of the screen, and I need to draw the shape in the same screen that has the buttons. I used FrameLayout in which the shapes are drawn.

My problem is, the two shapes are overwriting, so I need to redraw the canvas.

My Code

```<code>package draw.tab;

import android.app.Activity;
//import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;

public class DrawActivity extends Activity implements OnClickListener
{
    DrawView drawview;
    CircleView circleView;
    FrameLayout Frame;
    Button square,circle;

    /** Called when the activity is first created. */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Frame=(FrameLayout)findViewById(R.id.MyFrame);
        drawview=new DrawView(this);
        circleView=new CircleView(this);

        square=(Button)findViewById(R.id.buttonTest);
        square.setOnClickListener(this);
        circle=(Button)findViewById(R.id.circleButton);
        circle.setOnClickListener(this);
    }

    public void onClick(View v)
    {
        switch (v.getId()) {
            case R.id.circleButton:
                Frame.addView(circleView);
                /*circleView.setBackgroundColor(Color.rgb(40,100,20));
                circleView.findViewById(R.id.CircleViewId);
                setContentView(circleView);*/
                break;
            case R.id.buttonTest:
                Frame.addView(drawview);
                /*drawview.setBackgroundColor(Color.WHITE);
                drawview.findViewById(R.id.DrawViewId);
                drawview.layout(400,0,200,450);
                setContentView(drawview);*/
                break;
        }
    }
}
</code>```

DrawView.java

```<code>package draw.tab;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

public class DrawView extends View
{
    Paint paint=new Paint();
    Path pat=new Path();

    public DrawView(Context context)
    {
        super(context);
        paint.setColor(Color.RED);
        paint.setStyle(Style.STROKE);
        //context.clearRect(70,140,400,450);
        //pat.addRect(50,40,250,400,Path.Direction.CW);
    }

    public DrawView(Context con,AttributeSet atts)
    {
        super(con,atts);
    }

    @Override
    public void onDraw(Canvas canvas)
    {
        //canvas.drawPath(pat,paint);
        canvas.drawLine(20,40,450,40,paint);//horizontal top
        canvas.drawRect(70,140,400,450,paint);
        canvas.drawLine(20,40,20,600,paint);//vertical left
        canvas.drawLine(20,600,450,600,paint);//horizontal bottom
        canvas.drawLine(450,40,450,600,paint);//vertical right
        //this.invalidate();
    }
}
</code>```

CircleView.java

```<code>package draw.tab;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

public class CircleView extends View
{
    Paint p=new Paint();
    Path path=new Path();

    public CircleView(Context context)
    {
        super(context);
        p.setColor(Color.BLUE);
        p.setStyle(Style.STROKE);
        //path.addCircle(250,250,50,Path.Direction.CW);
    }

    public CircleView(Context con,AttributeSet atts)
    {
        super(con,atts);
    }

    public void onDraw(Canvas c)
    {
        //c.drawPath(path,p);
        //c.save();
        c.drawLine(20,40,450,40, p);//horizontal top
        c.drawCircle(250,350,100,p);
        c.drawLine(20,40,20,600,p);//vertical left
        c.drawLine(20,600,450,600,p);//horizontal bottom
        c.drawLine(450,40,450,600,p);//vertical right
        //c.restore();
        this.invalidate();
    }
}
</code>```

main.xml

```<code><?xml version="1.0" encoding="utf-8"?>

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:visibility="visible"
    android:id="@+id/MyFrame"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <draw.tab.DrawView
    android:id="@+id/DrawViewId"
    android:layout_width="320dp"
    android:layout_height="600dp">
    </draw.tab.DrawView>

    <draw.tab.CircleView
    android:id="@+id/CircleViewId"
    android:layout_width="320dp"
    android:layout_height="600dp">
    </draw.tab.CircleView>

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    android:gravity="bottom">

     <Button
        android:layout_height="wrap_content"
        android:text="Circle"
        android:id="@+id/circleButton"
        android:layout_width="160dp">
    </Button>

    <Button
        android:layout_height="wrap_content"
        android:text="Square"
        android:id="@+id/buttonTest"
        android:layout_width="160dp">
    </Button>
</LinearLayout>

</FrameLayout>
</code>```

The above is all my code. The shapes are overwriting, so I want to remove and redraw the canvas or redraw without overwriting.

答:
Call canvas.save() then do drawing then call canvas.restore(). Also depends on the bitmaps you are drawing. The bitmaps should have a transparent background.

Edit

Call canvas.drawColor(Color.White); //Or whichever bg color before drawing the bitmap.

Edit

In drawview try this

```<code>canvas.drawRect(getLeft(), getTop(), getright() , getBottom() ,paint);
</code>```

Similarly in CircleView

```<code>canvas.drawCircle(getLeft()+getwidth()/2, getTop()+getheight()/2, 100, paint);
</code>```

One last try. Set children gravity..

```<code><draw.tab.DrawView
android:id="@+id/DrawViewId"
android:layout_width="320dp"
android:layout_height="600dp"
android:layout_gravity="left">
</draw.tab.DrawView>

<draw.tab.CircleView
android:id="@+id/CircleViewId"
android:layout_width="320dp"
android:layout_height="600dp"
android:layout_gravity="right">
</draw.tab.CircleView>
</code>```

Title: Redraw canvas in Android

Body:
I am making an Android 2.2 application using Eclipse. My application should draw
images by clicking on buttons.

I have two buttons at the bottom of the screen, and I need to draw the shape in the same screen that has the buttons. I used FrameLayout in which the shapes are drawn.

My problem is, the two shapes are overwriting, so I need to redraw the canvas.

My Code

package draw.tab;

import android.app.Activity;
//import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;

public class DrawActivity extends Activity implements OnClickListener
{
    DrawView drawview;
    CircleView circleView;
    FrameLayout Frame;
    Button square,circle;

    /** Called when the activity is first created. */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Frame=(FrameLayout)findViewById(R.id.MyFrame);
        drawview=new DrawView(this);
        circleView=new CircleView(this);

        square=(Button)findViewById(R.id.buttonTest);
        square.setOnClickListener(this);
        circle=(Button)findViewById(R.id.circleButton);
        circle.setOnClickListener(this);
    }

    public void onClick(View v)
    {
        switch (v.getId()) {
            case R.id.circleButton:
                Frame.addView(circleView);
                /*circleView.setBackgroundColor(Color.rgb(40,100,20));
                circleView.findViewById(R.id.CircleViewId);
                setContentView(circleView);*/
                break;
            case R.id.buttonTest:
                Frame.addView(drawview);
                /*drawview.setBackgroundColor(Color.WHITE);
                drawview.findViewById(R.id.DrawViewId);
                drawview.layout(400,0,200,450);
                setContentView(drawview);*/
                break;
        }
    }
}

DrawView.java

package draw.tab;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

public class DrawView extends View
{
    Paint paint=new Paint();
    Path pat=new Path();

    public DrawView(Context context)
    {
        super(context);
        paint.setColor(Color.RED);
        paint.setStyle(Style.STROKE);
        //context.clearRect(70,140,400,450);
        //pat.addRect(50,40,250,400,Path.Direction.CW);
    }

    public DrawView(Context con,AttributeSet atts)
    {
        super(con,atts);
    }

    @Override
    public void onDraw(Canvas canvas)
    {
        //canvas.drawPath(pat,paint);
        canvas.drawLine(20,40,450,40,paint);//horizontal top
        canvas.drawRect(70,140,400,450,paint);
        canvas.drawLine(20,40,20,600,paint);//vertical left
        canvas.drawLine(20,600,450,600,paint);//horizontal bottom
        canvas.drawLine(450,40,450,600,paint);//vertical right
        //this.invalidate();
    }
}

CircleView.java

package draw.tab;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

public class CircleView extends View
{
    Paint p=new Paint();
    Path path=new Path();

    public CircleView(Context context)
    {
        super(context);
        p.setColor(Color.BLUE);
        p.setStyle(Style.STROKE);
        //path.addCircle(250,250,50,Path.Direction.CW);
    }

    public CircleView(Context con,AttributeSet atts)
    {
        super(con,atts);
    }

    public void onDraw(Canvas c)
    {
        //c.drawPath(path,p);
        //c.save();
        c.drawLine(20,40,450,40, p);//horizontal top
        c.drawCircle(250,350,100,p);
        c.drawLine(20,40,20,600,p);//vertical left
        c.drawLine(20,600,450,600,p);//horizontal bottom
        c.drawLine(450,40,450,600,p);//vertical right
        //c.restore();
        this.invalidate();
    }
}

main.xml

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:visibility="visible"
    android:id="@+id/MyFrame"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <draw.tab.DrawView
    android:id="@+id/DrawViewId"
    android:layout_width="320dp"
    android:layout_height="600dp">
    </draw.tab.DrawView>

    <draw.tab.CircleView
    android:id="@+id/CircleViewId"
    android:layout_width="320dp"
    android:layout_height="600dp">
    </draw.tab.CircleView>

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    android:gravity="bottom">

     <Button
        android:layout_height="wrap_content"
        android:text="Circle"
        android:id="@+id/circleButton"
        android:layout_width="160dp">
    </Button>

    <Button
        android:layout_height="wrap_content"
        android:text="Square"
        android:id="@+id/buttonTest"
        android:layout_width="160dp">
    </Button>
</LinearLayout>

</FrameLayout>

The above is all my code. The shapes are overwriting, so I want to remove and redraw the canvas or redraw without overwriting.

Body:
Call canvas.save() then do drawing then call canvas.restore(). Also depends on the bitmaps you are drawing. The bitmaps should have a transparent background.

Edit

Call canvas.drawColor(Color.White); //Or whichever bg color before drawing the bitmap.

Edit

In drawview try this

canvas.drawRect(getLeft(), getTop(), getright() , getBottom() ,paint);

Similarly in CircleView

canvas.drawCircle(getLeft()+getwidth()/2, getTop()+getheight()/2, 100, paint);

One last try. Set children gravity..

<draw.tab.DrawView
android:id="@+id/DrawViewId"
android:layout_width="320dp"
android:layout_height="600dp"
android:layout_gravity="left">
</draw.tab.DrawView>

<draw.tab.CircleView
android:id="@+id/CircleViewId"
android:layout_width="320dp"
android:layout_height="600dp"
android:layout_gravity="right">
</draw.tab.CircleView>


问:
installation of TypeScript and Javascript in Visual Studio Code
I'm new to visual studio code where I want to have welcome screen like this:

But my screen is like this

How can I customize my screen where I get options to install support for JavaScript, TypeScript

if you see the first screenshot In the WELCOME screen there is

Customize - Tools and Languages - Install support for Type Script, Java Script ....

Please be kind since I'm new and in learning phase and posted this question after several google searches

答:
That thing you are referring to is called the activity bar, which can be activated in several ways but the easiest way to do so would be through the Command Pallette.

To use the command pallet, you can click on View> and pick Command Pallette. A small textbox should appear at the top. Type in > Toggle Activity Bar Visibility , which should make your toggle bar visible again!

Through there you can go to extensions (The box looking thing)  and install support for the things you're in need of.


问:
How to switch from .then to async await in Vue JS
I am wondering how to switch the created function that is already asynchronours via .then, to async await.

```<code>created() {
    this.$http.get("wp/v2/posts").then(
      response => {
        for (let post in response.data) {
          this.posts.push(response.data[post]);
        }
        this.$store.dispatch({
          type: "updatePost",
          value: this.posts
        });
      },
      error => {
        alert(error);
      }
    );
}
</code>```

I could easily add async created() and await this.$http.get, but couldn't figure out on the error => {} part since the curly braces for responses will also be gone.

答:
I think you can use this instead of using try:</p>
```<code>async created() {
  await this.$http.get("wp/v2/posts").then(response => {
    for (let post in response.data) {
      this.posts.push(response.data[post]);
    }
    this.$store.dispatch({
      type: "updatePost",
      value: this.posts
    });
  }).catch(function () {
    alert(error);
  })
}
</code>```

Body:
I am wondering how to switch the created function that is already asynchronours via .then, to async await.

created() {
    this.$http.get("wp/v2/posts").then(
      response => {
        for (let post in response.data) {
          this.posts.push(response.data[post]);
        }
        this.$store.dispatch({
          type: "updatePost",
          value: this.posts
        });
      },
      error => {
        alert(error);
      }
    );
}

I could easily add async created() and await this.$http.get, but couldn't figure out on the error => {} part since the curly braces for responses will also be gone.

Body:
I think you can use this instead of using try:

async created() {
  await this.$http.get("wp/v2/posts").then(response => {
    for (let post in response.data) {
      this.posts.push(response.data[post]);
    }
    this.$store.dispatch({
      type: "updatePost",
      value: this.posts
    });
  }).catch(function () {
    alert(error);
  })
}


问:
Subtract 1 month of the Calendar Function End Date
I am using a calendar table in an slicer in my Power BI report. In order to avoid the user to select the current month, I would like this calendar to go up to the last day of the previous month. i.e., If we are in February, it would only display the dates until Jan 31.

How can I define the end date of my Calendar DAX.

```<code>    CALENDAR (
              DATE(2019,1,1),
              TODAY()
            )
</code>```

I have tried a couple of things included ENDOFMONTH() and EOMONTH(), but none of them worked.

答:
I like Andrey's solution, but want to flagg that you can do it like this as well:

```<code>Calendar =
CALENDAR(
    DATE(2019,1,1),
    TODAY()-DAY(TODAY())
)
</code>```

As always, in DAX there are several ways of doing the same thing.

Body:
I am using a calendar table in an slicer in my Power BI report. In order to avoid the user to select the current month, I would like this calendar to go up to the last day of the previous month. i.e., If we are in February, it would only display the dates until Jan 31.

How can I define the end date of my Calendar DAX.

    CALENDAR (
              DATE(2019,1,1),
              TODAY()
            )

I have tried a couple of things included ENDOFMONTH() and EOMONTH(), but none of them worked.

Body:
I like Andrey's solution, but want to flagg that you can do it like this as well:

Calendar =
CALENDAR(
    DATE(2019,1,1),
    TODAY()-DAY(TODAY())
)

As always, in DAX there are several ways of doing the same thing.


问:
How to get metadata of hive tables, columns, views, constraint keys and comment columns?
Please help me out how get metadata of hive tables, columns, views, constraint keys and comment columns.</p>

答:
Below are some metadata tables from the RDBMS hive metastore.

TBLS - Tables, external tables & views Metadata

DBS - Database metadata

PARTITIONS - Table partition metadata

KEY_CONSTRAINTS - Table constraints metadata

For Column related metadata you need to join multiple tables like COLUMNS_V2, SDS, TBLS & DBS


问:
SQL CASE WHEN a is NULL
I have 3 columns all contain email addresses

```<code>email
alt_email
main_email
</code>```

I wanted to do case when email is null then alt_email
when alt_email is null then email and when both are null then main_email end as all_emails.

I am not getting the correct answer as the total count for all_emails is way 90% less than the total all customers.

TIA

答: Select CASE WHEN (email != '') THEN email WHEN (alt_email != '') THEN alt_email ELSE main_email END AS emaiId From table</p>

Title: SQL CASE WHEN a is NULL

Body:
I have 3 columns all contain email addresses

email
alt_email
main_email

I wanted to do case when email is null then alt_email
when alt_email is null then email and when both are null then main_email end as all_emails.

I am not getting the correct answer as the total count for all_emails is way 90% less than the total all customers.

TIA


问:
Saving txt logs into a file creating only once
I am running into a issue when trying to save the logcat to a file . Below is the code:

```<code>public void createLogs() {
    if (isExternalStorageWritable()) {

        File appDirectory;
        if(Build.VERSION.SDK_INT >= 30) {
             appDirectory = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + "/myTest");
        }else{
             appDirectory = new File(Environment.getExternalStorageDirectory() + “/myTest");
        }
        File logDirectory = new File(appDirectory + "/logs");

         File logFile = new File(logDirectory, “mytest.txt");

        if (!appDirectory.exists()) {
            appDirectory.mkdir();
        }

        if (!logDirectory.exists()) {
            logDirectory.mkdir();
        }

        try {
            //Process process = Runtime.getRuntime().exec("logcat -c");
            Process process = Runtime.getRuntime().exec("logcat -f " + logFile + " -r 2048 -n 4");
        } catch ( IOException e ) {
            e.printStackTrace();
        }

    }

}
</code>```

It creates the folder myTest-->logs--->mytest.txt in this folder structure.
It is creating .txt file but when manually delete .txt is not creating again. Please suggest.

答:
On Android 11+ devices created files will often be scannd by the MediaStore directly.

But on deleting the file the MediaStore mostly is not informed.

Hence if you try to create a file with the same name again the MediaStore gets involved and wil report that the file already exists.

Remove the MediaStore entry first.

Body:
I am running into a issue when trying to save the logcat to a file . Below is the code:

public void createLogs() {
    if (isExternalStorageWritable()) {

        File appDirectory;
        if(Build.VERSION.SDK_INT >= 30) {
             appDirectory = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + "/myTest");
        }else{
             appDirectory = new File(Environment.getExternalStorageDirectory() + “/myTest");
        }
        File logDirectory = new File(appDirectory + "/logs");

         File logFile = new File(logDirectory, “mytest.txt");

        if (!appDirectory.exists()) {
            appDirectory.mkdir();
        }

        if (!logDirectory.exists()) {
            logDirectory.mkdir();
        }

        try {
            //Process process = Runtime.getRuntime().exec("logcat -c");
            Process process = Runtime.getRuntime().exec("logcat -f " + logFile + " -r 2048 -n 4");
        } catch ( IOException e ) {
            e.printStackTrace();
        }

    }

}

It creates the folder myTest-->logs--->mytest.txt in this folder structure.
It is creating .txt file but when manually delete .txt is not creating again. Please suggest.


问:
what is the default value of an array in C++?
If I were to create an array with int* array = new int[10]; and fill part of the array with values, how can I check how much of the array is filled? I want to loop through and check if each value is the default value but I'm not sure what the default value of each array element is. Would it be null 0 or garbage values?

答:
I don't know if this helps but in c++17 onwards there's the std::array class that can be used. In this class you have the option to use class functions such as std::array.fill(...)

```<code>std::array<int, 10> arr;
arr.fill(-1);
</code>```

cpp docs: cpp-docs

This get's you closer to the experience from other languages such as Java and Python both having Arrays.fill(arr, -1); and arr = [-1]*N respectively to fill the array with non-default values.

Body:
I don't know if this helps but in c++17 onwards there's the std::array class that can be used. In this class you have the option to use class functions such as std::array.fill(...)

std::array<int, 10> arr;
arr.fill(-1);

cpp docs: cpp-docs

This get's you closer to the experience from other languages such as Java and Python both having Arrays.fill(arr, -1); and arr = [-1]*N respectively to fill the array with non-default values.