Проще всего вычислить нужные вам величины за пределами ggplot, так как трудно отслеживать, что вычисляет ggplot и где эти величины хранятся и доступны.
Сначала суммируем ваши данные:
library(dplyr)
mtcars %>% count(cyl = factor(cyl), gear = factor(gear)) %>%
ungroup() %>% # drop if you want percentages per cylinder
mutate(pct = prop.table(n) * 100)
## # A tibble: 8 × 4
## cyl gear n pct
##
## 1 4 3 1 3.125
## 2 4 4 8 25.000
## 3 4 5 2 6.250
## 4 6 3 2 6.250
## 5 6 4 4 12.500
## 6 6 5 1 3.125
## 7 8 3 12 37.500
## 8 8 5 2 6.250
Сохраните это, если хотите, или прямо в ggplot:
mtcars %>% count(cyl = factor(cyl), gear = factor(gear)) %>%
ungroup() %>%
mutate(pct = prop.table(n) * 100) %>%
ggplot(aes(x = cyl, y = pct, fill = gear)) +
geom_bar(stat = 'identity', position = 'dodge') +
geom_text(aes(y = pct + .5, # nudge above top of bar
label = paste0(pct, '%')), # prettify
position = position_dodge(width = .9),
size = 3)
Если вы действительно хотите его сохранить все внутренние по отношению к ggplot, вы можете использовать geom_text
с stat = 'count'
(или stat_count
с geom = "text"
, если хотите):
ggplot(data = mtcars, aes(x = factor(cyl), fill = factor(gear))) +
geom_bar(aes(y = prop.table(..count..) * 100),
position = "dodge") +
geom_text(aes(y = prop.table(..count..) * 100 + 0.5,
label = paste0(prop.table(..count..) * 100, '%')),
stat = 'count',
position = position_dodge(.9),
size = 3) +
labs(x = 'cyl', y = 'pct', fill = 'gear')
, который изображает одно и то же.
Embedded Jetty настолько замечателен здесь.
У вас есть несколько общих опций:
ServletHolder
(может быть любое значение или тип объекта) ServletContext
в своей основной папке, а затем получите доступ к нему через ServletContext
в вашем приложении (может быть любое значение или тип объекта). Примеры:
package jetty;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
public class ObjectPassingExample
{
public static void main(String args[]) throws Exception
{
Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
// Option 1: Direct servlet instantiation and ServletHolder
HelloServlet hello = new HelloServlet("everyone");
ServletHolder helloHolder = new ServletHolder(hello);
context.addServlet(helloHolder, "/hello/*");
// Option 2: Using ServletContext attribute
context.setAttribute("my.greeting", "you");
context.addServlet(GreetingServlet.class, "/greetings/*");
server.setHandler(context);
server.start();
server.join();
}
public static class HelloServlet extends HttpServlet
{
private final String hello;
public HelloServlet(String greeting)
{
this.hello = greeting;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
resp.setContentType("text/plain");
resp.getWriter().println("Hello " + this.hello);
}
}
public static class GreetingServlet extends HttpServlet
{
private String greeting;
@Override
public void init() throws ServletException
{
this.greeting = (String) getServletContext().getAttribute("my.greeting");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
{
resp.setContentType("text/plain");
resp.getWriter().println("Greetings to " + this.greeting);
}
}
}
Вы хотите передать один и тот же единственный экземпляр каждому сервлету?
Используйте шаблон Singleton , чтобы создать единый экземпляр, доступный во всем мире.
Простейшим способом сделать это на Java является Enum
. См. Учебник Oracle . Также см. эту статью и книгу Эффективное Java: Руководство по языку программирования, второе издание (ISBN 978-0-321-35668-0, 2008) by Dr. Джошуа Блох .
Так что не нужно передавать объект. Каждый сервлет может получить доступ к одному и тому же экземпляру через enum.
Если вы хотите выполнить некоторую работу, когда ваше веб-приложение запускается первым, но перед любым сервлетом в этой сети приложение обработало любой запрос, напишите класс, который реализует интерфейс ServletContextListener
.
Отметьте свой класс аннотацией @WebListener
, чтобы ваш веб-контейнер автоматически создавал экземпляр и вызывал.
У меня была аналогичная ситуация, но мне нужно было предоставить один сингл с сервлетом, развернутым через войну, с помощью горячего (повторного) развертывания в контейнере Jetty. Принятый ответ был не совсем тем, что мне нужно в моем случае, так как сервлет имеет жизненный цикл и контекст, управляемые установщиком.
Я закончил с применением грубой силы, добавив объект в server
, который сохраняется для жизни контейнера, а затем извлекает объект из сервлета (ов). Это потребовало загрузки класса объекта в родительский (системный) загрузчик классов, чтобы war Webapp не загружал свою собственную версию класса в свой собственный загрузчик классов, что вызвало бы исключение литья, как описано здесь здесь .
Код сервера Embedded Jetty:
Server server = new Server(8090);
// Add all classes related to the object(s) you want to share here.
WebAppContext.addSystemClasses(server, "my.package.MyFineClass", ...);
// Handler config
ContextHandlerCollection contexts = new ContextHandlerCollection();
HandlerCollection handlers = new HandlerCollection();
handlers.setHandlers(new Handler[] { contexts });
server.setHandler(handlers);
// Deployer config (hot deploy)
DeploymentManager deployer = new DeploymentManager();
DebugListener debug = new DebugListener(System.err,true,true,true);
server.addBean(debug);
deployer.addLifeCycleBinding(new DebugListenerBinding(debug));
deployer.setContexts(contexts);
deployer.setContextAttribute(
"org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$");
WebAppProvider webapp_provider = new WebAppProvider();
webapp_provider.setMonitoredDirName("/.../webapps");
webapp_provider.setScanInterval(1);
webapp_provider.setExtractWars(true);
webapp_provider.setConfigurationManager(new PropertiesConfigurationManager());
deployer.addAppProvider(webapp_provider);
server.addBean(deployer);
// Other config...
// Tuck any objects/data you want into the root server object.
server.setAttribute("my.package.MyFineClass", myFineSingleton);
server.start();
server.join();
Пример сервлета:
public class MyFineServlet extends HttpServlet
{
MyFineClass myFineSingleton;
@Override
public void init() throws ServletException
{
// Sneak access to the root server object (non-portable).
// Not possible to cast this to `Server` because of classloader restrictions in Jetty.
Object server = request.getAttribute("org.eclipse.jetty.server.Server");
// Because we cannot cast to `Server`, use reflection to access the object we tucked away there.
try {
myFineSingleton = (MyFineClass) server.getClass().getMethod("getAttribute", String.class).invoke(server, "my.package.MyFineClass");
} catch (Exception ex) {
throw new ServletException("Unable to reflect MyFineClass instance via Jetty Server", ex);
}
}
@Override
protected void doGet( HttpServletRequest request,
HttpServletResponse response ) throws ServletException, IOException
{
response.setContentType("text/html");
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().println("<h1>Hello from MyFineServlet</h1>");
response.getWriter().println("Here's: " + myFineSingleton.toString());
}
}
Мой файл сборки для сервлета (sbt) помещал my.package.MyFineClass
в «предоставленный» объем, чтобы он не попал в войну, поскольку он уже будет загружен на сервер Jetty.
Server
, которое реализует ваш контейнер, и, возможно, это может измениться для Jetty также в разных версиях.
– Reed Sandberg
13 June 2018 в 23:57
init
работает отлично! Благодарю. – Freddy 12 September 2016 в 23:38