问:
Create a dictionary that has summary value from list / Combine two different dictionaries to summarize value
I am new to python and working with dictionaries and list.
Here is the list

```<code>detail = [(1, [u'apple', u'2017-07-03T08:03:32Z', 'boston']),

 (2, [u'orange', u'2017-07-03T08:58:35Z', 'NOLOCATION']),

 (3, [u'grape', u'2017-07-03T12:14:12Z', 'boston']),

 (4, [u'cherry', u'2017-07-04T13:16:44Z', 'new york']),

 (5, [u'strawberry', u'2017-07-06T10:56:22Z', 'san francisco']),

 (6, [u'plum', u'2017-07-06T10:56:22Z', 'seattle'])]
</code>```

I want to summarize this, so that - for each date, I get split of counts for each location. Something  like this -

```<code>details_summary = {'2017-07-03':[(boston,2), (NOLOCATION,1)], '2017-07-04':
[new york,1], '2017-07-06':[(san francisco,1),(seattle,1)]}
</code>```

I want it in this format, because I want to generate map (visualization) for each date (key), and location points(value).

I ended up creating two different dictionaries that look like this -

```<code>location = {u'boston': 2, 'NOLOCATION': 1, u'new york': 1, u'san francisco':
1, u'seattle': 1}

date = {'2017-07-03':3, '2017-07-04':1, '2017-07-06':2}
</code>```

Now, I want to summarize so that I get, split of counts in different location for each date and I am stuck here.

答:
Make use of Python collections defaultdict and Counter

```<code>from collections import defaultdict, Counter
summary = defaultdict(list)
for item in detail:
  summary[item[1][1].split('T')[0]].append(item[1][2])

details_summary = {str(k):[(x,y) for x,y in Counter(v).iteritems()] for k,v in summary.iteritems()}
print details_summary
{'2017-07-06': [('san francisco', 1), ('seattle', 1)], '2017-07-04': [('new york', 1)], '2017-07-03': [('boston', 2), ('NOLOCATION', 1)]}
</code>```

Body:
I am new to python and working with dictionaries and list.
Here is the list

detail = [(1, [u'apple', u'2017-07-03T08:03:32Z', 'boston']),

 (2, [u'orange', u'2017-07-03T08:58:35Z', 'NOLOCATION']),

 (3, [u'grape', u'2017-07-03T12:14:12Z', 'boston']),

 (4, [u'cherry', u'2017-07-04T13:16:44Z', 'new york']),

 (5, [u'strawberry', u'2017-07-06T10:56:22Z', 'san francisco']),

 (6, [u'plum', u'2017-07-06T10:56:22Z', 'seattle'])]

I want to summarize this, so that - for each date, I get split of counts for each location. Something  like this -

details_summary = {'2017-07-03':[(boston,2), (NOLOCATION,1)], '2017-07-04':
[new york,1], '2017-07-06':[(san francisco,1),(seattle,1)]}

I want it in this format, because I want to generate map (visualization) for each date (key), and location points(value).

I ended up creating two different dictionaries that look like this -

location = {u'boston': 2, 'NOLOCATION': 1, u'new york': 1, u'san francisco':
1, u'seattle': 1}

date = {'2017-07-03':3, '2017-07-04':1, '2017-07-06':2}

Now, I want to summarize so that I get, split of counts in different location for each date and I am stuck here.

Body:
Make use of Python collections defaultdict and Counter

from collections import defaultdict, Counter
summary = defaultdict(list)
for item in detail:
  summary[item[1][1].split('T')[0]].append(item[1][2])

details_summary = {str(k):[(x,y) for x,y in Counter(v).iteritems()] for k,v in summary.iteritems()}
print details_summary
{'2017-07-06': [('san francisco', 1), ('seattle', 1)], '2017-07-04': [('new york', 1)], '2017-07-03': [('boston', 2), ('NOLOCATION', 1)]}


来源: stackexchange

问:
In R, why do [<-.data.frame` and `$<-.data.frame` behave differently?
Whilst trying to convert a column of my data.frame from strings to date objects I received an unexpected result together with a rather scary warning message:

```<code>my_dataframe <- data.frame(date = c("20070610", "20170611"))
my_dataframe["date"] <- strptime(my_dataframe$date, format = "%Y%m%d")

# Warning message:
# In `[<-.data.frame`(`*tmp*`, "date", value = list(sec = c(NA_real_,  :
#   provided 11 variables to replace 1 variables

my_dataframe

# my_dataframe
#   date
# 1    0
# 2    0
</code>```

However, if I simply replace the [<-.data.frame operator with a $<-.data.frame operator I receive the result I want and am not warned about any issues:

```<code>my_dataframe <- data.frame(date = c("20070610", "20170611"))
my_dataframe$date <- strptime(my_dataframe$date, format = "%Y%m%d")
my_dataframe

# my_dataframe
#       date
# 1 20070610
# 2 20170611
</code>```

I am now doing this analysis in a completely different way, but I find this difference in behaviour really distressing and would be really grateful if someone could explain why it occurs.

Thanks!

答:
[.data.frame and $.data.frame are different because [ returns a data frame (list) and $ returns a vector. The bracket equivalent of $ is [[, and that works as expected. You can also wrap what you're assigning in list() to make sure it is recognized as a single column.

```<code>my_dataframe <- data.frame(date = c("20070610", "20170611"))
my_dataframe["date2"] <- strptime(my_dataframe$date, format = "%Y%m%d")
my_dataframe[["date3"]] <- strptime(my_dataframe$date, format = "%Y%m%d")
my_dataframe$date4 <- strptime(my_dataframe$date, format = "%Y%m%d")
my_dataframe["date5"] <- list(strptime(my_dataframe$date, format = "%Y%m%d"))
my_dataframe
#       date date2      date3      date4      date5
# 1 20070610     0 2007-06-10 2007-06-10 2007-06-10
# 2 20170611     0 2017-06-11 2017-06-11 2017-06-11

# [[<-, $<-, and [<- list() all work fine
</code>```

In this case, I think it's the extra attributes of the POSIX class objects that confuse things. In general, best practice is to use [[ when you know there is a single column.

```<code>x = strptime(my_dataframe$date, format = "%Y%m%d")
attributes(x)
# $names
#  [1] "sec"    "min"    "hour"   "mday"   "mon"    "year"   "wday"   "yday"   "isdst"  "zone"
# [11] "gmtoff"
#
# $class
# [1] "POSIXlt" "POSIXt"
</code>```

ContentLicense: CC BY-SA 3.0

Body:
Whilst trying to convert a column of my data.frame from strings to date objects I received an unexpected result together with a rather scary warning message:

my_dataframe <- data.frame(date = c("20070610", "20170611"))
my_dataframe["date"] <- strptime(my_dataframe$date, format = "%Y%m%d")

# Warning message:
# In `[<-.data.frame`(`*tmp*`, "date", value = list(sec = c(NA_real_,  :
#   provided 11 variables to replace 1 variables

my_dataframe

# my_dataframe
#   date
# 1    0
# 2    0

However, if I simply replace the [<-.data.frame operator with a $<-.data.frame operator I receive the result I want and am not warned about any issues:

my_dataframe <- data.frame(date = c("20070610", "20170611"))
my_dataframe$date <- strptime(my_dataframe$date, format = "%Y%m%d")
my_dataframe

# my_dataframe
#       date
# 1 20070610
# 2 20170611

I am now doing this analysis in a completely different way, but I find this difference in behaviour really distressing and would be really grateful if someone could explain why it occurs.

Thanks!

Body:
[.data.frame and $.data.frame are different because [ returns a data frame (list) and $ returns a vector. The bracket equivalent of $ is [[, and that works as expected. You can also wrap what you're assigning in list() to make sure it is recognized as a single column.

my_dataframe <- data.frame(date = c("20070610", "20170611"))
my_dataframe["date2"] <- strptime(my_dataframe$date, format = "%Y%m%d")
my_dataframe[["date3"]] <- strptime(my_dataframe$date, format = "%Y%m%d")
my_dataframe$date4 <- strptime(my_dataframe$date, format = "%Y%m%d")
my_dataframe["date5"] <- list(strptime(my_dataframe$date, format = "%Y%m%d"))
my_dataframe
#       date date2      date3      date4      date5
# 1 20070610     0 2007-06-10 2007-06-10 2007-06-10
# 2 20170611     0 2017-06-11 2017-06-11 2017-06-11

# [[<-, $<-, and [<- list() all work fine

In this case, I think it's the extra attributes of the POSIX class objects that confuse things. In general, best practice is to use [[ when you know there is a single column.

x = strptime(my_dataframe$date, format = "%Y%m%d")
attributes(x)
# $names
#  [1] "sec"    "min"    "hour"   "mday"   "mon"    "year"   "wday"   "yday"   "isdst"  "zone"
# [11] "gmtoff"
#
# $class
# [1] "POSIXlt" "POSIXt"


问:
How to close modal after form submit event in Angular2?
I want to close modal after form submit event is finished. I've done following things:

<form [formGroup]="alertForm" novalidate (ngSubmit)="save(alertForm.value, alertForm.valid)">

          Available Recipient
          <textarea class="form-control validate" id="recipientLogin" required formControlName="recipientLogin"> </textarea>

          <select class="form-control" id="alert_level" formControlName="alert_level">
            <option  value="0" selected> Emergency </option>
            <option value="1">Major</option>
            <option value="2">Minor</option>
            <option value="3">Information</option>
          </select>

          Subject
          <input type="text" class="form-control validate" id="subject" required formControlName="subject">

          Message
          <textarea class="form-control validate" id="message" required formControlName="message"> </textarea>

          <input type="file" class="form-control" id="media1" />
          <input type="file" class="form-control" id="media2" />
          <input type="file" class="form-control" id="media3" />

          <button type="submit" class="btn btn-default input-field">Send</button>

          <button type="submit" data-dismiss="modal" class="btn btn-default input-field">Close</button>

  </form>```

This triggers save() on form submit but does not close the modal for that I tried data-dismiss="modal" on save button, which block the save() call and close the modal.
I want to complete save() first after that close modal.

答:
Assuming the form is inside a bootstrap modal, you can use
$('#modalID').modal("hide") to close the modal.

For full reference check here.

Body:
I want to close modal after form submit event is finished. I've done following things:

<form [formGroup]="alertForm" novalidate (ngSubmit)="save(alertForm.value, alertForm.valid)">

          Available Recipient
          <textarea class="form-control validate" id="recipientLogin" required formControlName="recipientLogin"> </textarea>

          <select class="form-control" id="alert_level" formControlName="alert_level">
            <option  value="0" selected> Emergency </option>
            <option value="1">Major</option>
            <option value="2">Minor</option>
            <option value="3">Information</option>
          </select>

          Subject
          <input type="text" class="form-control validate" id="subject" required formControlName="subject">

          Message
          <textarea class="form-control validate" id="message" required formControlName="message"> </textarea>

          <input type="file" class="form-control" id="media1" />
          <input type="file" class="form-control" id="media2" />
          <input type="file" class="form-control" id="media3" />

          <button type="submit" class="btn btn-default input-field">Send</button>

          <button type="submit" data-dismiss="modal" class="btn btn-default input-field">Close</button>

  </form>

This triggers save() on form submit but does not close the modal for that I tried data-dismiss="modal" on save button, which block the save() call and close the modal.
I want to complete save() first after that close modal.


问:
Drupal "You are not authorized to access this page"
I've taken over managing our site from MIA developers and have spent the day trying to find this answer.

After upgrading to v 7.56 there's just ONE specific page in a list of pages that I am unable to access as an admin. (and unfortunately it's probably the most needed report in our admin panel).

Here's what I know:

Drupal Version 7.56

PHP 7.0.20

No errors when status report is run

Chron - no errors

Here's what I've done:

added $cookie_domain = '.example.com'; to settings.php

cleared browser cache and cookies

ensured admin has access to everything

cleared site cache

made sure code on page(s) was exactly the same as it was before I did the update

Not sure what to do or where to go from here. Any help is much appreciated.

UPDATE: When logged in as super admin, received HTTP 500 error. After more research, I updated the php.ini to include memory_limit = 64M ;
Now I can view the page as the superadmin, but it still isn't available for other admins.

Image 1: viewing page as admin

Image 2: viewing page as superadmin

```<code>function custom_reports_menu() {

    $items['administration/upcoming-classes'] = array(
    'title' => 'Upcoming Classes',
    'page callback' => 'custom_reports_upcoming_classes_page',
    'access callback' => 'user_access',
    'access arguments' => array('admin wdcc reports'),
        'file' => 'includes/custom_reports.upcoming-classes.inc',
    'type' => MENU_CALLBACK,
    );

    $items['administration/class-details'] = array(
    'title' => 'Class Details',
    'page callback' => 'custom_reports_class_details_page',
    'access callback' => 'user_access',
    'access arguments' => array('admin wdcc reports'),
        'file' => 'includes/custom_reports.class-details.inc',
    'type' => MENU_CALLBACK,
    );
    return $items;

}

function custom_reports_upcoming_classes_page() {

    drupal_add_css(base_path().path_to_theme().'/assets/css/outburst-accounts.css', array('type' => 'external'));

    global $user;
    $uid = $user->uid;

    $output = '';

    $upcoming_classes = custom_reports_get_upcoming_classes();
    $attendee_count = custom_reports_get_attendee_count();

    // upcoming classes
    $output .= '<h2>Upcoming Classes</h2>';
    $output .= custom_reports_format_upcoming_classes($upcoming_classes, $attendee_count);

    return $output;
}

function custom_reports_permission() {

  return array(
    'admin wdcc reports' => array(
      'title' => t('Admin WDCC Reports'),
      'description' => t('Perform administration tasks for WDCC.'),
      //'cache' => DRUPAL_NO_CACHE,
    ),
  );
}

function custom_reports_get_upcoming_classes() {

    $today = date('Y-m-d');

    $x = 0;
    $classes = '';

    // get classes from new db tables
    $today = date('Y-m-d H:i:s');

    $result = db_query("SELECT n.nid FROM node n, field_data_field_date fdfd WHERE n.status = :status AND n.type = :type AND n.nid = fdfd.entity_id AND fdfd.field_date_value >= :today ORDER BY fdfd.field_date_value ASC", array(':status' => 1, ':type' => 'public_class_date', ':today' => $today));
    if ($result->rowCount() > 0) {
        foreach ($result as $row) {

            $nid = $row->nid;
            $node = node_load($nid);

            $product_id = $nid;
            $product_title = $node->title;
            $product_type = 'public_class_date';
            $product_date = $node->field_date[$node->language][0]['value'];
            $product_datestamp = strtotime($product_date);
            //$product_datestamp = strtotime($product_date);

            // set vars
            $classes[$x]['product_id'] = $product_id;
            $classes[$x]['product_title'] = $product_title;
            $classes[$x]['product_type'] = $product_type;
            $classes[$x]['product_date'] = $product_date;
            $classes[$x]['product_datestamp'] = $product_datestamp;

            $x++;
        }
    }

    return $classes;
}

function custom_reports_get_attendee_count() {

    $attendees = array();
    $old_attendees = array();
    $new_attendees = array();

    $result = db_query("SELECT itemID, attendeeID, attendeeName FROM wdcc_old_attendee");
    if ($result->rowCount() > 0) {
        foreach ($result as $row) {
            $item_id = $row->itemID;
            $attendee_id = 'B'.$row->attendeeID;
            $attendee_name = $row->attendeeName;

            $old_attendees[$item_id][$attendee_id]['old_attendee_id'] = $attendee_id;

            if (strpos($attendee_name, '&') > 0 || strpos($attendee_name, ' and') > 0) { // couples
                $old_attendees[$item_id][$attendee_id]['total_attendees'] = 2;
            } else {
                $old_attendees[$item_id][$attendee_id]['total_attendees'] = 1;
            }
        }
    }
    if (is_array($old_attendees)) {
        $connect_class_ids = custom_accounts_connect_class_ids();
        foreach ($old_attendees as $old_item_id => $attendee_list) {
            if (isset($connect_class_ids[$old_item_id])) {
                $product_id = $connect_class_ids[$old_item_id];
                foreach ($attendee_list as $attendee_id => $attendee) {
                    $old_attendee_id = $attendee['old_attendee_id'];
                    $attendees[$product_id][$old_attendee_id]['total_attendees'] = $attendee['total_attendees'];
                }
            }
        }
    }
    $result = db_query("SELECT id, product_id FROM wdcc_attendees WHERE transaction_id > 0");
    if ($result->rowCount() > 0) {
        foreach ($result as $row) {
            $attendee_id = $row->id;
            $product_id = $row->product_id;
            $attendees[$product_id][$attendee_id]['total_attendees'] = 1;
        }
    }
    $cancelled_attendees = array();
    $result = db_query("SELECT * FROM wdcc_attendees_cancelled");
    if ($result->rowCount() > 0) {
        foreach ($result as $row) {
            $attendee_id = $row->attendee_id;
            $old_attendee_id = 'B'.$row->old_attendee_id;

            if ($attendee_id > 0) {
                $cancelled_attendees[] = $attendee_id;
            } else {
                $cancelled_attendees[] = $old_attendee_id;
            }
        }
    }
    foreach ($attendees as $product_id => $product_attendees) {
        foreach ($product_attendees as $attendee_id => $attendee) {
            if (in_array($attendee_id, $cancelled_attendees)) {
                unset($attendees[$product_id][$attendee_id]);
            }
        }
    }
    $attendee_count = array();
    foreach ($attendees as $product_id => $product_attendees) {
        foreach ($product_attendees as $attendee_id => $attendee) {
            if (!isset($attendee_count[$product_id])) {
                $attendee_count[$product_id] = $attendee['total_attendees'];
            } else {
                $attendee_count[$product_id] = $attendee_count[$product_id] + $attendee['total_attendees'];
            }
        }
    }

    return $attendee_count;
}

function custom_reports_format_upcoming_classes($upcoming_classes, $attendee_count) {

    $output = '';

    if (is_array($upcoming_classes)) {
        $output .= '<div class="table-responsive table-container">';
        $output .= '<table class="table">';
        $output .= '<tr><td>Class</td><td>Guests</td><td>Actions</td></tr>';
        foreach ($upcoming_classes as $class) {
            $nid = $class['product_id'];
            $node_url = url('node/'.$nid, array('absolute' => TRUE));
            $attendees = 0;
            if (isset($attendee_count[$nid])) {
                $attendees = $attendee_count[$nid];
            }

            $output .= '<tr><td><a href="'.$node_url.'">'.$class['product_title'].'</a><br />'.date('m/d/Y - g:i A', $class['product_datestamp']).'</td><td>'.$attendees.'</td><td><a href="/administration/class-details/'.$class['product_id'].'">View roster</a></td></tr>';
        }
        $output .= '</table>';
        $output .= '</div>';
    } else {
        $output .= '<p>No upcoming classes found.</p>';
    }

    return $output;
}
</code>```

答:
Replace this below code in settings.php file

PHP variable name:

$cookie_domain = 'example.com'; (line 340)

Body:
I've taken over managing our site from MIA developers and have spent the day trying to find this answer.

After upgrading to v 7.56 there's just ONE specific page in a list of pages that I am unable to access as an admin. (and unfortunately it's probably the most needed report in our admin panel).

Here's what I know:

Drupal Version 7.56

PHP 7.0.20

No errors when status report is run

Chron - no errors

Here's what I've done:

added $cookie_domain = '.example.com'; to settings.php

cleared browser cache and cookies

ensured admin has access to everything

cleared site cache

made sure code on page(s) was exactly the same as it was before I did the update

Not sure what to do or where to go from here. Any help is much appreciated.

UPDATE: When logged in as super admin, received HTTP 500 error. After more research, I updated the php.ini to include memory_limit = 64M ;
Now I can view the page as the superadmin, but it still isn't available for other admins.

Image 1: viewing page as admin

Image 2: viewing page as superadmin

function custom_reports_menu() {

    $items['administration/upcoming-classes'] = array(
    'title' => 'Upcoming Classes',
    'page callback' => 'custom_reports_upcoming_classes_page',
    'access callback' => 'user_access',
    'access arguments' => array('admin wdcc reports'),
        'file' => 'includes/custom_reports.upcoming-classes.inc',
    'type' => MENU_CALLBACK,
    );

    $items['administration/class-details'] = array(
    'title' => 'Class Details',
    'page callback' => 'custom_reports_class_details_page',
    'access callback' => 'user_access',
    'access arguments' => array('admin wdcc reports'),
        'file' => 'includes/custom_reports.class-details.inc',
    'type' => MENU_CALLBACK,
    );
    return $items;

}

function custom_reports_upcoming_classes_page() {

    drupal_add_css(base_path().path_to_theme().'/assets/css/outburst-accounts.css', array('type' => 'external'));

    global $user;
    $uid = $user->uid;

    $output = '';

    $upcoming_classes = custom_reports_get_upcoming_classes();
    $attendee_count = custom_reports_get_attendee_count();

    // upcoming classes
    $output .= '
Upcoming Classes
';
    $output .= custom_reports_format_upcoming_classes($upcoming_classes, $attendee_count);

    return $output;
}

function custom_reports_permission() {

  return array(
    'admin wdcc reports' => array(
      'title' => t('Admin WDCC Reports'),
      'description' => t('Perform administration tasks for WDCC.'),
      //'cache' => DRUPAL_NO_CACHE,
    ),
  );
}

function custom_reports_get_upcoming_classes() {

    $today = date('Y-m-d');

    $x = 0;
    $classes = '';

    // get classes from new db tables
    $today = date('Y-m-d H:i:s');

    $result = db_query("SELECT n.nid FROM node n, field_data_field_date fdfd WHERE n.status = :status AND n.type = :type AND n.nid = fdfd.entity_id AND fdfd.field_date_value >= :today ORDER BY fdfd.field_date_value ASC", array(':status' => 1, ':type' => 'public_class_date', ':today' => $today));
    if ($result->rowCount() > 0) {
        foreach ($result as $row) {

            $nid = $row->nid;
            $node = node_load($nid);

            $product_id = $nid;
            $product_title = $node->title;
            $product_type = 'public_class_date';
            $product_date = $node->field_date[$node->language][0]['value'];
            $product_datestamp = strtotime($product_date);
            //$product_datestamp = strtotime($product_date);

            // set vars
            $classes[$x]['product_id'] = $product_id;
            $classes[$x]['product_title'] = $product_title;
            $classes[$x]['product_type'] = $product_type;
            $classes[$x]['product_date'] = $product_date;
            $classes[$x]['product_datestamp'] = $product_datestamp;

            $x++;
        }
    }

    return $classes;
}

function custom_reports_get_attendee_count() {

    $attendees = array();
    $old_attendees = array();
    $new_attendees = array();

    $result = db_query("SELECT itemID, attendeeID, attendeeName FROM wdcc_old_attendee");
    if ($result->rowCount() > 0) {
        foreach ($result as $row) {
            $item_id = $row->itemID;
            $attendee_id = 'B'.$row->attendeeID;
            $attendee_name = $row->attendeeName;

            $old_attendees[$item_id][$attendee_id]['old_attendee_id'] = $attendee_id;

            if (strpos($attendee_name, '&') > 0 || strpos($attendee_name, ' and') > 0) { // couples
                $old_attendees[$item_id][$attendee_id]['total_attendees'] = 2;
            } else {
                $old_attendees[$item_id][$attendee_id]['total_attendees'] = 1;
            }
        }
    }
    if (is_array($old_attendees)) {
        $connect_class_ids = custom_accounts_connect_class_ids();
        foreach ($old_attendees as $old_item_id => $attendee_list) {
            if (isset($connect_class_ids[$old_item_id])) {
                $product_id = $connect_class_ids[$old_item_id];
                foreach ($attendee_list as $attendee_id => $attendee) {
                    $old_attendee_id = $attendee['old_attendee_id'];
                    $attendees[$product_id][$old_attendee_id]['total_attendees'] = $attendee['total_attendees'];
                }
            }
        }
    }
    $result = db_query("SELECT id, product_id FROM wdcc_attendees WHERE transaction_id > 0");
    if ($result->rowCount() > 0) {
        foreach ($result as $row) {
            $attendee_id = $row->id;
            $product_id = $row->product_id;
            $attendees[$product_id][$attendee_id]['total_attendees'] = 1;
        }
    }
    $cancelled_attendees = array();
    $result = db_query("SELECT * FROM wdcc_attendees_cancelled");
    if ($result->rowCount() > 0) {
        foreach ($result as $row) {
            $attendee_id = $row->attendee_id;
            $old_attendee_id = 'B'.$row->old_attendee_id;

            if ($attendee_id > 0) {
                $cancelled_attendees[] = $attendee_id;
            } else {
                $cancelled_attendees[] = $old_attendee_id;
            }
        }
    }
    foreach ($attendees as $product_id => $product_attendees) {
        foreach ($product_attendees as $attendee_id => $attendee) {
            if (in_array($attendee_id, $cancelled_attendees)) {
                unset($attendees[$product_id][$attendee_id]);
            }
        }
    }
    $attendee_count = array();
    foreach ($attendees as $product_id => $product_attendees) {
        foreach ($product_attendees as $attendee_id => $attendee) {
            if (!isset($attendee_count[$product_id])) {
                $attendee_count[$product_id] = $attendee['total_attendees'];
            } else {
                $attendee_count[$product_id] = $attendee_count[$product_id] + $attendee['total_attendees'];
            }
        }
    }

    return $attendee_count;
}

function custom_reports_format_upcoming_classes($upcoming_classes, $attendee_count) {

    $output = '';

    if (is_array($upcoming_classes)) {
        $output .= '
';
        $output .= '
';
        $output .= '
Class	Guests	Actions
';
        foreach ($upcoming_classes as $class) {
            $nid = $class['product_id'];
            $node_url = url('node/'.$nid, array('absolute' => TRUE));
            $attendees = 0;
            if (isset($attendee_count[$nid])) {
                $attendees = $attendee_count[$nid];
            }

            $output .= '
'.$class['product_title'].'
'.date('m/d/Y - g:i A', $class['product_datestamp']).'	'.$attendees.'	View roster
';
        }
        $output .= '
';
        $output .= '
';
    } else {
        $output .= '
No upcoming classes found.
';
    }

    return $output;
}


问:
Validation of radiobuttonlist using javascript
I want to validate radiobuttonlist if user is not checked any item. If not checked whole list should be highlighted. Following is my code:

```<code>var userImpect = document.getElementById("<%=userImpect.ClientID%>");
for (var i = 0; i < userImpect.length; i++) {
    if (userImpect[i].checked) {
        userImpect.style.backgroundColor = "Yellow";
        validate = false;
    }
}
return validate;
</code>```

Please tell me how to do it.
Here is my asp code

```<code><asp:RadioButtonList ID="userImpect" runat="server" ForeColor="Black" RepeatDirection="Horizontal">
     <asp:ListItem Text="Just me" Value="Just me"></asp:ListItem>
     <asp:ListItem Text="Multiple Users" Value="Multiple Users"></asp:ListItem>
     <asp:ListItem Text="Everyone" Value="Everyone"></asp:ListItem>
</asp:RadioButtonList>
</code>```

Button code

```<code><asp:Button Text="Save" runat="server" ID="btnTest" OnClick="btnTest_Click" OnClientClick="return ValidateForm();" />
</code>```

html generated

答:
You can write this way :

document.getElementById("userImpect").style.backgroundColor = "Yellow";

Body:
I want to validate radiobuttonlist if user is not checked any item. If not checked whole list should be highlighted. Following is my code:

var userImpect = document.getElementById("<%=userImpect.ClientID%>");
for (var i = 0; i < userImpect.length; i++) {
    if (userImpect[i].checked) {
        userImpect.style.backgroundColor = "Yellow";
        validate = false;
    }
}
return validate;

Please tell me how to do it.
Here is my asp code

<asp:RadioButtonList ID="userImpect" runat="server" ForeColor="Black" RepeatDirection="Horizontal">
     <asp:ListItem Text="Just me" Value="Just me"></asp:ListItem>
     <asp:ListItem Text="Multiple Users" Value="Multiple Users"></asp:ListItem>
     <asp:ListItem Text="Everyone" Value="Everyone"></asp:ListItem>
</asp:RadioButtonList>

Button code

<asp:Button Text="Save" runat="server" ID="btnTest" OnClick="btnTest_Click" OnClientClick="return ValidateForm();" />

html generated


问:
How to edit the variables of a php file with another php file
Ok so I want to do something similar to how Simple Machine Forum edits some variable within the Admin panel on the forum. For instance
I have a settings.php file. I want tool.php to open and find all declared php variables in the settings.php like $background_color='Orange' and output in tools.php Background Color: Orange inside of a form tag that, once changed to 'Purple' and submitted, replaces 'Orange' with 'Purple' and now if i open 'settings.php' the variable inside the file is now "$background_color='Purple'" without having to go in an manually edit it. I can just submit the new data for the variable and replace the old.

答:
You can do this using database
fetch that value from database in settings.php
and update that from your  tools.php or wherever you want .</p>


问:
ASP.NET Focus Scrolls Page to Input
I have a few textboxes/labels inside of an UpdatePanel. When I tab out of one of the textboxes, a label has to be updated with some text. This causes focus on the page to reset to the topmost element.

This is a data-entry form and the users expect to not have to use the mouse at all. I can set focus back on the correct textbox in code:

```<code>Page.SetFocus(tbxInput);
</code>```

or

```<code>tbxInput.Focus();
</code>```

In IE, the browser scroll position is maintained (woo hoo!). In Chrome and Firefox it is not; the scroll location is adjusted so that the focused textbox is the last element shown on the page. This is really disturbing to the user.

I am using the following rules in my web.config:

```<code><pages theme="Default" styleSheetTheme="Default" maintainScrollPositionOnPostBack="true" validateRequest="false">
</code>```

How can I achieve the behavior that IE has?

答:
Using asp.net AJAX UpdatePanel is an option. Also which version of .net framework are you using.

As per this with 4.0 it should work but I haven't tried.

ContentLicense: CC BY-SA 2.5

Title: ASP.NET Focus Scrolls Page to Input

Body:
I have a few textboxes/labels inside of an UpdatePanel. When I tab out of one of the textboxes, a label has to be updated with some text. This causes focus on the page to reset to the topmost element.

This is a data-entry form and the users expect to not have to use the mouse at all. I can set focus back on the correct textbox in code:

Page.SetFocus(tbxInput);

or

tbxInput.Focus();

In IE, the browser scroll position is maintained (woo hoo!). In Chrome and Firefox it is not; the scroll location is adjusted so that the focused textbox is the last element shown on the page. This is really disturbing to the user.

I am using the following rules in my web.config:

<pages theme="Default" styleSheetTheme="Default" maintainScrollPositionOnPostBack="true" validateRequest="false">

How can I achieve the behavior that IE has?


问:
SSRS 2012 Divide By Zero Error
I've read through the answers and updated my expression and I continue to get #Error in the row that has a 0 for the budget.

All the percentages are being calculated correctly.

=IIF(SUM(Fields!CM_Budget.Value,"Name")=0,0,SUM(Fields!MTD_Actual.Value,"Name")/SUM(Fields!CM_Budget.Value,"Name"))

答:
This is because SSRS always evaluates both expressions.
You have to break your expression in two parts.

```<code>=IIF(SUM(Fields!CM_Budget.Value,"Name")=0,0,SUM(Fields!MTD_Actual.Value,"Name"))
/
IIF(SUM(Fields!CM_Budget.Value,"Name")=0,1,SUM(Fields!CM_Budget.Value,"Name"))
</code>```

An alternative could be using custom code like below

```<code>Public Function Divider (ByVal Dividend As Double, ByVal Divisor As Double)
If IsNothing(Divisor) Or Divisor = 0
  Return Nothing
Else
  Return Dividend/Divisor
End If
End Function
</code>```

Then you can write your expression like:

```<code>=Code.Divider(SUM(Fields!MTD_Actual.Value,"Name"),SUM(Fields!CM_Budget.Value,"Name"))
</code>```

I usually prefer the second way to do it, to make my expressions more readable

Title: SSRS 2012 Divide By Zero Error

Body:
This is because SSRS always evaluates both expressions.
You have to break your expression in two parts.

=IIF(SUM(Fields!CM_Budget.Value,"Name")=0,0,SUM(Fields!MTD_Actual.Value,"Name"))
/
IIF(SUM(Fields!CM_Budget.Value,"Name")=0,1,SUM(Fields!CM_Budget.Value,"Name"))

An alternative could be using custom code like below

Public Function Divider (ByVal Dividend As Double, ByVal Divisor As Double)
If IsNothing(Divisor) Or Divisor = 0
  Return Nothing
Else
  Return Dividend/Divisor
End If
End Function

Then you can write your expression like:

=Code.Divider(SUM(Fields!MTD_Actual.Value,"Name"),SUM(Fields!CM_Budget.Value,"Name"))

I usually prefer the second way to do it, to make my expressions more readable


问:
Create radio button style in ReactJS
I'm new to ReactJS and I really want to know what is the best practice for creating a Radio button style. Actually kinda like switching between tabs. For example, I have a layout like this one

When use click on each icon, it switches to its own tab.
I really want to know what is the best way to do instead of using pure radio button? Btw, the icon will have a image and div text inside of a div wrap. Thanks

答: The best way would be to have a component that is your tab controller. Then that component tracks which tab is selected, and will render the selected component </p>

Title: Create radio button style in ReactJS


问:
SQL getting the correct dataset using aggregate query

so i have the user , calls, sms table , now i want to get the count of incoming and outgoing calls and sms per user

i have this query

```<code>select u.username,
        sum(case when c.type = 'incoming' then 1 else 0 end) as  incoming,
        sum(case when c.type = 'incoming' and status = 'true' then 1 else 0 end) as  answered,
        sum(case when c.type = 'outgoing' then 1 else 0 end) as  outgoing,
        sum(case when s.type = 'in'   then 1 else 0 end )  as sms
 from user u
 join
      calls c
      on u.id = c.user_id
 join
      sms s
      on u.id = s.user_id

 group by u.username;
</code>```

and the result is this

incoming and outgoing in calls is correct but in sms the result is wrong in user sample ,it should be 1 in column sms and not 4

答:
To avoid the multiplication effect you are having with the joins, you can try aggregating the calls and sms tables separately by user, and then joining to these subqueries:</p>

```<code>SELECT
    u.username,
    COALESCE(t1.incoming, 0) AS incoming,
    COALESCE(t1.answered, 0) AS answered,
    COALESCE(t1.outgoing, 0) AS outgoing,
    COALESCE(t2.sms, 0) AS sms
FROM user u
LEFT JOIN
(
    SELECT
        user_id,
        SUM(CASE WHEN type = 'incoming' THEN 1 ELSE 0 END) AS  incoming,
        SUM(CASE WHEN c.type = 'incoming' AND status = 'true'
                 THEN 1 ELSE 0 END) AS answered,
        SUM(CASE WHEN c.type = 'outgoing' THEN 1 ELSE 0 END) AS outgoing
    FROM calls
    GROUP BY user_id
) t1
    ON u.id = t1.user_id
LEFT JOIN
(
    SELECT
        user_id,
        SUM(CASE WHEN s.type = 'in' THEN 1 ELSE 0 END) AS sms
    FROM sms
    GROUP BY user_id
) t2
    ON u.id = t2.user_id
</code>```

Body:
so i have the user , calls, sms table , now i want to get the count of incoming and outgoing calls and sms per user

i have this query

select u.username,
        sum(case when c.type = 'incoming' then 1 else 0 end) as  incoming,
        sum(case when c.type = 'incoming' and status = 'true' then 1 else 0 end) as  answered,
        sum(case when c.type = 'outgoing' then 1 else 0 end) as  outgoing,
        sum(case when s.type = 'in'   then 1 else 0 end )  as sms
 from user u
 join
      calls c
      on u.id = c.user_id
 join
      sms s
      on u.id = s.user_id

 group by u.username;

and the result is this

incoming and outgoing in calls is correct but in sms the result is wrong in user sample ,it should be 1 in column sms and not 4

Body:
To avoid the multiplication effect you are having with the joins, you can try aggregating the calls and sms tables separately by user, and then joining to these subqueries:

SELECT
    u.username,
    COALESCE(t1.incoming, 0) AS incoming,
    COALESCE(t1.answered, 0) AS answered,
    COALESCE(t1.outgoing, 0) AS outgoing,
    COALESCE(t2.sms, 0) AS sms
FROM user u
LEFT JOIN
(
    SELECT
        user_id,
        SUM(CASE WHEN type = 'incoming' THEN 1 ELSE 0 END) AS  incoming,
        SUM(CASE WHEN c.type = 'incoming' AND status = 'true'
                 THEN 1 ELSE 0 END) AS answered,
        SUM(CASE WHEN c.type = 'outgoing' THEN 1 ELSE 0 END) AS outgoing
    FROM calls
    GROUP BY user_id
) t1
    ON u.id = t1.user_id
LEFT JOIN
(
    SELECT
        user_id,
        SUM(CASE WHEN s.type = 'in' THEN 1 ELSE 0 END) AS sms
    FROM sms
    GROUP BY user_id
) t2
    ON u.id = t2.user_id


问:
Could I change my name and surname in all previous commits?
I would like to change my name, surname and email in my all commits, is it possible?</p>

答:
Use git-filter-branch.

```<code>git filter-branch --commit-filter 'if [ "$GIT_AUTHOR_NAME" = "Josh Lee" ];
  then export GIT_AUTHOR_NAME="Hobo Bob"; export GIT_AUTHOR_EMAIL=hobo@example.com;
  fi; git commit-tree "$@"'
</code>```

This only affects the author, not the committer (which for most commits will be the same as the author). If you want to rewrite those as well, set the GIT_COMMITTER_NAME and GIT_COMMITTER_EMAIL variables.

The standard warning about rewriting history applies; only do it to history that has not yet been shared.

June 2018 Update

The manual now includes a solution, using --env-filter, in its examples: https://git-scm.com/docs/git-filter-branch#_examples :

```<code>git filter-branch --env-filter '
    if test "$GIT_AUTHOR_EMAIL" = "root@localhost"
    then
        GIT_AUTHOR_EMAIL=john@example.com
    fi
    if test "$GIT_COMMITTER_EMAIL" = "root@localhost"
    then
        GIT_COMMITTER_EMAIL=john@example.com
    fi
' -- --all
</code>```

Body:
Use git-filter-branch.

git filter-branch --commit-filter 'if [ "$GIT_AUTHOR_NAME" = "Josh Lee" ];
  then export GIT_AUTHOR_NAME="Hobo Bob"; export GIT_AUTHOR_EMAIL=hobo@example.com;
  fi; git commit-tree "$@"'

This only affects the author, not the committer (which for most commits will be the same as the author). If you want to rewrite those as well, set the GIT_COMMITTER_NAME and GIT_COMMITTER_EMAIL variables.

The standard warning about rewriting history applies; only do it to history that has not yet been shared.

June 2018 Update

The manual now includes a solution, using --env-filter, in its examples: https://git-scm.com/docs/git-filter-branch#_examples :

git filter-branch --env-filter '
    if test "$GIT_AUTHOR_EMAIL" = "root@localhost"
    then
        GIT_AUTHOR_EMAIL=john@example.com
    fi
    if test "$GIT_COMMITTER_EMAIL" = "root@localhost"
    then
        GIT_COMMITTER_EMAIL=john@example.com
    fi
' -- --all

ContentLicense: CC BY-SA 4.0


问:
Understanding the transclude option of directive definition?
I think this is one of the hardest concept for me to understand with angularjs's directive.

The document from http://docs.angularjs.org/guide/directive says:

transclude - compile the content of the element and make it available to the directive. Typically used with ngTransclude. The advantage of transclusion is that the linking function receives a transclusion function which is pre-bound to the correct scope. In a typical setup the widget creates an isolate scope, but the transclusion is not a child, but a sibling of the isolate scope. This makes it possible for the widget to have private state, and the transclusion to be bound to the parent (pre-isolate) scope.

true - transclude the content of the directive.

'element' - transclude the whole element including any directives defined at lower priority.

It says transclude typically used with ngTransclude. But the sample from the doc of ngTransclude doesn't use ngTransclude directive at all.

I'd like some good examples to help me understand this. Why do we need it? What does it solve? How to use it?

答:
The Updated AngularJS 1.6.6 documentation now has a better explanation.

Transclude is Used to Create a Directive that Wraps Other Elements

Sometimes it's desirable to be able to pass in an entire template rather than a string or an object. Let's say that we want to create a "dialog box" component. The dialog box should be able to wrap any arbitrary content.

To do this, we need to use the transclude option. Refer to the example below.

script.js

```<code>angular.module('docsTransclusionExample', [])
.controller('Controller', ['$scope', function($scope) {
  $scope.name = 'Tobias';
}])
.directive('myDialog', function() {
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    templateUrl: 'my-dialog.html',
    link: function(scope) {
      scope.name = 'Jeff';
    }
  };
});
</code>```

index.html

```<code><div ng-controller="Controller">
  <my-dialog>Check out the contents, {{name}}!</my-dialog>
</div>
</code>```

my-dialog.html

```<code><div class="alert" ng-transclude></div>
</code>```

Compiled Output

```<code><div ng-controller="Controller" class="ng-scope">
  <my-dialog class="ng-isolate-scope"><div class="alert" ng-transclude="">Check out the contents, Tobias!</div></my-dialog>
</div>
</code>```

Transclude makes the contents of a directive with this option have access to the scope outside of the directive rather than inside.

This is illustrated in the previous example. Notice that we've added a link function in script.js that redefines name as Jeff. Ordinarily, we would expect that {{name}} would be Jeff. However, we see in this example that the {{name}} binding is still Tobias.

Best Practice: only use transclude: true when you want to create a directive that wraps arbitrary content.

Body:
The Updated AngularJS 1.6.6 documentation now has a better explanation.

Transclude is Used to Create a Directive that Wraps Other Elements

Sometimes it's desirable to be able to pass in an entire template rather than a string or an object. Let's say that we want to create a "dialog box" component. The dialog box should be able to wrap any arbitrary content.

To do this, we need to use the transclude option. Refer to the example below.

script.js

angular.module('docsTransclusionExample', [])
.controller('Controller', ['$scope', function($scope) {
  $scope.name = 'Tobias';
}])
.directive('myDialog', function() {
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    templateUrl: 'my-dialog.html',
    link: function(scope) {
      scope.name = 'Jeff';
    }
  };
});

index.html

<div ng-controller="Controller">
  <my-dialog>Check out the contents, {{name}}!</my-dialog>
</div>

my-dialog.html

<div class="alert" ng-transclude></div>

Compiled Output

<div ng-controller="Controller" class="ng-scope">
  <my-dialog class="ng-isolate-scope"><div class="alert" ng-transclude="">Check out the contents, Tobias!</div></my-dialog>
</div>

Transclude makes the contents of a directive with this option have access to the scope outside of the directive rather than inside.

This is illustrated in the previous example. Notice that we've added a link function in script.js that redefines name as Jeff. Ordinarily, we would expect that {{name}} would be Jeff. However, we see in this example that the {{name}} binding is still Tobias.

Best Practice: only use transclude: true when you want to create a directive that wraps arbitrary content.


问:
How to read External Sqllite Database in xamirin android in Visual Studio C#
My Code :

```<code>var dbpath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "ot.db3");
Context myContext = null;
try
{
      var dbcon = new SQLiteConnection(dbpath);
         var db=   dbcon.Query<records>("SELECT * FROM records WHERE sno = ? ", "1");
            int count = db.Count;
}
catch (IOException ex)
{
    var reason = string.Format("The database failed to create - reason {0}", ex.Message);
    Toast.MakeText(myContext, reason, ToastLength.Long).Show();
}
</code>```

I Create a Sqlite Database from my SQL Server Database.

Now I save it to my Phone on this path (Android/Data/Application/File)

Now using Sqlite-net-pcl nugget package for Sqlite Connection the connection works fine showing have no error.

When I try to read a table from database this Give any error that "No Such Table exist in database". And the table exists in the database and is populated with data.

What can I do?

Thanks in advance

答:
Create a Blank Database – A database reference can be created by passing the file path the SQLiteConnection class constructor. You do not need to check if the file already exists – it will automatically be created if required, otherwise the existing database file will be opened.

```<code>var db = new SQLiteConnection (dbPath);
</code>```

Save Data – Once you have created a SQLiteConnection object, database commands are executed by calling its methods, such as CreateTable and Insert like this:

```<code>db.CreateTable<Stock> ();
db.Insert (newStock); // after creating the newStock object
</code>```

Retrieve Data – To retrieve an object (or a list of objects) use the following syntax:

```<code>var stock = db.Get<Stock>(5); // primary key id of 5
var stockList = db.Table<Stock>();
</code>```

For more info use following link:

https://developer.xamarin.com/guides/android/application_fundamentals/data/part_3_using_sqlite_orm/#Using_SQLite.NET

Body:
My Code :

var dbpath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "ot.db3");
Context myContext = null;
try
{
      var dbcon = new SQLiteConnection(dbpath);
         var db=   dbcon.Query<records>("SELECT * FROM records WHERE sno = ? ", "1");
            int count = db.Count;
}
catch (IOException ex)
{
    var reason = string.Format("The database failed to create - reason {0}", ex.Message);
    Toast.MakeText(myContext, reason, ToastLength.Long).Show();
}

I Create a Sqlite Database from my SQL Server Database.

Now I save it to my Phone on this path (Android/Data/Application/File)

Now using Sqlite-net-pcl nugget package for Sqlite Connection the connection works fine showing have no error.

When I try to read a table from database this Give any error that "No Such Table exist in database". And the table exists in the database and is populated with data.

What can I do?

Thanks in advance

Body:
Create a Blank Database – A database reference can be created by passing the file path the SQLiteConnection class constructor. You do not need to check if the file already exists – it will automatically be created if required, otherwise the existing database file will be opened.

var db = new SQLiteConnection (dbPath);

Save Data – Once you have created a SQLiteConnection object, database commands are executed by calling its methods, such as CreateTable and Insert like this:

db.CreateTable<Stock> ();
db.Insert (newStock); // after creating the newStock object

Retrieve Data – To retrieve an object (or a list of objects) use the following syntax:

var stock = db.Get<Stock>(5); // primary key id of 5
var stockList = db.Table<Stock>();

For more info use following link:

https://developer.xamarin.com/guides/android/application_fundamentals/data/part_3_using_sqlite_orm/#Using_SQLite.NET


答:
Give all your checkboxes a class name say 'involved'. With JQuery you can do this:
$('.involved :checked').length == 0

Title: Validation of radiobuttonlist using javascript


问:
Changing button text on a shared workbook: Run-Time Error '-2147024809 (80070057)'
I recorded a macro to change the text on a button to show the current date.

The worksheet is not protected.

When I shared the Workbook, and click on the button, I get this error:

Run-time error '-2147024809 (80070057)':

  Requested Shapes are locked for selection

I unchecked the "Lock" and "Lock Text" (when I right click on the button and click "Format Control" and under "Protection" tab), but it didn't resolve the issue.

I want the macro to work while it is being shared.

```<code>Sub updateDate()
'
' updateDate Macro
'

'
    ActiveSheet.Shapes.Range(Array("Button 1")).Select
    Selection.Characters.Text = Date
    With Selection.Characters(Start:=1, Length:=9).Font
        .Name = "Calibri"
        .FontStyle = "Bold"
        .Size = 11
        .Strikethrough = False
        .Superscript = False
        .Subscript = False
        .OutlineFont = False
        .Shadow = False
        .Underline = xlUnderlineStyleNone
        .ColorIndex = 3
    End With
    Range("B1").Select
End Sub
</code>```

答:
You cannot access some Objects/Class when you had it Shared/Protected. But what your goal is can be achieved, you don't have to change the Fonts once it is done (bare in mind that this Sub should only be called when the ActiveSheet had this button):

```<code>Sub updateDate()
'
' updateDate Macro
'
'
    ActiveSheet.Buttons("Button 1").Text = CStr(Now) ' Date
    Range("B1").Select ' <-- Not needed
End Sub
</code>```

EDIT

To change Shapes when it is Shared, you first need to UnShare it, make changes and then Save it SharedAccess.

Try add another button and assign it to MakeButtonRedBold:

```<code>Sub MakeButtonRedBold()
    MakeButtonStyle01 "Button 1"
End Sub

Private Sub MakeButtonStyle01(ByVal sButtonName As String)
    Dim oBtn As Object
    On Error Resume Next
    Set oBtn = ActiveSheet.Buttons("Button 1")
    On Error GoTo 0
    If Not oBtn Is Nothing Then
        Application.DisplayAlerts = False
        ThisWorkbook.ExclusiveAccess ' UnShare Workbook
        With oBtn.Font
            .Name = "Calibri"
            .Bold = True
            .Size = 11
            .Color = RGB(255, 0, 0)
        End With
        ThisWorkbook.SaveAs ThisWorkbook.FullName, AccessMode:=xlShared ' Share the Workbook
        Application.DisplayAlerts = True
    End If
End Sub
</code>```

Body:
I recorded a macro to change the text on a button to show the current date.

The worksheet is not protected.

When I shared the Workbook, and click on the button, I get this error:

Run-time error '-2147024809 (80070057)':

  Requested Shapes are locked for selection

I unchecked the "Lock" and "Lock Text" (when I right click on the button and click "Format Control" and under "Protection" tab), but it didn't resolve the issue.

I want the macro to work while it is being shared.

Sub updateDate()
'
' updateDate Macro
'

'
    ActiveSheet.Shapes.Range(Array("Button 1")).Select
    Selection.Characters.Text = Date
    With Selection.Characters(Start:=1, Length:=9).Font
        .Name = "Calibri"
        .FontStyle = "Bold"
        .Size = 11
        .Strikethrough = False
        .Superscript = False
        .Subscript = False
        .OutlineFont = False
        .Shadow = False
        .Underline = xlUnderlineStyleNone
        .ColorIndex = 3
    End With
    Range("B1").Select
End Sub

Body:
You cannot access some Objects/Class when you had it Shared/Protected. But what your goal is can be achieved, you don't have to change the Fonts once it is done (bare in mind that this Sub should only be called when the ActiveSheet had this button):

Sub updateDate()
'
' updateDate Macro
'
'
    ActiveSheet.Buttons("Button 1").Text = CStr(Now) ' Date
    Range("B1").Select ' <-- Not needed
End Sub

EDIT

To change Shapes when it is Shared, you first need to UnShare it, make changes and then Save it SharedAccess.

Try add another button and assign it to MakeButtonRedBold:

Sub MakeButtonRedBold()
    MakeButtonStyle01 "Button 1"
End Sub

Private Sub MakeButtonStyle01(ByVal sButtonName As String)
    Dim oBtn As Object
    On Error Resume Next
    Set oBtn = ActiveSheet.Buttons("Button 1")
    On Error GoTo 0
    If Not oBtn Is Nothing Then
        Application.DisplayAlerts = False
        ThisWorkbook.ExclusiveAccess ' UnShare Workbook
        With oBtn.Font
            .Name = "Calibri"
            .Bold = True
            .Size = 11
            .Color = RGB(255, 0, 0)
        End With
        ThisWorkbook.SaveAs ThisWorkbook.FullName, AccessMode:=xlShared ' Share the Workbook
        Application.DisplayAlerts = True
    End If
End Sub


问:
beanshell decimal variables with proper value out
How do I write beanshell script to get complete decimal value?

My code is:

```<code>valueput = 0.00000001;

Double i = new Double(vars.get("valueput"));

Double = i * 2;

vars.put("test", Double.toString(i));
</code>```

Currently the above code is giving a value 1.0E-7.

I want the exact actual value 0.00000001.

Please let me know.

答:
Use BigDecimal class instead of Double. Example code:

```<code>vars.put("valueput", "0.00000001");

BigDecimal i = new BigDecimal(vars.get("valueput"));

BigDecimal Double = i * 2;

vars.put("test", Double.toPlainString());

log.info(vars.get("test"));
</code>```

Use JSR223 Test Elements and Groovy language instead of Beanshell (this is optional, but highly recommended)

Demo:

OwnerDisplayName: Richard Biswas

Body:
How do I write beanshell script to get complete decimal value?

My code is:

valueput = 0.00000001;

Double i = new Double(vars.get("valueput"));

Double = i * 2;

vars.put("test", Double.toString(i));

Currently the above code is giving a value 1.0E-7.

I want the exact actual value 0.00000001.

Please let me know.

Body:
Use BigDecimal class instead of Double. Example code:

vars.put("valueput", "0.00000001");

BigDecimal i = new BigDecimal(vars.get("valueput"));

BigDecimal Double = i * 2;

vars.put("test", Double.toPlainString());

log.info(vars.get("test"));

Use JSR223 Test Elements and Groovy language instead of Beanshell (this is optional, but highly recommended)

Demo:


问:
I am trying to connect my eclipse with oracle 11_g but it is asking for ojdbc14.jar
I want to connect 11_g with my eclipse but it is continously asking for ojdbc14.jar</p>

答:
ojdbc14.jar and ojdbc12.jar are required files to connect database with java program which is present on Eclipse.
So you can download ojdbc14.jar from internet or it will present inside your oracle11g folder and add into eclipse.
steps to connect Oracle instance from Eclipse:
1)In Eclipse IDE and Select Database Perspective-Windows->Open Perspective->Other->Database Development).
2)Create Connection Profile, Chose Oracle
3)Choose JDBC Driver and specify its location
4)Specify connection detail e.g. localhost, port(8080), username and password ORACLE database
5)check Test Connection</p>


问:
How to fix ioexception stream closed?
On start up my program gives me the message java.io.IOException: stream closed. It then opens with limited components.

I understand what a stream closed exception is, I just can't figure out how to fix it, in my case. I would really appreciate some help. (I'm sorry about the big chunk of code, but I am not sure what you need to help me)

```<code> try {
    //Defines new file reader and buffered reader
    FileReader file_to_read = new FileReader(path);
    BufferedReader br1 = new BufferedReader(file_to_read);

    //action code

        try {
        //Finds the line number to see the number of cards in each set
        lnr2= new LineNumberReader(new FileReader(new File("C:\\Users\\priceadria\\Desktop\\Words_" + strSetName + ".txt")));
        lnr2.skip(Long.MAX_VALUE);
        strLineNumber2 = String.valueOf(lnr2.getLineNumber());
        lineNumber2 = Integer.parseInt(strLineNumber2);

        //Closes the file reader and buffered reader
        br1.close();
        file_to_read.close();

    } catch (IOException | NumberFormatException e) {
        strLineNumber2 = "0";
    }
        //Adds the set name to the set name array
        lblDeckName[row] = new JLabel (strSetName);

        //Adds all buttons that will be used in the layout into a button array
        JButton aryOptions [][] = new JButton [3][lineNumber];

        //Defines and formats the Add Words button
        JButton btnAddWords = new JButton("Add Words");
        btnAddWords.setOpaque(false);
        btnAddWords.setContentAreaFilled(false);
        btnAddWords.setBorder(null);
        btnAddWords.setBorderPainted(false);

        //Defines and formats the Play button
        JButton btnPlay = new JButton("Play");
        btnPlay.setOpaque(false);
        btnPlay.setContentAreaFilled(false);
        btnPlay.setBorder(null);
        btnPlay.setBorderPainted(false);

        //Defines and formats the Delete Set button
        JButton btnDelete = new JButton("Delete Set");
        btnDelete.setOpaque(false);
        btnDelete.setContentAreaFilled(false);
        btnDelete.setBorder(null);
        btnDelete.setBorderPainted(false);

        //Adds each button to the array based on the number of sets
        aryOptions [0][row] = btnAddWords;
        aryOptions [1][row] = btnPlay;
        aryOptions [2][row] = btnDelete;

        //Formats the GridBagLayout (Spaces are for formatting purposes)
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 0;
        gbc.gridy = row;
        layoutBackground.add(lblDeckName[row],gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 1;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("      "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx =2;
        gbc.gridy = row;
        layoutBackground.add(new JLabel (strSubjectName),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 3;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("                   "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 4;
        gbc.gridy = row;
        layoutBackground.add(new JLabel(strLineNumber2),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 5;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("             |  "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 6;
        gbc.gridy = row;
        layoutBackground.add(aryOptions[0][row],gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 7;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("  |  "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 8;
        gbc.gridy = row;
        layoutBackground.add(aryOptions[1][row],gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 9;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("  |  "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 10;
        gbc.gridy = row;
        layoutBackground.add(aryOptions[2][row],gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 11;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("  |"),gbc);

        //Creates an action event for the delete set button
        btnDelete.addActionListener((ActionEvent a) -> {
            //Finds the source of the button that was clicked
            String strSource = String.valueOf(a.getSource());
            String strSourceCut1 = strSource.substring(25,30);

            //Finds the index of the button that was clicked
            String [] aryIndex = strSourceCut1.split(",");
            String strIndex = aryIndex[0];

            try {
                //Defines new file reader and buffered reader
                FileReader file_to_read2 = new FileReader(path);
                BufferedReader br2 = new BufferedReader(file_to_read2);

                //Finds the numerical index of the button that was clicked
                int intIndex = Integer.parseInt(strIndex)/16;

                //Creates a counter to count line numbers
                int counter = 0;

                while((br2.readLine()) != null) {

                    counter ++;
                    if(intIndex == 0) { //If the index is the first option the normal try/catch returns null pointer, so a new try/catch had to be created
                        try {
                            //Finds the name of the set based on what button was clicked
                            String chosenDeck2 = br2.readLine();
                            String [] aryDeleteDeck = chosenDeck2.split(",");
                            deleteDeck = aryDeleteDeck[0];

                            //Closes the buffered reader and file reader
                            br2.close();
                            file_to_read2.close();

                            //Creates the path to the file that needs to be deleted
                            Path p2 = Paths.get("C:\\Users\\priceadria\\Desktop\\Words_" + deleteDeck + ".txt");
                            Files.delete(p2);

                        } catch (IOException e) {
                            JOptionPane.showMessageDialog(null, e);
                        }

                    } else if ( counter == intIndex) {
                        //Reads the deck name based on the button that was clicked
                        String chosenDeck2 = br2.readLine();

                        //Splits the deck name from the subject
                        String [] aryDeleteDeck = chosenDeck2.split(",");
                        deleteDeck = aryDeleteDeck[0];

                        //Closes the buffered reader and file reader
                        br2.close();
                        file_to_read2.close();

                        //Gets the file that needs to be deleted
                        Path p1 = Paths.get("C:\\Users\\priceadria\\Desktop\\Words_" + deleteDeck + ".txt");
                        Files.delete(p1);

                    }
                }
            }
            catch (HeadlessException | IOException | NumberFormatException e) {
                JOptionPane.showMessageDialog(null, e);
            }
        });

        //Creates an action event for the add words button
        btnAddWords.addActionListener((ActionEvent a) -> {
            //Finds the source of the button that was clicked
            String strSource = String.valueOf(a.getSource());
            String strSourceCut1 = strSource.substring(25,30);

            //Finds the index of the button that was clicked
            String [] aryIndex = strSourceCut1.split(",");
            String strIndex = aryIndex[0];

            try {
                //Creates a new file reader and buffered reader
                FileReader file_to_read3 = new FileReader(path);
                BufferedReader br3 = new BufferedReader(file_to_read3);

                //Finds the index value
                int intIndex = Integer.parseInt(strIndex)/16;

                //Creates a counter to count line numbers
                int counter = 0;

                while((br3.readLine()) != null) {
                    //Increases counter value by 1
                    counter ++;
                    if(intIndex == 0)
                    {
                        try {
                            //Reads the set and subject for the
                            String chosenDeck2 = br3.readLine();

                            //Splits the subject from the set
                            String [] aryDeck = chosenDeck2.split(",");
                            chosenDeck = aryDeck[0];

                            //Closes the buffered reader and file reader
                            br3.close();
                            file_to_read3.close();

                        } catch (Exception e) {
                            JOptionPane.showMessageDialog(null, e);
                        }

                    } else if ( counter == intIndex) {
                        String chosenDeck2 = br3.readLine();

                        String [] aryDeck = chosenDeck2.split(",");
                        chosenDeck = aryDeck[0];

                        br3.close();
                        file_to_read3.close();
                    }

                }
            }
            catch (Exception e) {
                JOptionPane.showMessageDialog(null, e);
            }
            //Opens the new words frame
            frmWords s = new frmWords(deckName, newXPoint, newYPoint, chosenDeck);
            s.setVisible(true);
        });
    }

    } catch (Exception e ) {
        JOptionPane.showMessageDialog(null, e);

    }
</code>```

What I am finding is that when I am deleting the br1.close() the stream closed error stops, but I can find any reason why? Nothing is using that reader, that I can see. And when I do delete it I get and error saying that the test files are being used by other processes, which I can only presume is br1.

I know this may seem confusing to look at, probably because it is sloppy code, but I would really appreciate some help. I am a high school student.

Thanks :)

答:
You could use the closable feature from Java 7:

```<code> try ( FileReader file_to_read = new FileReader(path);
              BufferedReader br1 = new BufferedReader(file_to_read)){
            //Finds the line number to see the number of cards in each set
            lnr2= new LineNumberReader(new FileReader(new File("C:\\Users\\priceadria\\Desktop\\Words_" + strSetName + ".txt")));
            lnr2.skip(Long.MAX_VALUE);
            strLineNumber2 = String.valueOf(lnr2.getLineNumber());
            lineNumber2 = Integer.parseInt(strLineNumber2);
        } catch (IOException | NumberFormatException e) {
            strLineNumber2 = "0";
        }
</code>```

Then you don't have to care about closing your stream or file in the right order.

Furthermore you could just use libs for doing the "readFile" job like apache commons or guava.

Title: How to fix ioexception stream closed?

Body:
On start up my program gives me the message java.io.IOException: stream closed. It then opens with limited components.

I understand what a stream closed exception is, I just can't figure out how to fix it, in my case. I would really appreciate some help. (I'm sorry about the big chunk of code, but I am not sure what you need to help me)

 try {
    //Defines new file reader and buffered reader
    FileReader file_to_read = new FileReader(path);
    BufferedReader br1 = new BufferedReader(file_to_read);

    //action code

        try {
        //Finds the line number to see the number of cards in each set
        lnr2= new LineNumberReader(new FileReader(new File("C:\\Users\\priceadria\\Desktop\\Words_" + strSetName + ".txt")));
        lnr2.skip(Long.MAX_VALUE);
        strLineNumber2 = String.valueOf(lnr2.getLineNumber());
        lineNumber2 = Integer.parseInt(strLineNumber2);

        //Closes the file reader and buffered reader
        br1.close();
        file_to_read.close();

    } catch (IOException | NumberFormatException e) {
        strLineNumber2 = "0";
    }
        //Adds the set name to the set name array
        lblDeckName[row] = new JLabel (strSetName);

        //Adds all buttons that will be used in the layout into a button array
        JButton aryOptions [][] = new JButton [3][lineNumber];

        //Defines and formats the Add Words button
        JButton btnAddWords = new JButton("Add Words");
        btnAddWords.setOpaque(false);
        btnAddWords.setContentAreaFilled(false);
        btnAddWords.setBorder(null);
        btnAddWords.setBorderPainted(false);

        //Defines and formats the Play button
        JButton btnPlay = new JButton("Play");
        btnPlay.setOpaque(false);
        btnPlay.setContentAreaFilled(false);
        btnPlay.setBorder(null);
        btnPlay.setBorderPainted(false);

        //Defines and formats the Delete Set button
        JButton btnDelete = new JButton("Delete Set");
        btnDelete.setOpaque(false);
        btnDelete.setContentAreaFilled(false);
        btnDelete.setBorder(null);
        btnDelete.setBorderPainted(false);

        //Adds each button to the array based on the number of sets
        aryOptions [0][row] = btnAddWords;
        aryOptions [1][row] = btnPlay;
        aryOptions [2][row] = btnDelete;

        //Formats the GridBagLayout (Spaces are for formatting purposes)
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 0;
        gbc.gridy = row;
        layoutBackground.add(lblDeckName[row],gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 1;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("      "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx =2;
        gbc.gridy = row;
        layoutBackground.add(new JLabel (strSubjectName),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 3;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("                   "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 4;
        gbc.gridy = row;
        layoutBackground.add(new JLabel(strLineNumber2),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 5;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("             |  "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 6;
        gbc.gridy = row;
        layoutBackground.add(aryOptions[0][row],gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 7;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("  |  "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 8;
        gbc.gridy = row;
        layoutBackground.add(aryOptions[1][row],gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 9;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("  |  "),gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 10;
        gbc.gridy = row;
        layoutBackground.add(aryOptions[2][row],gbc);

        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.gridx = 11;
        gbc.gridy = row;
        layoutBackground.add(new JLabel("  |"),gbc);

        //Creates an action event for the delete set button
        btnDelete.addActionListener((ActionEvent a) -> {
            //Finds the source of the button that was clicked
            String strSource = String.valueOf(a.getSource());
            String strSourceCut1 = strSource.substring(25,30);

            //Finds the index of the button that was clicked
            String [] aryIndex = strSourceCut1.split(",");
            String strIndex = aryIndex[0];

            try {
                //Defines new file reader and buffered reader
                FileReader file_to_read2 = new FileReader(path);
                BufferedReader br2 = new BufferedReader(file_to_read2);

                //Finds the numerical index of the button that was clicked
                int intIndex = Integer.parseInt(strIndex)/16;

                //Creates a counter to count line numbers
                int counter = 0;

                while((br2.readLine()) != null) {

                    counter ++;
                    if(intIndex == 0) { //If the index is the first option the normal try/catch returns null pointer, so a new try/catch had to be created
                        try {
                            //Finds the name of the set based on what button was clicked
                            String chosenDeck2 = br2.readLine();
                            String [] aryDeleteDeck = chosenDeck2.split(",");
                            deleteDeck = aryDeleteDeck[0];

                            //Closes the buffered reader and file reader
                            br2.close();
                            file_to_read2.close();

                            //Creates the path to the file that needs to be deleted
                            Path p2 = Paths.get("C:\\Users\\priceadria\\Desktop\\Words_" + deleteDeck + ".txt");
                            Files.delete(p2);

                        } catch (IOException e) {
                            JOptionPane.showMessageDialog(null, e);
                        }

                    } else if ( counter == intIndex) {
                        //Reads the deck name based on the button that was clicked
                        String chosenDeck2 = br2.readLine();

                        //Splits the deck name from the subject
                        String [] aryDeleteDeck = chosenDeck2.split(",");
                        deleteDeck = aryDeleteDeck[0];

                        //Closes the buffered reader and file reader
                        br2.close();
                        file_to_read2.close();

                        //Gets the file that needs to be deleted
                        Path p1 = Paths.get("C:\\Users\\priceadria\\Desktop\\Words_" + deleteDeck + ".txt");
                        Files.delete(p1);

                    }
                }
            }
            catch (HeadlessException | IOException | NumberFormatException e) {
                JOptionPane.showMessageDialog(null, e);
            }
        });

        //Creates an action event for the add words button
        btnAddWords.addActionListener((ActionEvent a) -> {
            //Finds the source of the button that was clicked
            String strSource = String.valueOf(a.getSource());
            String strSourceCut1 = strSource.substring(25,30);

            //Finds the index of the button that was clicked
            String [] aryIndex = strSourceCut1.split(",");
            String strIndex = aryIndex[0];

            try {
                //Creates a new file reader and buffered reader
                FileReader file_to_read3 = new FileReader(path);
                BufferedReader br3 = new BufferedReader(file_to_read3);

                //Finds the index value
                int intIndex = Integer.parseInt(strIndex)/16;

                //Creates a counter to count line numbers
                int counter = 0;

                while((br3.readLine()) != null) {
                    //Increases counter value by 1
                    counter ++;
                    if(intIndex == 0)
                    {
                        try {
                            //Reads the set and subject for the
                            String chosenDeck2 = br3.readLine();

                            //Splits the subject from the set
                            String [] aryDeck = chosenDeck2.split(",");
                            chosenDeck = aryDeck[0];

                            //Closes the buffered reader and file reader
                            br3.close();
                            file_to_read3.close();

                        } catch (Exception e) {
                            JOptionPane.showMessageDialog(null, e);
                        }

                    } else if ( counter == intIndex) {
                        String chosenDeck2 = br3.readLine();

                        String [] aryDeck = chosenDeck2.split(",");
                        chosenDeck = aryDeck[0];

                        br3.close();
                        file_to_read3.close();
                    }

                }
            }
            catch (Exception e) {
                JOptionPane.showMessageDialog(null, e);
            }
            //Opens the new words frame
            frmWords s = new frmWords(deckName, newXPoint, newYPoint, chosenDeck);
            s.setVisible(true);
        });
    }

    } catch (Exception e ) {
        JOptionPane.showMessageDialog(null, e);

    }

What I am finding is that when I am deleting the br1.close() the stream closed error stops, but I can find any reason why? Nothing is using that reader, that I can see. And when I do delete it I get and error saying that the test files are being used by other processes, which I can only presume is br1.

I know this may seem confusing to look at, probably because it is sloppy code, but I would really appreciate some help. I am a high school student.

Thanks :)

Body:
You could use the closable feature from Java 7:

 try ( FileReader file_to_read = new FileReader(path);
              BufferedReader br1 = new BufferedReader(file_to_read)){
            //Finds the line number to see the number of cards in each set
            lnr2= new LineNumberReader(new FileReader(new File("C:\\Users\\priceadria\\Desktop\\Words_" + strSetName + ".txt")));
            lnr2.skip(Long.MAX_VALUE);
            strLineNumber2 = String.valueOf(lnr2.getLineNumber());
            lineNumber2 = Integer.parseInt(strLineNumber2);
        } catch (IOException | NumberFormatException e) {
            strLineNumber2 = "0";
        }

Then you don't have to care about closing your stream or file in the right order.

Furthermore you could just use libs for doing the "readFile" job like apache commons or guava.


问:
MethodInvocation always returns null from pointcut expression
I defined one pointcut like below:

```<code><aop:pointcut id="getAllDataCut" expression=
   "execution(* com.example.test.getAllData(com.example test.User)) and args(usr)" />
</code>```

When i call

```<code>final Object[] methodArgs= methodInvocation.getArguements();
</code>```

i am getting always null.

Please give some hints.
Thanks in Advance

答:
Since you know the arguments sent to the method, you can get them as parameter to your aspect method:

```<code>public void aspect(JoinPoint joinPoint, com.example.test.User user) {
  // DO SOME THING WITH user
}
</code>```

if you want to add aspect for methods with different arguments, you can remove the args from the expression

Body:
I defined one pointcut like below:

<aop:pointcut id="getAllDataCut" expression=
   "execution(* com.example.test.getAllData(com.example test.User)) and args(usr)" />

When i call

final Object[] methodArgs= methodInvocation.getArguements();

i am getting always null.

Please give some hints.
Thanks in Advance

Body:
Since you know the arguments sent to the method, you can get them as parameter to your aspect method:

public void aspect(JoinPoint joinPoint, com.example.test.User user) {
  // DO SOME THING WITH user
}

if you want to add aspect for methods with different arguments, you can remove the args from the expression


问:
Transitions with nested data D3.js
I've recently begun learning D3.js and I am struggling to create a transition in a scatter plot with the following data:

```<code>var data = [
    {"year" : "2004", "x":100, "y":300, "size": 2, "type": "A"},
    {"year" : "2005", "x":200, "y":200, "size": 2, "type": "A"},
    {"year" : "2006", "x":300, "y":100, "size": 2, "type": "A"},
    {"year" : "2004", "x":150, "y":250, "size": 2.382450, "type": "B"},
    {"year" : "2005", "x":150, "y":250, "size": 3.078548, "type": "B"},
    {"year" : "2006", "x":150, "y":250, "size": 4.265410, "type": "B"}];
</code>```

Where in the scatter plot there are 2 points (type A&B) and they change location (x&y) and size by year. I've created a fiddle where I try to nest the data and plot the points, but making the next step of using transition() function is confusing. More specifically, I am still declaring the whole data, but to make transitions work I only need part of the data.

答:
The key to understand what you want lies here:

There are 2 points and they change location (x&y) and size by year

Therefore, this is clearly a XY problem. Your problem is not "how to transition with nested data". Your problem is "how to transition by year".

My proposed solution involves, first of all, dropping that nested array. You don't need that.

Instead, get all the years in the data...

```<code>var years = [...new Set(data.map(function(d) {
  return d.year
}))];
</code>```

..., filter the data by year...

```<code>var dataStart = data.filter(function(d) {
  return d.year === years[0]
});
</code>```

... and loop trough the years. Here, I'm using d3.interval():

```<code>var counter = 1;
var timer = d3.interval(transition, 1500);

function transition() {

  var newData = data.filter(function(d) {
    return d.year === years[counter]
  });

  svg.selectAll("circle").data(newData)
    .transition()
    .duration(1000)
    .attr("cx", function(d) {
      console.log(d)
      return d.x;
    })
    .attr("cy", function(d) {
      return d.y;
    })
    .attr("r", function(d) {
      return d.size * 10;
    });
  counter += 1;
  if (counter === 3) {
    timer.stop()
  }
}
</code>```

Here is the demo:

var data = [{
      "year": "2004",
      "x": 100,
      "y": 100,
      "size": 2,
      "type": "A"
    }, {
      "year": "2005",
      "x": 200,
      "y": 180,
      "size": 2,
      "type": "A"
    }, {
      "year": "2006",
      "x": 300,
      "y": 50,
      "size": 2,
      "type": "A"
    }, {
      "year": "2004",
      "x": 150,
      "y": 150,
      "size": 2.382450,
      "type": "B"
    }, {
      "year": "2005",
      "x": 150,
      "y": 50,
      "size": 3.078548,
      "type": "B"
    }, {
      "year": "2006",
      "x": 150,
      "y": 100,
      "size": 4.265410,
      "type": "B"
    }];

    var width = 400,
      height = 200;

    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height);

    var years = [...new Set(data.map(function(d) {
      return d.year
    }))];

    var dataStart = data.filter(function(d) {
      return d.year === years[0]
    });

    var cell = svg.selectAll("circle")
      .data(dataStart);

    cell.enter()
      .append("circle")
      .attr("cx", function(d) {
        return d.x;
      })
      .attr("cy", function(d) {
        return d.y;
      })
      .attr("r", function(d) {
        return d.size * 10;
      });

    var counter = 1;
    var timer = d3.interval(transition, 1500);

    function transition() {

      var newData = data.filter(function(d) {
        return d.year === years[counter]
      });

      svg.selectAll("circle").data(newData)
        .transition()
        .duration(1000)
        .attr("cx", function(d) {
          return d.x;
        })
        .attr("cy", function(d) {
          return d.y;
        })
        .attr("r", function(d) {
          return d.size * 10;
        });
      counter += 1;
      if (counter === 3) {
        timer.stop()
      }
    }```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://d3js.org/d3.v4.min.js"></script></code>```

Title: Transitions with nested data D3.js

Body:
I've recently begun learning D3.js and I am struggling to create a transition in a scatter plot with the following data:

var data = [
    {"year" : "2004", "x":100, "y":300, "size": 2, "type": "A"},
    {"year" : "2005", "x":200, "y":200, "size": 2, "type": "A"},
    {"year" : "2006", "x":300, "y":100, "size": 2, "type": "A"},
    {"year" : "2004", "x":150, "y":250, "size": 2.382450, "type": "B"},
    {"year" : "2005", "x":150, "y":250, "size": 3.078548, "type": "B"},
    {"year" : "2006", "x":150, "y":250, "size": 4.265410, "type": "B"}];

Where in the scatter plot there are 2 points (type A&B) and they change location (x&y) and size by year. I've created a fiddle where I try to nest the data and plot the points, but making the next step of using transition() function is confusing. More specifically, I am still declaring the whole data, but to make transitions work I only need part of the data.

Body:
The key to understand what you want lies here:

There are 2 points and they change location (x&y) and size by year

Therefore, this is clearly a XY problem. Your problem is not "how to transition with nested data". Your problem is "how to transition by year".

My proposed solution involves, first of all, dropping that nested array. You don't need that.

Instead, get all the years in the data...

var years = [...new Set(data.map(function(d) {
  return d.year
}))];

..., filter the data by year...

var dataStart = data.filter(function(d) {
  return d.year === years[0]
});

... and loop trough the years. Here, I'm using d3.interval():

var counter = 1;
var timer = d3.interval(transition, 1500);

function transition() {

  var newData = data.filter(function(d) {
    return d.year === years[counter]
  });

  svg.selectAll("circle").data(newData)
    .transition()
    .duration(1000)
    .attr("cx", function(d) {
      console.log(d)
      return d.x;
    })
    .attr("cy", function(d) {
      return d.y;
    })
    .attr("r", function(d) {
      return d.size * 10;
    });
  counter += 1;
  if (counter === 3) {
    timer.stop()
  }
}

Here is the demo:

var data = [{
      "year": "2004",
      "x": 100,
      "y": 100,
      "size": 2,
      "type": "A"
    }, {
      "year": "2005",
      "x": 200,
      "y": 180,
      "size": 2,
      "type": "A"
    }, {
      "year": "2006",
      "x": 300,
      "y": 50,
      "size": 2,
      "type": "A"
    }, {
      "year": "2004",
      "x": 150,
      "y": 150,
      "size": 2.382450,
      "type": "B"
    }, {
      "year": "2005",
      "x": 150,
      "y": 50,
      "size": 3.078548,
      "type": "B"
    }, {
      "year": "2006",
      "x": 150,
      "y": 100,
      "size": 4.265410,
      "type": "B"
    }];

    var width = 400,
      height = 200;

    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height);

    var years = [...new Set(data.map(function(d) {
      return d.year
    }))];

    var dataStart = data.filter(function(d) {
      return d.year === years[0]
    });

    var cell = svg.selectAll("circle")
      .data(dataStart);

    cell.enter()
      .append("circle")
      .attr("cx", function(d) {
        return d.x;
      })
      .attr("cy", function(d) {
        return d.y;
      })
      .attr("r", function(d) {
        return d.size * 10;
      });

    var counter = 1;
    var timer = d3.interval(transition, 1500);

    function transition() {

      var newData = data.filter(function(d) {
        return d.year === years[counter]
      });

      svg.selectAll("circle").data(newData)
        .transition()
        .duration(1000)
        .attr("cx", function(d) {
          return d.x;
        })
        .attr("cy", function(d) {
          return d.y;
        })
        .attr("r", function(d) {
          return d.size * 10;
        });
      counter += 1;
      if (counter === 3) {
        timer.stop()
      }
    }

<script src="https://d3js.org/d3.v4.min.js"></script>


问:
interact between google map API and fusion table in order to get data
I have a fusion table of polygons that can show on my google map javascript API.

The link is right here: https://fusiontables.google.com/data?docid=1O-VUAKZnf0ey4-BttV7xsjXh9pIf6qK60G7-30eB

In my fusion table, there is some districts of the map which has been divided by polygons.

I wish that when I add a marker on my google map javascript API, I can identify which district(polygon) is the marker at.

Is there a way that the google map Javascript API can retrieve data from the fusion table?

Thank you so much for your help

答:
I think you are after Fusion Tables Layer.
https://developers.google.com/maps/documentation/javascript/fusiontableslayer

You basically can create fusion tables layer and add to your map. Hope it points you to the right direction.