Compare commits
No commits in common. "0.2-rc1" and "master" have entirely different histories.
41
.gitignore
vendored
|
@ -1,6 +1,35 @@
|
||||||
etc/volkszaehler.conf.php
|
*~
|
||||||
misc/sql/demo/pulses.dummy.copy
|
|
||||||
.project
|
# Binaries
|
||||||
.buildpath
|
/src/vzlogger
|
||||||
.settings/
|
|
||||||
lib/vendor/*
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
*.lo
|
||||||
|
*.o
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
*.la
|
||||||
|
*.a
|
||||||
|
|
||||||
|
# automake
|
||||||
|
Makefile
|
||||||
|
.deps
|
||||||
|
|
||||||
|
# autoconf
|
||||||
|
/autom4te.cache
|
||||||
|
|
||||||
|
/config.status
|
||||||
|
/config.log
|
||||||
|
/config.h
|
||||||
|
stamp-h1
|
||||||
|
|
||||||
|
/libtool
|
||||||
|
|
||||||
|
# Debian packaging
|
||||||
|
/debian/config.log
|
||||||
|
|
3
.gitmodules
vendored
|
@ -1,3 +0,0 @@
|
||||||
[submodule "misc/frontend/fnordlicht"]
|
|
||||||
path = misc/frontend/fnordlicht
|
|
||||||
url = git://github.com/stv0g/libfn.git
|
|
|
@ -1,2 +0,0 @@
|
||||||
Deny from all
|
|
||||||
Allow from localhost
|
|
1
AUTHORS
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Written by Steffen Vogel <info@steffenvogel.de>
|
|
@ -1 +0,0 @@
|
||||||
There is no stable release yet. Have some patience please or contribute.
|
|
53
COPYING
|
@ -619,56 +619,3 @@ Program, unless a warranty or assumption of liability accompanies a
|
||||||
copy of the Program in return for a fee.
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
|
||||||
|
|
0
ChangeLog
Normal file
5
INSTALL
|
@ -1 +1,4 @@
|
||||||
Refer to the wiki: http://wiki.volkszaehler.org/howto/getstarted
|
vzlogger is build with the GNU Autotools buildsystem. All required files
|
||||||
|
are included in this repository. There is no dependecy on autotools!
|
||||||
|
|
||||||
|
Just use the standard './configure && make && make install' triplet
|
||||||
|
|
3
Makefile.am
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
sysconf_DATA = etc/vzlogger.conf
|
||||||
|
|
||||||
|
SUBDIRS = src docs
|
|
@ -36,7 +36,7 @@ subdir = .
|
||||||
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
|
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
|
||||||
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
|
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
|
||||||
$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
|
$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
|
||||||
depcomp install-sh missing
|
compile depcomp install-sh missing
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
|
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
|
||||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
|
@ -137,8 +137,12 @@ CPPFLAGS = @CPPFLAGS@
|
||||||
CYGPATH_W = @CYGPATH_W@
|
CYGPATH_W = @CYGPATH_W@
|
||||||
DEFS = @DEFS@
|
DEFS = @DEFS@
|
||||||
DEPDIR = @DEPDIR@
|
DEPDIR = @DEPDIR@
|
||||||
DEPS_CFLAGS = @DEPS_CFLAGS@
|
DEPS_LOCAL_CFLAGS = @DEPS_LOCAL_CFLAGS@
|
||||||
DEPS_LIBS = @DEPS_LIBS@
|
DEPS_LOCAL_LIBS = @DEPS_LOCAL_LIBS@
|
||||||
|
DEPS_SML_CFLAGS = @DEPS_SML_CFLAGS@
|
||||||
|
DEPS_SML_LIBS = @DEPS_SML_LIBS@
|
||||||
|
DEPS_VZ_CFLAGS = @DEPS_VZ_CFLAGS@
|
||||||
|
DEPS_VZ_LIBS = @DEPS_VZ_LIBS@
|
||||||
ECHO_C = @ECHO_C@
|
ECHO_C = @ECHO_C@
|
||||||
ECHO_N = @ECHO_N@
|
ECHO_N = @ECHO_N@
|
||||||
ECHO_T = @ECHO_T@
|
ECHO_T = @ECHO_T@
|
||||||
|
@ -168,6 +172,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||||
PKG_CONFIG = @PKG_CONFIG@
|
PKG_CONFIG = @PKG_CONFIG@
|
||||||
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
SET_MAKE = @SET_MAKE@
|
SET_MAKE = @SET_MAKE@
|
||||||
SHELL = @SHELL@
|
SHELL = @SHELL@
|
||||||
STRIP = @STRIP@
|
STRIP = @STRIP@
|
||||||
|
@ -214,7 +219,7 @@ target_alias = @target_alias@
|
||||||
top_build_prefix = @top_build_prefix@
|
top_build_prefix = @top_build_prefix@
|
||||||
top_builddir = @top_builddir@
|
top_builddir = @top_builddir@
|
||||||
top_srcdir = @top_srcdir@
|
top_srcdir = @top_srcdir@
|
||||||
sysconf_DATA = vzlogger.conf
|
sysconf_DATA = etc/vzlogger.conf
|
||||||
SUBDIRS = src docs
|
SUBDIRS = src docs
|
||||||
all: config.h
|
all: config.h
|
||||||
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
0
NEWS
Normal file
35
README
|
@ -1,28 +1,11 @@
|
||||||
This are the scripts running on volkszaehler.org
|
vzlogger...
|
||||||
Feel free to setup your own installation and protect your privacy!
|
* is a tool to read and log measurements of a wide variety of smartmeters, sensors to the volkszaehler.org middleware.
|
||||||
|
* can run as a daemon or via Cron.
|
||||||
|
* includes a tiny onboard httpd to serve realtime readings to the AJAX web frontend.
|
||||||
|
* is written in ANSI C and should run on most embedded devices which conform to the POSIX standard.
|
||||||
|
|
||||||
volkszaehler.org/
|
Feel free to implement support your own hardware ;)
|
||||||
|_ htdocs/ static files accessible through the web
|
If you have questions, contact Steffen Vogel <info@steffenvogel.de>
|
||||||
| |_ middleware.php middleware bootstrapping
|
|
||||||
| \_ frontend web frontend
|
|
||||||
|
|
|
||||||
|_ etc/ configuration files
|
|
||||||
|_ var/ SQLite database (optional)
|
|
||||||
|_ lib/ middleware libraries
|
|
||||||
|_ misc/
|
|
||||||
|_ controller/
|
|
||||||
| |_ vzlogger/ command line tool to log meters/sensors
|
|
||||||
| \_ batch/ batch scripts for logging (prototypes)
|
|
||||||
|
|
|
||||||
|_ docs/ documentation
|
|
||||||
|_ frontend/
|
|
||||||
|_ graphics/ several graphics for docs, etc..
|
|
||||||
|_ sql/ database schema dumps
|
|
||||||
| \_ demo/ demo data
|
|
||||||
|
|
|
||||||
|_ tools/ scripts for imports, installation etc.
|
|
||||||
\_ tests/ simple tests for middleware classes
|
|
||||||
|
|
||||||
Wiki: http://wiki.volkszaehler.org
|
More information is available in our wiki:
|
||||||
Other: http://volkszaehler.org
|
http://wiki.volkszaehler.org/software/controller/vzlogger
|
||||||
Or contact our mailing list: volkszaehler-dev@lists.volkszaehler.org
|
|
||||||
|
|
35
misc/controller/vzlogger/aclocal.m4 → aclocal.m4
vendored
|
@ -797,6 +797,41 @@ AC_MSG_RESULT([$_am_result])
|
||||||
rm -f confinc confmf
|
rm -f confinc confmf
|
||||||
])
|
])
|
||||||
|
|
||||||
|
# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008
|
||||||
|
# Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# serial 6
|
||||||
|
|
||||||
|
# AM_PROG_CC_C_O
|
||||||
|
# --------------
|
||||||
|
# Like AC_PROG_CC_C_O, but changed for automake.
|
||||||
|
AC_DEFUN([AM_PROG_CC_C_O],
|
||||||
|
[AC_REQUIRE([AC_PROG_CC_C_O])dnl
|
||||||
|
AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||||
|
AC_REQUIRE_AUX_FILE([compile])dnl
|
||||||
|
# FIXME: we rely on the cache variable name because
|
||||||
|
# there is no other way.
|
||||||
|
set dummy $CC
|
||||||
|
am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
|
||||||
|
eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
|
||||||
|
if test "$am_t" != yes; then
|
||||||
|
# Losing compiler, so override with the script.
|
||||||
|
# FIXME: It is wrong to rewrite CC.
|
||||||
|
# But if we don't then we get into trouble of one sort or another.
|
||||||
|
# A longer-term fix would be to have automake use am__CC in this case,
|
||||||
|
# and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
|
||||||
|
CC="$am_aux_dir/compile $CC"
|
||||||
|
fi
|
||||||
|
dnl Make sure AC_PROG_CC is never called again, or it will override our
|
||||||
|
dnl setting of CC.
|
||||||
|
m4_define([AC_PROG_CC],
|
||||||
|
[m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
|
||||||
|
])
|
||||||
|
|
||||||
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
||||||
|
|
||||||
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
|
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
|
143
compile
Executable file
|
@ -0,0 +1,143 @@
|
||||||
|
#! /bin/sh
|
||||||
|
# Wrapper for compilers which do not understand `-c -o'.
|
||||||
|
|
||||||
|
scriptversion=2009-10-06.20; # UTC
|
||||||
|
|
||||||
|
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009 Free Software
|
||||||
|
# Foundation, Inc.
|
||||||
|
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
# This file is maintained in Automake, please report
|
||||||
|
# bugs to <bug-automake@gnu.org> or send patches to
|
||||||
|
# <automake-patches@gnu.org>.
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
'')
|
||||||
|
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||||
|
exit 1;
|
||||||
|
;;
|
||||||
|
-h | --h*)
|
||||||
|
cat <<\EOF
|
||||||
|
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||||
|
|
||||||
|
Wrapper for compilers which do not understand `-c -o'.
|
||||||
|
Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||||
|
arguments, and rename the output as expected.
|
||||||
|
|
||||||
|
If you are trying to build a whole package this is not the
|
||||||
|
right script to run: please start by reading the file `INSTALL'.
|
||||||
|
|
||||||
|
Report bugs to <bug-automake@gnu.org>.
|
||||||
|
EOF
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
-v | --v*)
|
||||||
|
echo "compile $scriptversion"
|
||||||
|
exit $?
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
ofile=
|
||||||
|
cfile=
|
||||||
|
eat=
|
||||||
|
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
if test -n "$eat"; then
|
||||||
|
eat=
|
||||||
|
else
|
||||||
|
case $1 in
|
||||||
|
-o)
|
||||||
|
# configure might choose to run compile as `compile cc -o foo foo.c'.
|
||||||
|
# So we strip `-o arg' only if arg is an object.
|
||||||
|
eat=1
|
||||||
|
case $2 in
|
||||||
|
*.o | *.obj)
|
||||||
|
ofile=$2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set x "$@" -o "$2"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*.c)
|
||||||
|
cfile=$1
|
||||||
|
set x "$@" "$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
set x "$@" "$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -z "$ofile" || test -z "$cfile"; then
|
||||||
|
# If no `-o' option was seen then we might have been invoked from a
|
||||||
|
# pattern rule where we don't need one. That is ok -- this is a
|
||||||
|
# normal compilation that the losing compiler can handle. If no
|
||||||
|
# `.c' file was seen then we are probably linking. That is also
|
||||||
|
# ok.
|
||||||
|
exec "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Name of file we expect compiler to create.
|
||||||
|
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||||
|
|
||||||
|
# Create the lock directory.
|
||||||
|
# Note: use `[/\\:.-]' here to ensure that we don't use the same name
|
||||||
|
# that we are using for the .o file. Also, base the name on the expected
|
||||||
|
# object file name, since that is what matters with a parallel build.
|
||||||
|
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||||
|
while true; do
|
||||||
|
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
# FIXME: race condition here if user kills between mkdir and trap.
|
||||||
|
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||||
|
|
||||||
|
# Run the compile.
|
||||||
|
"$@"
|
||||||
|
ret=$?
|
||||||
|
|
||||||
|
if test -f "$cofile"; then
|
||||||
|
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||||
|
elif test -f "${cofile}bj"; then
|
||||||
|
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||||
|
fi
|
||||||
|
|
||||||
|
rmdir "$lockdir"
|
||||||
|
exit $ret
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: shell-script
|
||||||
|
# sh-indentation: 2
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-time-zone: "UTC"
|
||||||
|
# time-stamp-end: "; # UTC"
|
||||||
|
# End:
|
|
@ -10,6 +10,9 @@
|
||||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||||
#undef HAVE_FCNTL_H
|
#undef HAVE_FCNTL_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <getopt.h> header file. */
|
||||||
|
#undef HAVE_GETOPT_H
|
||||||
|
|
||||||
/* Define to 1 if you have the `gettimeofday' function. */
|
/* Define to 1 if you have the `gettimeofday' function. */
|
||||||
#undef HAVE_GETTIMEOFDAY
|
#undef HAVE_GETTIMEOFDAY
|
||||||
|
|
||||||
|
@ -26,10 +29,16 @@
|
||||||
/* Define to 1 if you have the `memset' function. */
|
/* Define to 1 if you have the `memset' function. */
|
||||||
#undef HAVE_MEMSET
|
#undef HAVE_MEMSET
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <pthread.h> header file. */
|
||||||
|
#undef HAVE_PTHREAD_H
|
||||||
|
|
||||||
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
|
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
|
||||||
and to 0 otherwise. */
|
and to 0 otherwise. */
|
||||||
#undef HAVE_REALLOC
|
#undef HAVE_REALLOC
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <signal.h> header file. */
|
||||||
|
#undef HAVE_SIGNAL_H
|
||||||
|
|
||||||
/* Define to 1 if you have the `sqrt' function. */
|
/* Define to 1 if you have the `sqrt' function. */
|
||||||
#undef HAVE_SQRT
|
#undef HAVE_SQRT
|
||||||
|
|
||||||
|
@ -72,8 +81,11 @@
|
||||||
/* Define to 1 if you have the <unistd.h> header file. */
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
#undef HAVE_UNISTD_H
|
#undef HAVE_UNISTD_H
|
||||||
|
|
||||||
/* No-debug Mode */
|
/* Local interface */
|
||||||
#undef NDEBUG
|
#undef LOCAL_SUPPORT
|
||||||
|
|
||||||
|
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||||
|
#undef NO_MINUS_C_MINUS_O
|
||||||
|
|
||||||
/* Name of package */
|
/* Name of package */
|
||||||
#undef PACKAGE
|
#undef PACKAGE
|
||||||
|
@ -96,6 +108,9 @@
|
||||||
/* Define to the version of this package. */
|
/* Define to the version of this package. */
|
||||||
#undef PACKAGE_VERSION
|
#undef PACKAGE_VERSION
|
||||||
|
|
||||||
|
/* Smart Messaging Language */
|
||||||
|
#undef SML_SUPPORT
|
||||||
|
|
||||||
/* Define to 1 if you have the ANSI C header files. */
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
#undef STDC_HEADERS
|
#undef STDC_HEADERS
|
||||||
|
|
646
misc/controller/vzlogger/configure → configure
vendored
|
@ -1,8 +1,8 @@
|
||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.67 for vzlogger 0.2.
|
# Generated by GNU Autoconf 2.67 for vzlogger 0.3.3.
|
||||||
#
|
#
|
||||||
# Report bugs to <info@steffenvogel.de>.
|
# Report bugs to <http://bugs.volkszaehler.org>.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
|
||||||
|
@ -231,10 +231,10 @@ fi
|
||||||
$as_echo "$0: be upgraded to zsh 4.3.4 or later."
|
$as_echo "$0: be upgraded to zsh 4.3.4 or later."
|
||||||
else
|
else
|
||||||
$as_echo "$0: Please tell bug-autoconf@gnu.org and
|
$as_echo "$0: Please tell bug-autoconf@gnu.org and
|
||||||
$0: info@steffenvogel.de about your system, including any
|
$0: http://bugs.volkszaehler.org about your system,
|
||||||
$0: error possibly output before this message. Then install
|
$0: including any error possibly output before this
|
||||||
$0: a modern shell, or manually run the script under such a
|
$0: message. Then install a modern shell, or manually run
|
||||||
$0: shell if you do have one."
|
$0: the script under such a shell if you do have one."
|
||||||
fi
|
fi
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -552,12 +552,12 @@ MAKEFLAGS=
|
||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='vzlogger'
|
PACKAGE_NAME='vzlogger'
|
||||||
PACKAGE_TARNAME='vzlogger'
|
PACKAGE_TARNAME='vzlogger'
|
||||||
PACKAGE_VERSION='0.2'
|
PACKAGE_VERSION='0.3.3'
|
||||||
PACKAGE_STRING='vzlogger 0.2'
|
PACKAGE_STRING='vzlogger 0.3.3'
|
||||||
PACKAGE_BUGREPORT='info@steffenvogel.de'
|
PACKAGE_BUGREPORT='http://bugs.volkszaehler.org'
|
||||||
PACKAGE_URL=''
|
PACKAGE_URL=''
|
||||||
|
|
||||||
ac_unique_file="src/main.c"
|
ac_unique_file="src/meter.c"
|
||||||
# Factoring default headers for most tests.
|
# Factoring default headers for most tests.
|
||||||
ac_includes_default="\
|
ac_includes_default="\
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -597,15 +597,26 @@ ac_includes_default="\
|
||||||
ac_subst_vars='am__EXEEXT_FALSE
|
ac_subst_vars='am__EXEEXT_FALSE
|
||||||
am__EXEEXT_TRUE
|
am__EXEEXT_TRUE
|
||||||
LTLIBOBJS
|
LTLIBOBJS
|
||||||
|
READER_BUILD_FALSE
|
||||||
|
READER_BUILD_TRUE
|
||||||
|
DEPS_LOCAL_LIBS
|
||||||
|
DEPS_LOCAL_CFLAGS
|
||||||
|
LOCAL_SUPPORT_FALSE
|
||||||
|
LOCAL_SUPPORT_TRUE
|
||||||
|
DEPS_SML_LIBS
|
||||||
|
DEPS_SML_CFLAGS
|
||||||
|
SML_SUPPORT_FALSE
|
||||||
|
SML_SUPPORT_TRUE
|
||||||
LIBOBJS
|
LIBOBJS
|
||||||
EGREP
|
EGREP
|
||||||
GREP
|
GREP
|
||||||
CPP
|
CPP
|
||||||
DEPS_LIBS
|
DEPS_VZ_LIBS
|
||||||
DEPS_CFLAGS
|
DEPS_VZ_CFLAGS
|
||||||
PKG_CONFIG_LIBDIR
|
PKG_CONFIG_LIBDIR
|
||||||
PKG_CONFIG_PATH
|
PKG_CONFIG_PATH
|
||||||
PKG_CONFIG
|
PKG_CONFIG
|
||||||
|
RANLIB
|
||||||
am__fastdepCC_FALSE
|
am__fastdepCC_FALSE
|
||||||
am__fastdepCC_TRUE
|
am__fastdepCC_TRUE
|
||||||
CCDEPMODE
|
CCDEPMODE
|
||||||
|
@ -687,6 +698,9 @@ ac_subst_files=''
|
||||||
ac_user_opts='
|
ac_user_opts='
|
||||||
enable_option_checking
|
enable_option_checking
|
||||||
enable_dependency_tracking
|
enable_dependency_tracking
|
||||||
|
enable_sml
|
||||||
|
enable_local
|
||||||
|
with_reader
|
||||||
enable_debug
|
enable_debug
|
||||||
'
|
'
|
||||||
ac_precious_vars='build_alias
|
ac_precious_vars='build_alias
|
||||||
|
@ -700,9 +714,13 @@ CPPFLAGS
|
||||||
PKG_CONFIG
|
PKG_CONFIG
|
||||||
PKG_CONFIG_PATH
|
PKG_CONFIG_PATH
|
||||||
PKG_CONFIG_LIBDIR
|
PKG_CONFIG_LIBDIR
|
||||||
DEPS_CFLAGS
|
DEPS_VZ_CFLAGS
|
||||||
DEPS_LIBS
|
DEPS_VZ_LIBS
|
||||||
CPP'
|
CPP
|
||||||
|
DEPS_SML_CFLAGS
|
||||||
|
DEPS_SML_LIBS
|
||||||
|
DEPS_LOCAL_CFLAGS
|
||||||
|
DEPS_LOCAL_LIBS'
|
||||||
|
|
||||||
|
|
||||||
# Initialize some variables set by options.
|
# Initialize some variables set by options.
|
||||||
|
@ -1245,7 +1263,7 @@ if test "$ac_init_help" = "long"; then
|
||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# Omit some internal or obsolete options to make the list less imposing.
|
||||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures vzlogger 0.2 to adapt to many kinds of systems.
|
\`configure' configures vzlogger 0.3.3 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
|
@ -1311,7 +1329,7 @@ fi
|
||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of vzlogger 0.2:";;
|
short | recursive ) echo "Configuration of vzlogger 0.3.3:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
|
@ -1321,8 +1339,16 @@ Optional Features:
|
||||||
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||||
--disable-dependency-tracking speeds up one-time build
|
--disable-dependency-tracking speeds up one-time build
|
||||||
--enable-dependency-tracking do not reject slow dependency extractors
|
--enable-dependency-tracking do not reject slow dependency extractors
|
||||||
|
--enable-sml enable support for smart messaging language
|
||||||
|
(def=yes)
|
||||||
|
--enable-local enable support for local HTTPd (def=yes)
|
||||||
--enable-debug enable debug data generation (def=no)
|
--enable-debug enable debug data generation (def=no)
|
||||||
|
|
||||||
|
Optional Packages:
|
||||||
|
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||||
|
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
|
||||||
|
--with-reader compile reader to for testing your meters (def=yes)
|
||||||
|
|
||||||
Some influential environment variables:
|
Some influential environment variables:
|
||||||
CC C compiler command
|
CC C compiler command
|
||||||
CFLAGS C compiler flags
|
CFLAGS C compiler flags
|
||||||
|
@ -1336,14 +1362,24 @@ Some influential environment variables:
|
||||||
directories to add to pkg-config's search path
|
directories to add to pkg-config's search path
|
||||||
PKG_CONFIG_LIBDIR
|
PKG_CONFIG_LIBDIR
|
||||||
path overriding pkg-config's built-in search path
|
path overriding pkg-config's built-in search path
|
||||||
DEPS_CFLAGS C compiler flags for DEPS, overriding pkg-config
|
DEPS_VZ_CFLAGS
|
||||||
DEPS_LIBS linker flags for DEPS, overriding pkg-config
|
C compiler flags for DEPS_VZ, overriding pkg-config
|
||||||
|
DEPS_VZ_LIBS
|
||||||
|
linker flags for DEPS_VZ, overriding pkg-config
|
||||||
CPP C preprocessor
|
CPP C preprocessor
|
||||||
|
DEPS_SML_CFLAGS
|
||||||
|
C compiler flags for DEPS_SML, overriding pkg-config
|
||||||
|
DEPS_SML_LIBS
|
||||||
|
linker flags for DEPS_SML, overriding pkg-config
|
||||||
|
DEPS_LOCAL_CFLAGS
|
||||||
|
C compiler flags for DEPS_LOCAL, overriding pkg-config
|
||||||
|
DEPS_LOCAL_LIBS
|
||||||
|
linker flags for DEPS_LOCAL, overriding pkg-config
|
||||||
|
|
||||||
Use these variables to override the choices made by `configure' or to help
|
Use these variables to override the choices made by `configure' or to help
|
||||||
it to find libraries and programs with nonstandard names/locations.
|
it to find libraries and programs with nonstandard names/locations.
|
||||||
|
|
||||||
Report bugs to <info@steffenvogel.de>.
|
Report bugs to <http://bugs.volkszaehler.org>.
|
||||||
_ACEOF
|
_ACEOF
|
||||||
ac_status=$?
|
ac_status=$?
|
||||||
fi
|
fi
|
||||||
|
@ -1406,7 +1442,7 @@ fi
|
||||||
test -n "$ac_init_help" && exit $ac_status
|
test -n "$ac_init_help" && exit $ac_status
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
vzlogger configure 0.2
|
vzlogger configure 0.3.3
|
||||||
generated by GNU Autoconf 2.67
|
generated by GNU Autoconf 2.67
|
||||||
|
|
||||||
Copyright (C) 2010 Free Software Foundation, Inc.
|
Copyright (C) 2010 Free Software Foundation, Inc.
|
||||||
|
@ -1565,9 +1601,9 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
|
||||||
$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
|
$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
|
||||||
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
|
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
|
||||||
( $as_echo "## ----------------------------------- ##
|
( $as_echo "## ------------------------------------------- ##
|
||||||
## Report this to info@steffenvogel.de ##
|
## Report this to http://bugs.volkszaehler.org ##
|
||||||
## ----------------------------------- ##"
|
## ------------------------------------------- ##"
|
||||||
) | sed "s/^/$as_me: WARNING: /" >&2
|
) | sed "s/^/$as_me: WARNING: /" >&2
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
@ -1875,7 +1911,7 @@ cat >config.log <<_ACEOF
|
||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by vzlogger $as_me 0.2, which was
|
It was created by vzlogger $as_me 0.3.3, which was
|
||||||
generated by GNU Autoconf 2.67. Invocation command line was
|
generated by GNU Autoconf 2.67. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
|
@ -2690,7 +2726,7 @@ fi
|
||||||
|
|
||||||
# Define the identity of the package.
|
# Define the identity of the package.
|
||||||
PACKAGE=vzlogger
|
PACKAGE=vzlogger
|
||||||
VERSION=0.2
|
VERSION=0.3.3
|
||||||
|
|
||||||
|
|
||||||
cat >>confdefs.h <<_ACEOF
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
@ -2731,9 +2767,10 @@ am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ac_config_headers="$ac_config_headers config.h"
|
ac_config_headers="$ac_config_headers config.h"
|
||||||
|
|
||||||
ac_config_files="$ac_config_files Makefile src/Makefile docs/Makefile"
|
ac_config_files="$ac_config_files Makefile docs/Makefile src/Makefile"
|
||||||
|
|
||||||
|
|
||||||
# Checks for programs.
|
# Checks for programs.
|
||||||
|
@ -3717,6 +3754,228 @@ fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# We use per target compiler flags
|
||||||
|
if test "x$CC" != xcc; then
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
|
||||||
|
$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
|
||||||
|
$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
|
||||||
|
fi
|
||||||
|
set dummy $CC; ac_cc=`$as_echo "$2" |
|
||||||
|
sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
|
||||||
|
if eval "test \"\${ac_cv_prog_cc_${ac_cc}_c_o+set}\"" = set; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||||
|
/* end confdefs.h. */
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
|
||||||
|
;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_ACEOF
|
||||||
|
# Make sure it works both with $CC and with simple cc.
|
||||||
|
# We do the test twice because some compilers refuse to overwrite an
|
||||||
|
# existing .o file with -o, though they will create one.
|
||||||
|
ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
|
||||||
|
rm -f conftest2.*
|
||||||
|
if { { case "(($ac_try" in
|
||||||
|
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||||
|
*) ac_try_echo=$ac_try;;
|
||||||
|
esac
|
||||||
|
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
|
||||||
|
$as_echo "$ac_try_echo"; } >&5
|
||||||
|
(eval "$ac_try") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; } &&
|
||||||
|
test -f conftest2.$ac_objext && { { case "(($ac_try" in
|
||||||
|
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||||
|
*) ac_try_echo=$ac_try;;
|
||||||
|
esac
|
||||||
|
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
|
||||||
|
$as_echo "$ac_try_echo"; } >&5
|
||||||
|
(eval "$ac_try") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; };
|
||||||
|
then
|
||||||
|
eval ac_cv_prog_cc_${ac_cc}_c_o=yes
|
||||||
|
if test "x$CC" != xcc; then
|
||||||
|
# Test first that cc exists at all.
|
||||||
|
if { ac_try='cc -c conftest.$ac_ext >&5'
|
||||||
|
{ { case "(($ac_try" in
|
||||||
|
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||||
|
*) ac_try_echo=$ac_try;;
|
||||||
|
esac
|
||||||
|
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
|
||||||
|
$as_echo "$ac_try_echo"; } >&5
|
||||||
|
(eval "$ac_try") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; }; }; then
|
||||||
|
ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
|
||||||
|
rm -f conftest2.*
|
||||||
|
if { { case "(($ac_try" in
|
||||||
|
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||||
|
*) ac_try_echo=$ac_try;;
|
||||||
|
esac
|
||||||
|
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
|
||||||
|
$as_echo "$ac_try_echo"; } >&5
|
||||||
|
(eval "$ac_try") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; } &&
|
||||||
|
test -f conftest2.$ac_objext && { { case "(($ac_try" in
|
||||||
|
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||||
|
*) ac_try_echo=$ac_try;;
|
||||||
|
esac
|
||||||
|
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
|
||||||
|
$as_echo "$ac_try_echo"; } >&5
|
||||||
|
(eval "$ac_try") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; };
|
||||||
|
then
|
||||||
|
# cc works too.
|
||||||
|
:
|
||||||
|
else
|
||||||
|
# cc exists but doesn't like -o.
|
||||||
|
eval ac_cv_prog_cc_${ac_cc}_c_o=no
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
eval ac_cv_prog_cc_${ac_cc}_c_o=no
|
||||||
|
fi
|
||||||
|
rm -f core conftest*
|
||||||
|
|
||||||
|
fi
|
||||||
|
if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
|
$as_echo "yes" >&6; }
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
|
||||||
|
$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# FIXME: we rely on the cache variable name because
|
||||||
|
# there is no other way.
|
||||||
|
set dummy $CC
|
||||||
|
am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
|
||||||
|
eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
|
||||||
|
if test "$am_t" != yes; then
|
||||||
|
# Losing compiler, so override with the script.
|
||||||
|
# FIXME: It is wrong to rewrite CC.
|
||||||
|
# But if we don't then we get into trouble of one sort or another.
|
||||||
|
# A longer-term fix would be to have automake use am__CC in this case,
|
||||||
|
# and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
|
||||||
|
CC="$am_aux_dir/compile $CC"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Link libraries
|
||||||
|
if test -n "$ac_tool_prefix"; then
|
||||||
|
# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
|
||||||
|
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||||
|
$as_echo_n "checking for $ac_word... " >&6; }
|
||||||
|
if test "${ac_cv_prog_RANLIB+set}" = set; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
if test -n "$RANLIB"; then
|
||||||
|
ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
|
||||||
|
else
|
||||||
|
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||||
|
for as_dir in $PATH
|
||||||
|
do
|
||||||
|
IFS=$as_save_IFS
|
||||||
|
test -z "$as_dir" && as_dir=.
|
||||||
|
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||||
|
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
|
||||||
|
ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||||
|
break 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
IFS=$as_save_IFS
|
||||||
|
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
RANLIB=$ac_cv_prog_RANLIB
|
||||||
|
if test -n "$RANLIB"; then
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
|
||||||
|
$as_echo "$RANLIB" >&6; }
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
fi
|
||||||
|
if test -z "$ac_cv_prog_RANLIB"; then
|
||||||
|
ac_ct_RANLIB=$RANLIB
|
||||||
|
# Extract the first word of "ranlib", so it can be a program name with args.
|
||||||
|
set dummy ranlib; ac_word=$2
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||||
|
$as_echo_n "checking for $ac_word... " >&6; }
|
||||||
|
if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
if test -n "$ac_ct_RANLIB"; then
|
||||||
|
ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
|
||||||
|
else
|
||||||
|
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||||
|
for as_dir in $PATH
|
||||||
|
do
|
||||||
|
IFS=$as_save_IFS
|
||||||
|
test -z "$as_dir" && as_dir=.
|
||||||
|
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||||
|
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
|
||||||
|
ac_cv_prog_ac_ct_RANLIB="ranlib"
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||||
|
break 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
IFS=$as_save_IFS
|
||||||
|
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
|
||||||
|
if test -n "$ac_ct_RANLIB"; then
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
|
||||||
|
$as_echo "$ac_ct_RANLIB" >&6; }
|
||||||
|
else
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$ac_ct_RANLIB" = x; then
|
||||||
|
RANLIB=":"
|
||||||
|
else
|
||||||
|
case $cross_compiling:$ac_tool_warned in
|
||||||
|
yes:)
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
|
||||||
|
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
|
||||||
|
ac_tool_warned=yes ;;
|
||||||
|
esac
|
||||||
|
RANLIB=$ac_ct_RANLIB
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
RANLIB="$ac_cv_prog_RANLIB"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Checks for libraries.
|
# Checks for libraries.
|
||||||
|
|
||||||
|
|
||||||
|
@ -3839,35 +4098,35 @@ $as_echo "no" >&6; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
pkg_failed=no
|
pkg_failed=no
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEPS" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEPS_VZ" >&5
|
||||||
$as_echo_n "checking for DEPS... " >&6; }
|
$as_echo_n "checking for DEPS_VZ... " >&6; }
|
||||||
|
|
||||||
if test -n "$DEPS_CFLAGS"; then
|
if test -n "$DEPS_VZ_CFLAGS"; then
|
||||||
pkg_cv_DEPS_CFLAGS="$DEPS_CFLAGS"
|
pkg_cv_DEPS_VZ_CFLAGS="$DEPS_VZ_CFLAGS"
|
||||||
elif test -n "$PKG_CONFIG"; then
|
elif test -n "$PKG_CONFIG"; then
|
||||||
if test -n "$PKG_CONFIG" && \
|
if test -n "$PKG_CONFIG" && \
|
||||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"json >= 0.9 libcurl >= 7.21.0 libmicrohttpd >= 0.9.3\""; } >&5
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"json >= 0.9 libcurl >= 7.19\""; } >&5
|
||||||
($PKG_CONFIG --exists --print-errors "json >= 0.9 libcurl >= 7.21.0 libmicrohttpd >= 0.9.3") 2>&5
|
($PKG_CONFIG --exists --print-errors "json >= 0.9 libcurl >= 7.19") 2>&5
|
||||||
ac_status=$?
|
ac_status=$?
|
||||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
test $ac_status = 0; }; then
|
test $ac_status = 0; }; then
|
||||||
pkg_cv_DEPS_CFLAGS=`$PKG_CONFIG --cflags "json >= 0.9 libcurl >= 7.21.0 libmicrohttpd >= 0.9.3" 2>/dev/null`
|
pkg_cv_DEPS_VZ_CFLAGS=`$PKG_CONFIG --cflags "json >= 0.9 libcurl >= 7.19" 2>/dev/null`
|
||||||
else
|
else
|
||||||
pkg_failed=yes
|
pkg_failed=yes
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
pkg_failed=untried
|
pkg_failed=untried
|
||||||
fi
|
fi
|
||||||
if test -n "$DEPS_LIBS"; then
|
if test -n "$DEPS_VZ_LIBS"; then
|
||||||
pkg_cv_DEPS_LIBS="$DEPS_LIBS"
|
pkg_cv_DEPS_VZ_LIBS="$DEPS_VZ_LIBS"
|
||||||
elif test -n "$PKG_CONFIG"; then
|
elif test -n "$PKG_CONFIG"; then
|
||||||
if test -n "$PKG_CONFIG" && \
|
if test -n "$PKG_CONFIG" && \
|
||||||
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"json >= 0.9 libcurl >= 7.21.0 libmicrohttpd >= 0.9.3\""; } >&5
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"json >= 0.9 libcurl >= 7.19\""; } >&5
|
||||||
($PKG_CONFIG --exists --print-errors "json >= 0.9 libcurl >= 7.21.0 libmicrohttpd >= 0.9.3") 2>&5
|
($PKG_CONFIG --exists --print-errors "json >= 0.9 libcurl >= 7.19") 2>&5
|
||||||
ac_status=$?
|
ac_status=$?
|
||||||
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
test $ac_status = 0; }; then
|
test $ac_status = 0; }; then
|
||||||
pkg_cv_DEPS_LIBS=`$PKG_CONFIG --libs "json >= 0.9 libcurl >= 7.21.0 libmicrohttpd >= 0.9.3" 2>/dev/null`
|
pkg_cv_DEPS_VZ_LIBS=`$PKG_CONFIG --libs "json >= 0.9 libcurl >= 7.19" 2>/dev/null`
|
||||||
else
|
else
|
||||||
pkg_failed=yes
|
pkg_failed=yes
|
||||||
fi
|
fi
|
||||||
|
@ -3887,22 +4146,22 @@ else
|
||||||
_pkg_short_errors_supported=no
|
_pkg_short_errors_supported=no
|
||||||
fi
|
fi
|
||||||
if test $_pkg_short_errors_supported = yes; then
|
if test $_pkg_short_errors_supported = yes; then
|
||||||
DEPS_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "json >= 0.9 libcurl >= 7.21.0 libmicrohttpd >= 0.9.3" 2>&1`
|
DEPS_VZ_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "json >= 0.9 libcurl >= 7.19" 2>&1`
|
||||||
else
|
else
|
||||||
DEPS_PKG_ERRORS=`$PKG_CONFIG --print-errors "json >= 0.9 libcurl >= 7.21.0 libmicrohttpd >= 0.9.3" 2>&1`
|
DEPS_VZ_PKG_ERRORS=`$PKG_CONFIG --print-errors "json >= 0.9 libcurl >= 7.19" 2>&1`
|
||||||
fi
|
fi
|
||||||
# Put the nasty error message in config.log where it belongs
|
# Put the nasty error message in config.log where it belongs
|
||||||
echo "$DEPS_PKG_ERRORS" >&5
|
echo "$DEPS_VZ_PKG_ERRORS" >&5
|
||||||
|
|
||||||
as_fn_error $? "Package requirements (json >= 0.9 libcurl >= 7.21.0 libmicrohttpd >= 0.9.3) were not met:
|
as_fn_error $? "Package requirements (json >= 0.9 libcurl >= 7.19) were not met:
|
||||||
|
|
||||||
$DEPS_PKG_ERRORS
|
$DEPS_VZ_PKG_ERRORS
|
||||||
|
|
||||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||||
installed software in a non-standard prefix.
|
installed software in a non-standard prefix.
|
||||||
|
|
||||||
Alternatively, you may set the environment variables DEPS_CFLAGS
|
Alternatively, you may set the environment variables DEPS_VZ_CFLAGS
|
||||||
and DEPS_LIBS to avoid the need to call pkg-config.
|
and DEPS_VZ_LIBS to avoid the need to call pkg-config.
|
||||||
See the pkg-config man page for more details." "$LINENO" 5
|
See the pkg-config man page for more details." "$LINENO" 5
|
||||||
elif test $pkg_failed = untried; then
|
elif test $pkg_failed = untried; then
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
@ -3913,15 +4172,15 @@ as_fn_error $? "The pkg-config script could not be found or is too old. Make su
|
||||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||||
path to pkg-config.
|
path to pkg-config.
|
||||||
|
|
||||||
Alternatively, you may set the environment variables DEPS_CFLAGS
|
Alternatively, you may set the environment variables DEPS_VZ_CFLAGS
|
||||||
and DEPS_LIBS to avoid the need to call pkg-config.
|
and DEPS_VZ_LIBS to avoid the need to call pkg-config.
|
||||||
See the pkg-config man page for more details.
|
See the pkg-config man page for more details.
|
||||||
|
|
||||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.
|
To get pkg-config, see <http://pkg-config.freedesktop.org/>.
|
||||||
See \`config.log' for more details" "$LINENO" 5 ; }
|
See \`config.log' for more details" "$LINENO" 5 ; }
|
||||||
else
|
else
|
||||||
DEPS_CFLAGS=$pkg_cv_DEPS_CFLAGS
|
DEPS_VZ_CFLAGS=$pkg_cv_DEPS_VZ_CFLAGS
|
||||||
DEPS_LIBS=$pkg_cv_DEPS_LIBS
|
DEPS_VZ_LIBS=$pkg_cv_DEPS_VZ_LIBS
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
$as_echo "yes" >&6; }
|
$as_echo "yes" >&6; }
|
||||||
|
|
||||||
|
@ -4326,7 +4585,7 @@ fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
for ac_header in fcntl.h stddef.h stdint.h stdlib.h string.h sys/time.h termios.h unistd.h
|
for ac_header in fcntl.h stddef.h stdint.h stdlib.h string.h sys/time.h termios.h unistd.h getopt.h signal.h pthread.h
|
||||||
do :
|
do :
|
||||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
||||||
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
|
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
|
||||||
|
@ -4604,28 +4863,267 @@ fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
# debug compilation support
|
# SML support
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with debug information" >&5
|
# Check whether --enable-sml was given.
|
||||||
$as_echo_n "checking whether to build with debug information... " >&6; }
|
if test "${enable_sml+set}" = set; then :
|
||||||
# Check whether --enable-debug was given.
|
enableval=$enable_sml; sml=$enableval
|
||||||
if test "${enable_debug+set}" = set; then :
|
|
||||||
enableval=$enable_debug; debugit="$enableval"
|
|
||||||
else
|
else
|
||||||
debugit=no
|
sml=yes
|
||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $debugit" >&5
|
|
||||||
$as_echo "$debugit" >&6; }
|
|
||||||
|
|
||||||
if test x"$debugit" = x"yes"; then
|
if test x"$sml" = x"yes"; then
|
||||||
|
SML_SUPPORT_TRUE=
|
||||||
|
SML_SUPPORT_FALSE='#'
|
||||||
|
else
|
||||||
|
SML_SUPPORT_TRUE='#'
|
||||||
|
SML_SUPPORT_FALSE=
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x"$sml" = x"yes"; then
|
||||||
|
|
||||||
|
$as_echo "#define SML_SUPPORT /**/" >>confdefs.h
|
||||||
|
|
||||||
|
|
||||||
|
pkg_failed=no
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEPS_SML" >&5
|
||||||
|
$as_echo_n "checking for DEPS_SML... " >&6; }
|
||||||
|
|
||||||
|
if test -n "$DEPS_SML_CFLAGS"; then
|
||||||
|
pkg_cv_DEPS_SML_CFLAGS="$DEPS_SML_CFLAGS"
|
||||||
|
elif test -n "$PKG_CONFIG"; then
|
||||||
|
if test -n "$PKG_CONFIG" && \
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sml >= 0.1\""; } >&5
|
||||||
|
($PKG_CONFIG --exists --print-errors "sml >= 0.1") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; }; then
|
||||||
|
pkg_cv_DEPS_SML_CFLAGS=`$PKG_CONFIG --cflags "sml >= 0.1" 2>/dev/null`
|
||||||
|
else
|
||||||
|
pkg_failed=yes
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
pkg_failed=untried
|
||||||
|
fi
|
||||||
|
if test -n "$DEPS_SML_LIBS"; then
|
||||||
|
pkg_cv_DEPS_SML_LIBS="$DEPS_SML_LIBS"
|
||||||
|
elif test -n "$PKG_CONFIG"; then
|
||||||
|
if test -n "$PKG_CONFIG" && \
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"sml >= 0.1\""; } >&5
|
||||||
|
($PKG_CONFIG --exists --print-errors "sml >= 0.1") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; }; then
|
||||||
|
pkg_cv_DEPS_SML_LIBS=`$PKG_CONFIG --libs "sml >= 0.1" 2>/dev/null`
|
||||||
|
else
|
||||||
|
pkg_failed=yes
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
pkg_failed=untried
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if test $pkg_failed = yes; then
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
|
||||||
|
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||||
|
_pkg_short_errors_supported=yes
|
||||||
|
else
|
||||||
|
_pkg_short_errors_supported=no
|
||||||
|
fi
|
||||||
|
if test $_pkg_short_errors_supported = yes; then
|
||||||
|
DEPS_SML_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "sml >= 0.1" 2>&1`
|
||||||
|
else
|
||||||
|
DEPS_SML_PKG_ERRORS=`$PKG_CONFIG --print-errors "sml >= 0.1" 2>&1`
|
||||||
|
fi
|
||||||
|
# Put the nasty error message in config.log where it belongs
|
||||||
|
echo "$DEPS_SML_PKG_ERRORS" >&5
|
||||||
|
|
||||||
|
as_fn_error $? "Package requirements (sml >= 0.1) were not met:
|
||||||
|
|
||||||
|
$DEPS_SML_PKG_ERRORS
|
||||||
|
|
||||||
|
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||||
|
installed software in a non-standard prefix.
|
||||||
|
|
||||||
|
Alternatively, you may set the environment variables DEPS_SML_CFLAGS
|
||||||
|
and DEPS_SML_LIBS to avoid the need to call pkg-config.
|
||||||
|
See the pkg-config man page for more details." "$LINENO" 5
|
||||||
|
elif test $pkg_failed = untried; then
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||||
|
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||||
|
as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
|
||||||
|
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||||
|
path to pkg-config.
|
||||||
|
|
||||||
|
Alternatively, you may set the environment variables DEPS_SML_CFLAGS
|
||||||
|
and DEPS_SML_LIBS to avoid the need to call pkg-config.
|
||||||
|
See the pkg-config man page for more details.
|
||||||
|
|
||||||
|
To get pkg-config, see <http://pkg-config.freedesktop.org/>.
|
||||||
|
See \`config.log' for more details" "$LINENO" 5 ; }
|
||||||
|
else
|
||||||
|
DEPS_SML_CFLAGS=$pkg_cv_DEPS_SML_CFLAGS
|
||||||
|
DEPS_SML_LIBS=$pkg_cv_DEPS_SML_LIBS
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
|
$as_echo "yes" >&6; }
|
||||||
|
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# local interface support
|
||||||
|
# Check whether --enable-local was given.
|
||||||
|
if test "${enable_local+set}" = set; then :
|
||||||
|
enableval=$enable_local; local=$enableval
|
||||||
|
else
|
||||||
|
local=yes
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test x"$local" = x"yes"; then
|
||||||
|
LOCAL_SUPPORT_TRUE=
|
||||||
|
LOCAL_SUPPORT_FALSE='#'
|
||||||
|
else
|
||||||
|
LOCAL_SUPPORT_TRUE='#'
|
||||||
|
LOCAL_SUPPORT_FALSE=
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x"$local" = x"yes"; then
|
||||||
|
|
||||||
|
$as_echo "#define LOCAL_SUPPORT /**/" >>confdefs.h
|
||||||
|
|
||||||
|
|
||||||
|
pkg_failed=no
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEPS_LOCAL" >&5
|
||||||
|
$as_echo_n "checking for DEPS_LOCAL... " >&6; }
|
||||||
|
|
||||||
|
if test -n "$DEPS_LOCAL_CFLAGS"; then
|
||||||
|
pkg_cv_DEPS_LOCAL_CFLAGS="$DEPS_LOCAL_CFLAGS"
|
||||||
|
elif test -n "$PKG_CONFIG"; then
|
||||||
|
if test -n "$PKG_CONFIG" && \
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmicrohttpd >= 0.4.6\""; } >&5
|
||||||
|
($PKG_CONFIG --exists --print-errors "libmicrohttpd >= 0.4.6") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; }; then
|
||||||
|
pkg_cv_DEPS_LOCAL_CFLAGS=`$PKG_CONFIG --cflags "libmicrohttpd >= 0.4.6" 2>/dev/null`
|
||||||
|
else
|
||||||
|
pkg_failed=yes
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
pkg_failed=untried
|
||||||
|
fi
|
||||||
|
if test -n "$DEPS_LOCAL_LIBS"; then
|
||||||
|
pkg_cv_DEPS_LOCAL_LIBS="$DEPS_LOCAL_LIBS"
|
||||||
|
elif test -n "$PKG_CONFIG"; then
|
||||||
|
if test -n "$PKG_CONFIG" && \
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libmicrohttpd >= 0.4.6\""; } >&5
|
||||||
|
($PKG_CONFIG --exists --print-errors "libmicrohttpd >= 0.4.6") 2>&5
|
||||||
|
ac_status=$?
|
||||||
|
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
|
||||||
|
test $ac_status = 0; }; then
|
||||||
|
pkg_cv_DEPS_LOCAL_LIBS=`$PKG_CONFIG --libs "libmicrohttpd >= 0.4.6" 2>/dev/null`
|
||||||
|
else
|
||||||
|
pkg_failed=yes
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
pkg_failed=untried
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if test $pkg_failed = yes; then
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
|
||||||
|
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||||
|
_pkg_short_errors_supported=yes
|
||||||
|
else
|
||||||
|
_pkg_short_errors_supported=no
|
||||||
|
fi
|
||||||
|
if test $_pkg_short_errors_supported = yes; then
|
||||||
|
DEPS_LOCAL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "libmicrohttpd >= 0.4.6" 2>&1`
|
||||||
|
else
|
||||||
|
DEPS_LOCAL_PKG_ERRORS=`$PKG_CONFIG --print-errors "libmicrohttpd >= 0.4.6" 2>&1`
|
||||||
|
fi
|
||||||
|
# Put the nasty error message in config.log where it belongs
|
||||||
|
echo "$DEPS_LOCAL_PKG_ERRORS" >&5
|
||||||
|
|
||||||
|
as_fn_error $? "Package requirements (libmicrohttpd >= 0.4.6) were not met:
|
||||||
|
|
||||||
|
$DEPS_LOCAL_PKG_ERRORS
|
||||||
|
|
||||||
|
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||||
|
installed software in a non-standard prefix.
|
||||||
|
|
||||||
|
Alternatively, you may set the environment variables DEPS_LOCAL_CFLAGS
|
||||||
|
and DEPS_LOCAL_LIBS to avoid the need to call pkg-config.
|
||||||
|
See the pkg-config man page for more details." "$LINENO" 5
|
||||||
|
elif test $pkg_failed = untried; then
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||||
|
$as_echo "no" >&6; }
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||||
|
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||||
|
as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
|
||||||
|
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||||
|
path to pkg-config.
|
||||||
|
|
||||||
|
Alternatively, you may set the environment variables DEPS_LOCAL_CFLAGS
|
||||||
|
and DEPS_LOCAL_LIBS to avoid the need to call pkg-config.
|
||||||
|
See the pkg-config man page for more details.
|
||||||
|
|
||||||
|
To get pkg-config, see <http://pkg-config.freedesktop.org/>.
|
||||||
|
See \`config.log' for more details" "$LINENO" 5 ; }
|
||||||
|
else
|
||||||
|
DEPS_LOCAL_CFLAGS=$pkg_cv_DEPS_LOCAL_CFLAGS
|
||||||
|
DEPS_LOCAL_LIBS=$pkg_cv_DEPS_LOCAL_LIBS
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||||
|
$as_echo "yes" >&6; }
|
||||||
|
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# build reader binary
|
||||||
|
|
||||||
|
# Check whether --with-reader was given.
|
||||||
|
if test "${with_reader+set}" = set; then :
|
||||||
|
withval=$with_reader; reader=$withval
|
||||||
|
reader=yes
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test x"$reader" = x"yes"; then
|
||||||
|
READER_BUILD_TRUE=
|
||||||
|
READER_BUILD_FALSE='#'
|
||||||
|
else
|
||||||
|
READER_BUILD_TRUE='#'
|
||||||
|
READER_BUILD_FALSE=
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# debug compilation support
|
||||||
|
# Check whether --enable-debug was given.
|
||||||
|
if test "${enable_debug+set}" = set; then :
|
||||||
|
enableval=$enable_debug; debug=$enableval
|
||||||
|
else
|
||||||
|
debug=no
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if test x"$debug" = x"yes"; then
|
||||||
|
|
||||||
$as_echo "#define DEBUG /**/" >>confdefs.h
|
$as_echo "#define DEBUG /**/" >>confdefs.h
|
||||||
|
|
||||||
AM_CXXFLAGS="$AM_CXXFLAGS -g -Wall -Werror -Wno-uninitialized -O0"
|
AM_CXXFLAGS="$AM_CXXFLAGS -g -Wall -Werror -Wno-uninitialized -O0"
|
||||||
else
|
else
|
||||||
|
|
||||||
$as_echo "#define NDEBUG /**/" >>confdefs.h
|
|
||||||
|
|
||||||
AM_CXXFLAGS="$AM_CXXFLAGS -O3"
|
AM_CXXFLAGS="$AM_CXXFLAGS -O3"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -4743,6 +5241,18 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
|
||||||
as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
|
as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
|
||||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||||
fi
|
fi
|
||||||
|
if test -z "${SML_SUPPORT_TRUE}" && test -z "${SML_SUPPORT_FALSE}"; then
|
||||||
|
as_fn_error $? "conditional \"SML_SUPPORT\" was never defined.
|
||||||
|
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||||
|
fi
|
||||||
|
if test -z "${LOCAL_SUPPORT_TRUE}" && test -z "${LOCAL_SUPPORT_FALSE}"; then
|
||||||
|
as_fn_error $? "conditional \"LOCAL_SUPPORT\" was never defined.
|
||||||
|
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||||
|
fi
|
||||||
|
if test -z "${READER_BUILD_TRUE}" && test -z "${READER_BUILD_FALSE}"; then
|
||||||
|
as_fn_error $? "conditional \"READER_BUILD\" was never defined.
|
||||||
|
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||||
|
fi
|
||||||
|
|
||||||
: ${CONFIG_STATUS=./config.status}
|
: ${CONFIG_STATUS=./config.status}
|
||||||
ac_write_fail=0
|
ac_write_fail=0
|
||||||
|
@ -5151,7 +5661,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
ac_log="
|
||||||
This file was extended by vzlogger $as_me 0.2, which was
|
This file was extended by vzlogger $as_me 0.3.3, which was
|
||||||
generated by GNU Autoconf 2.67. Invocation command line was
|
generated by GNU Autoconf 2.67. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
|
@ -5211,13 +5721,13 @@ $config_headers
|
||||||
Configuration commands:
|
Configuration commands:
|
||||||
$config_commands
|
$config_commands
|
||||||
|
|
||||||
Report bugs to <info@steffenvogel.de>."
|
Report bugs to <http://bugs.volkszaehler.org>."
|
||||||
|
|
||||||
_ACEOF
|
_ACEOF
|
||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
vzlogger config.status 0.2
|
vzlogger config.status 0.3.3
|
||||||
configured by $0, generated by GNU Autoconf 2.67,
|
configured by $0, generated by GNU Autoconf 2.67,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
|
@ -5348,8 +5858,8 @@ do
|
||||||
case $ac_config_target in
|
case $ac_config_target in
|
||||||
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
|
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
|
||||||
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
|
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
|
||||||
"src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
|
|
||||||
"docs/Makefile") CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;;
|
"docs/Makefile") CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;;
|
||||||
|
"src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
|
||||||
"depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
|
"depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
|
||||||
|
|
||||||
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
|
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
|
96
configure.ac
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
# -*- Autoconf -*-
|
||||||
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
|
AC_PREREQ([2.67])
|
||||||
|
|
||||||
|
# update version here!
|
||||||
|
AC_INIT([vzlogger], [0.3.3], [http://bugs.volkszaehler.org])
|
||||||
|
AM_INIT_AUTOMAKE([vzlogger], [0.3.3])
|
||||||
|
|
||||||
|
AC_CONFIG_SRCDIR([src/meter.c])
|
||||||
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
AC_CONFIG_FILES([
|
||||||
|
Makefile
|
||||||
|
docs/Makefile
|
||||||
|
src/Makefile
|
||||||
|
])
|
||||||
|
|
||||||
|
# Checks for programs.
|
||||||
|
AC_PROG_CC
|
||||||
|
|
||||||
|
# We use per target compiler flags
|
||||||
|
AM_PROG_CC_C_O
|
||||||
|
|
||||||
|
# Link libraries
|
||||||
|
AC_PROG_RANLIB
|
||||||
|
|
||||||
|
# Checks for libraries.
|
||||||
|
PKG_CHECK_MODULES([DEPS_VZ], [json >= 0.9 libcurl >= 7.19])
|
||||||
|
|
||||||
|
# Checks for header files.
|
||||||
|
AC_CHECK_HEADERS([fcntl.h stddef.h stdint.h stdlib.h string.h sys/time.h termios.h unistd.h getopt.h signal.h pthread.h])
|
||||||
|
|
||||||
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_TYPE_MODE_T
|
||||||
|
AC_TYPE_SIZE_T
|
||||||
|
|
||||||
|
# Checks for library functions.
|
||||||
|
AC_FUNC_MALLOC
|
||||||
|
AC_FUNC_REALLOC
|
||||||
|
AC_FUNC_STRERROR_R
|
||||||
|
AC_CHECK_FUNCS([gettimeofday memset sqrt strchr strtol])
|
||||||
|
|
||||||
|
# SML support
|
||||||
|
AC_ARG_ENABLE(
|
||||||
|
[sml],
|
||||||
|
[AS_HELP_STRING([--enable-sml], [enable support for smart messaging language (def=yes)])],
|
||||||
|
[sml=$enableval],
|
||||||
|
[sml=yes]
|
||||||
|
)
|
||||||
|
|
||||||
|
AM_CONDITIONAL([SML_SUPPORT], [test x"$sml" = x"yes"])
|
||||||
|
if test x"$sml" = x"yes"; then
|
||||||
|
AC_DEFINE([SML_SUPPORT], [], [Smart Messaging Language])
|
||||||
|
PKG_CHECK_MODULES([DEPS_SML], [sml >= 0.1])
|
||||||
|
fi
|
||||||
|
|
||||||
|
# local interface support
|
||||||
|
AC_ARG_ENABLE(
|
||||||
|
[local],
|
||||||
|
[AS_HELP_STRING([--enable-local], [enable support for local HTTPd (def=yes)])],
|
||||||
|
[local=$enableval],
|
||||||
|
[local=yes]
|
||||||
|
)
|
||||||
|
|
||||||
|
AM_CONDITIONAL([LOCAL_SUPPORT], [test x"$local" = x"yes"])
|
||||||
|
if test x"$local" = x"yes"; then
|
||||||
|
AC_DEFINE([LOCAL_SUPPORT], [], [Local interface])
|
||||||
|
PKG_CHECK_MODULES([DEPS_LOCAL], [libmicrohttpd >= 0.4.6])
|
||||||
|
fi
|
||||||
|
|
||||||
|
# build reader binary
|
||||||
|
AC_ARG_WITH(
|
||||||
|
[reader],
|
||||||
|
[AS_HELP_STRING([--with-reader], [compile reader to for testing your meters (def=yes)])],
|
||||||
|
[reader=$withval]
|
||||||
|
[reader=yes]
|
||||||
|
)
|
||||||
|
|
||||||
|
AM_CONDITIONAL([READER_BUILD], [test x"$reader" = x"yes"])
|
||||||
|
|
||||||
|
# debug compilation support
|
||||||
|
AC_ARG_ENABLE(
|
||||||
|
[debug],
|
||||||
|
[AS_HELP_STRING([--enable-debug], [enable debug data generation (def=no)])],
|
||||||
|
[debug=$enableval],
|
||||||
|
[debug=no]
|
||||||
|
)
|
||||||
|
|
||||||
|
if test x"$debug" = x"yes"; then
|
||||||
|
AC_DEFINE([DEBUG], [], [Debug Mode])
|
||||||
|
AM_CXXFLAGS="$AM_CXXFLAGS -g -Wall -Werror -Wno-uninitialized -O0"
|
||||||
|
else
|
||||||
|
AM_CXXFLAGS="$AM_CXXFLAGS -O3"
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_OUTPUT
|
54
debian/changelog
vendored
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
vzlogger (0.3.3-1) stable; urgency=low
|
||||||
|
|
||||||
|
* added support for new fluksometer
|
||||||
|
* some code refactoring & cleanup
|
||||||
|
|
||||||
|
-- Steffen Vogel <info@steffenvogel.de> Thu, 19 Jan 2012 18:52:32 +0100
|
||||||
|
|
||||||
|
vzlogger (0.3.2-1) stable; urgency=low
|
||||||
|
|
||||||
|
* new release with improvments to various protocols and configuration parsing
|
||||||
|
* do not run with root privileges anymore
|
||||||
|
|
||||||
|
-- Steffen Vogel <info@steffenvogel.de> Tue, 06 Dec 2011 02:37:26 +0100
|
||||||
|
|
||||||
|
vzlogger (0.3.1-2) stable; urgency=low
|
||||||
|
|
||||||
|
* updated version number
|
||||||
|
* fixed forking behavior of init script
|
||||||
|
|
||||||
|
-- Steffen Vogel <info@steffenvogel.de> Sun, 16 Oct 2011 14:45:32 +0200
|
||||||
|
|
||||||
|
vzlogger (0.3.1-1) stable; urgency=low
|
||||||
|
|
||||||
|
* fixed bug in parsing configuration for sml meters
|
||||||
|
|
||||||
|
-- Steffen Vogel <info@steffenvogel.de> Sun, 16 Oct 2011 14:31:26 +0200
|
||||||
|
|
||||||
|
vzlogger (0.3-2) stable; urgency=low
|
||||||
|
|
||||||
|
* fixed typo in description
|
||||||
|
* fixed static linking of libsml
|
||||||
|
* added dependency for libsml
|
||||||
|
|
||||||
|
-- Steffen Vogel <info@steffenvogel.de> Sun, 16 Oct 2011 00:25:27 +0200
|
||||||
|
|
||||||
|
vzlogger (0.3-1) stable; urgency=high
|
||||||
|
|
||||||
|
* Rewrite of meter & channel mapping
|
||||||
|
* Added SML support
|
||||||
|
|
||||||
|
-- Steffen Vogel <info@steffenvogel.de> Thu, 15 Sep 2011 23:26:31 +0200
|
||||||
|
|
||||||
|
vzlogger (0.2-1) stable; urgency=low
|
||||||
|
|
||||||
|
* Fixed some bugs after porting to armel architecture
|
||||||
|
* Improved init script
|
||||||
|
|
||||||
|
-- Steffen Vogel <info@steffenvogel.de> Thu, 04 Aug 2011 20:00:25 +0200
|
||||||
|
|
||||||
|
vzlogger (0.2) unstable; urgency=low
|
||||||
|
|
||||||
|
* Initial Release.
|
||||||
|
|
||||||
|
-- Steffen Vogel <info@steffenvogel.de> Thu, 09 Jun 2011 16:04:25 +0200
|
23
debian/control
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
Source: vzlogger
|
||||||
|
Section: net
|
||||||
|
Priority: optional
|
||||||
|
Maintainer: Steffen Vogel <info@steffenvogel.de>
|
||||||
|
Build-Depends: debhelper (>= 7.0.50~), pkg-config (>= 0.25), libjson0-dev (>= 0.9), libcurl4-openssl-dev (>= 7.19), libmicrohttpd-dev (>= 0.4.6)
|
||||||
|
Standards-Version: 3.9.1
|
||||||
|
Homepage: http://wiki.volkszaehler.org/software/controller/vzlogger
|
||||||
|
Vcs-Git: git://github.com/volkszaehler/volkszaehler.org.git
|
||||||
|
Vcs-Browser: http://github.com/volkszaehler/volkszaehler.org/tree/master/misc/controller/vzlogger/
|
||||||
|
|
||||||
|
Package: vzlogger
|
||||||
|
Architecture: any
|
||||||
|
Depends: ${shlibs:Depends}, ${misc:Depends}, adduser
|
||||||
|
Description: program for logging measurements to an volkszaehler.org middleware
|
||||||
|
vzlogger...
|
||||||
|
* is a tool to read and log measurements of a wide variety of smartmeters and
|
||||||
|
sensors to the volkszaehler.org middleware.
|
||||||
|
* can run as a daemon or via Cron.
|
||||||
|
* includes a tiny onboard httpd to serve
|
||||||
|
realtime readings to the AJAX web frontend.
|
||||||
|
* is written in ANSI C and should run on most embedded devices
|
||||||
|
which conform to the POSIX standard.
|
||||||
|
|
|
@ -12,12 +12,14 @@
|
||||||
|
|
||||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||||
DESC=vzlogger # Introduce a short description here
|
DESC="smartmetering server"
|
||||||
NAME=vzlogger # Introduce the short server's name here
|
NAME=vzlogger
|
||||||
DAEMON=/usr/sbin/vzlogger # Introduce the server's location here
|
DAEMON=/usr/bin/vzlogger
|
||||||
DAEMON_ARGS="" # Arguments to run the daemon with
|
DAEMON_ARGS="-d" # Arguments to run the daemon with
|
||||||
PIDFILE=/var/run/$NAME.pid
|
PIDFILE=/var/run/$NAME.pid
|
||||||
SCRIPTNAME=/etc/init.d/$NAME
|
SCRIPTNAME=/etc/init.d/$NAME
|
||||||
|
USER=vzlogger
|
||||||
|
GROUP=vzlogger
|
||||||
|
|
||||||
# Exit if the package is not installed
|
# Exit if the package is not installed
|
||||||
[ -x $DAEMON ] || exit 0
|
[ -x $DAEMON ] || exit 0
|
||||||
|
@ -41,9 +43,9 @@ do_start()
|
||||||
# 0 if daemon has been started
|
# 0 if daemon has been started
|
||||||
# 1 if daemon was already running
|
# 1 if daemon was already running
|
||||||
# 2 if daemon could not be started
|
# 2 if daemon could not be started
|
||||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|
start-stop-daemon --start --chuid $USER --group $GROUP --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|
||||||
|| return 1
|
|| return 1
|
||||||
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
|
start-stop-daemon --start --chuid $USER --group $GROUP --quiet --pidfile $PIDFILE --exec $DAEMON -- \
|
||||||
$DAEMON_ARGS \
|
$DAEMON_ARGS \
|
||||||
|| return 2
|
|| return 2
|
||||||
# Add code here, if necessary, that waits for the process to be ready
|
# Add code here, if necessary, that waits for the process to be ready
|
26
debian/vzlogger.postinst
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
configure)
|
||||||
|
if ! id vzlogger > /dev/null 2>&1 ; then
|
||||||
|
adduser --system --home /usr/share/vzlogger --no-create-home \
|
||||||
|
--group --disabled-password --shell /bin/false \
|
||||||
|
vzlogger
|
||||||
|
usermod -a -G dialout vzlogger
|
||||||
|
fi
|
||||||
|
|
||||||
|
touch /var/log/vzlogger.log
|
||||||
|
chown vzlogger:adm /var/log/vzlogger.log
|
||||||
|
chown vzlogger:adm /etc/vzlogger.conf
|
||||||
|
;;
|
||||||
|
|
||||||
|
abort-upgrade|abort-remove|abort-deconfigure)
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "$0 called with unknown argument \`$1'" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
#DEBHELPER#
|
|
@ -83,8 +83,12 @@ CPPFLAGS = @CPPFLAGS@
|
||||||
CYGPATH_W = @CYGPATH_W@
|
CYGPATH_W = @CYGPATH_W@
|
||||||
DEFS = @DEFS@
|
DEFS = @DEFS@
|
||||||
DEPDIR = @DEPDIR@
|
DEPDIR = @DEPDIR@
|
||||||
DEPS_CFLAGS = @DEPS_CFLAGS@
|
DEPS_LOCAL_CFLAGS = @DEPS_LOCAL_CFLAGS@
|
||||||
DEPS_LIBS = @DEPS_LIBS@
|
DEPS_LOCAL_LIBS = @DEPS_LOCAL_LIBS@
|
||||||
|
DEPS_SML_CFLAGS = @DEPS_SML_CFLAGS@
|
||||||
|
DEPS_SML_LIBS = @DEPS_SML_LIBS@
|
||||||
|
DEPS_VZ_CFLAGS = @DEPS_VZ_CFLAGS@
|
||||||
|
DEPS_VZ_LIBS = @DEPS_VZ_LIBS@
|
||||||
ECHO_C = @ECHO_C@
|
ECHO_C = @ECHO_C@
|
||||||
ECHO_N = @ECHO_N@
|
ECHO_N = @ECHO_N@
|
||||||
ECHO_T = @ECHO_T@
|
ECHO_T = @ECHO_T@
|
||||||
|
@ -114,6 +118,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||||
PKG_CONFIG = @PKG_CONFIG@
|
PKG_CONFIG = @PKG_CONFIG@
|
||||||
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
|
||||||
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
SET_MAKE = @SET_MAKE@
|
SET_MAKE = @SET_MAKE@
|
||||||
SHELL = @SHELL@
|
SHELL = @SHELL@
|
||||||
STRIP = @STRIP@
|
STRIP = @STRIP@
|
|
@ -1,110 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Configuration template
|
|
||||||
*
|
|
||||||
* You should use this file to obtain your custom configuration
|
|
||||||
* new parameters should be documented
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2011, The volkszaehler.org project
|
|
||||||
* @author Steffen Vogel <info@steffenvogel.de>
|
|
||||||
* @package default
|
|
||||||
* @license http://www.opensource.org/licenses/gpl-license.php GNU Public License
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* This file is part of volkzaehler.org
|
|
||||||
*
|
|
||||||
* volkzaehler.org is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* volkzaehler.org is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string PDO driver for Doctrine DBAL
|
|
||||||
* @link http://www.doctrine-project.org/projects/dbal/2.0/docs/reference/configuration/en#getting-a-connection:driver
|
|
||||||
*/
|
|
||||||
$config['db']['driver'] = 'pdo_mysql';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string hostname of database server. Use 'localhost' for the machine your webserver is running on.
|
|
||||||
* @link http://www.doctrine-project.org/projects/dbal/2.0/docs/reference/configuration/en
|
|
||||||
*/
|
|
||||||
$config['db']['host'] = 'localhost';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string username for the database server
|
|
||||||
* @link http://www.doctrine-project.org/projects/dbal/2.0/docs/reference/configuration/en
|
|
||||||
*/
|
|
||||||
$config['db']['user'] = 'vz';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string password for the database server
|
|
||||||
* @link http://www.doctrine-project.org/projects/dbal/2.0/docs/reference/configuration/en
|
|
||||||
*/
|
|
||||||
$config['db']['password'] = 'demo';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string database name
|
|
||||||
* @link http://www.doctrine-project.org/projects/dbal/2.0/docs/reference/configuration/en
|
|
||||||
*/
|
|
||||||
$config['db']['dbname'] = 'volkszaehler';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For administration tasks (used by doctrine cli and the setup script)
|
|
||||||
* the following $['db']['admin'] settings will be merged with $config['db']
|
|
||||||
*/
|
|
||||||
//$config['db']['admin']['user'] = 'vz_admin';
|
|
||||||
//$config['db']['admin']['password'] = 'admin_demo';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string path of the sqlite database
|
|
||||||
* @link http://www.doctrine-project.org/projects/dbal/2.0/docs/reference/configuration/en
|
|
||||||
*/
|
|
||||||
//$config['db']['path'] = 'volkszaehler';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vendor libs
|
|
||||||
* Set to NULL to use PHP's include path
|
|
||||||
* @var string path to vendor libs
|
|
||||||
* @link http://www.php.net/manual/en/ini.core.php#ini.include-path
|
|
||||||
*/
|
|
||||||
$config['lib']['doctrine'] = VZ_DIR . '/lib/vendor/Doctrine';
|
|
||||||
//$config['lib']['jpgraph'] = VZ_DIR . '/lib/vendor/JpGraph';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string timezone for the middleware
|
|
||||||
* @link http://www.php.net/manual/de/timezones.php
|
|
||||||
* @link http://www.php.net/manual/de/datetime.configuration.php#ini.date.timezone
|
|
||||||
*/
|
|
||||||
//$config['timezone'] = 'Europe/Berlin';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var string Locale used for regular expressions
|
|
||||||
* @link http://php.net/manual/de/function.setlocale.php
|
|
||||||
*/
|
|
||||||
$config['locale'] = array('de_DE', 'en_US', 'C');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array of colors for plot series
|
|
||||||
*/
|
|
||||||
$config['colors'] = array('#83CAFF', '#7E0021', '#579D1C', '#FFD320', '#FF420E', '#004586', '#0084D1', '#C5000B', '#FF950E', '#4B1F6F', '#AECF00', '#314004');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var boolean disables some optimizations. Only use it when you exactly know what you are doing.
|
|
||||||
*/
|
|
||||||
$config['devmode'] = FALSE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var integer set to > 0 to show debugging messages
|
|
||||||
*/
|
|
||||||
$config['debug'] = 0;
|
|
||||||
|
|
||||||
?>
|
|
78
etc/vzlogger.conf
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
* vzlogger configuration
|
||||||
|
*
|
||||||
|
* use proper encoded JSON with javascript comments
|
||||||
|
*
|
||||||
|
* take a look at the wiki for detailed information:
|
||||||
|
* http://wiki.volkszaehler.org/software/controller/vzlogger#configuration
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
"retry" : 30, /* how long to sleep between failed requests, in seconds */
|
||||||
|
//"daemon": false, /* run periodically */
|
||||||
|
//"foreground" : true, /* dont run in background (prevents forking) */
|
||||||
|
//"verbosity" : 5, /* between 0 and 15 */
|
||||||
|
//"log" : "/var/log/vzlogger.log",/* path to logfile, optional */
|
||||||
|
|
||||||
|
"local" : {
|
||||||
|
// "enabled" : false, /* should we start the local HTTPd for serving live readings? */
|
||||||
|
"port" : 8080, /* the TCP port for the local HTTPd */
|
||||||
|
"index" : true, /* should we provide a index listing of available channels if no UUID was requested? */
|
||||||
|
"timeout" : 30, /* timeout for long polling comet requests, 0 disables comet, in seconds */
|
||||||
|
"buffer" : 600 /* how long to buffer readings for the local interface, in seconds */
|
||||||
|
},
|
||||||
|
|
||||||
|
"meters" : [{
|
||||||
|
"enabled" : false, /* disabled meters will be ignored */
|
||||||
|
"protocol" : "sml", /* see 'vzlogger -h' for list of available protocols */
|
||||||
|
"host" : "meinzaehler.dyndns.info:7331",
|
||||||
|
"channels": [{
|
||||||
|
"uuid" : "fde8f1d0-c5d0-11e0-856e-f9e4360ced10",
|
||||||
|
"middleware" : "http://localhost/volkszaehler/middleware.php",
|
||||||
|
"identifier" : "power" /* alias for '1-0:1.7.ff', see 'vzlogger -h' for list of available aliases */
|
||||||
|
}, {
|
||||||
|
"uuid" : "a8da012a-9eb4-49ed-b7f3-38c95142a90c",
|
||||||
|
"middleware" : "http://localhost/volkszaehler/middleware.php",
|
||||||
|
"identifier" : "counter",
|
||||||
|
}, {
|
||||||
|
"uuid" : "d5c6db0f-533e-498d-a85a-be972c104b48",
|
||||||
|
"middleware" : "http://localhost/volkszaehler/middleware.php",
|
||||||
|
"identifier" : "1-0:1.8.0" /* see 'vzlogger -v20' for an output with all available identifiers/OBIS ids */
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"protocol" : "random",
|
||||||
|
"interval" : 2,
|
||||||
|
"max" : 40.0, /* has to be double! */
|
||||||
|
"min" : -5.0, /* has to be double! */
|
||||||
|
"channel" : {
|
||||||
|
"uuid" : "bac2e840-f72c-11e0-bedf-3f850c1e5a66",
|
||||||
|
"middleware" : "http://demo.volkszaehler.org/middleware.php"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"protocol" : "s0",
|
||||||
|
"device" : "/dev/ttyUSB0",
|
||||||
|
"channel" : {
|
||||||
|
"uuid" : "d495a390-f747-11e0-b3ca-f7890e45c7b2",
|
||||||
|
"middleware" : "http://demo.volkszaehler.org/middleware.php"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"protocol" : "file",
|
||||||
|
"path" : "/proc/loadavg",
|
||||||
|
// "format" : "$i $v $t", /* a format string for parsing complex logfiles */
|
||||||
|
/* arbitrary text and whitespaces are allowed, see 'scanf()' */
|
||||||
|
/* at least $v has to be used */
|
||||||
|
/* $i => identifier, $v => value, $t => timestamp */
|
||||||
|
"rewind" : true, /* reset file pointer each interval to the beginning of the file */
|
||||||
|
"interval" : 2 /* of ommitted, we will try to listen on changes with inotify */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"protocol" : "fluksov2",
|
||||||
|
"fifo" : "/var/spid/delta/out",
|
||||||
|
"channel" : {
|
||||||
|
"uuid" : "3b4da450-42a8-11e1-8b8d-c526d853edec",
|
||||||
|
"middleware" : "http://demo.volkszaehler.org/middleware.php",
|
||||||
|
"identifier" : "sensor0/power" /* or "sensor2/consumption" e.g. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]}
|
|
@ -1,6 +0,0 @@
|
||||||
Allow from all
|
|
||||||
|
|
||||||
<IfModule mod_rewrite.c>
|
|
||||||
RewriteEngine On
|
|
||||||
RewriteRule ^middleware/(.*) middleware.php/$1 [L]
|
|
||||||
</IfModule>
|
|
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 733 B |
Before Width: | Height: | Size: 685 B |
Before Width: | Height: | Size: 349 B |
Before Width: | Height: | Size: 526 B |
Before Width: | Height: | Size: 737 B |
Before Width: | Height: | Size: 736 B |
Before Width: | Height: | Size: 745 B |
Before Width: | Height: | Size: 720 B |
Before Width: | Height: | Size: 655 B |
Before Width: | Height: | Size: 715 B |
Before Width: | Height: | Size: 894 B |
Before Width: | Height: | Size: 915 B |
Before Width: | Height: | Size: 750 B |
Before Width: | Height: | Size: 516 B |
Before Width: | Height: | Size: 778 B |
Before Width: | Height: | Size: 343 B |
Before Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 620 B |
Before Width: | Height: | Size: 530 B |
Before Width: | Height: | Size: 225 B |
Before Width: | Height: | Size: 670 B |
Before Width: | Height: | Size: 566 B |
Before Width: | Height: | Size: 537 B |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 634 B |
Before Width: | Height: | Size: 882 B |
Before Width: | Height: | Size: 581 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 537 B |
Before Width: | Height: | Size: 806 B |
Before Width: | Height: | Size: 579 B |
Before Width: | Height: | Size: 242 B |
Before Width: | Height: | Size: 626 B |
Before Width: | Height: | Size: 623 B |
Before Width: | Height: | Size: 262 B |
Before Width: | Height: | Size: 741 B |
Before Width: | Height: | Size: 555 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 610 B |
Before Width: | Height: | Size: 488 B |
Before Width: | Height: | Size: 692 B |
Before Width: | Height: | Size: 729 B |
Before Width: | Height: | Size: 742 B |
|
@ -1,168 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>volkszaehler.org - web frontend</title>
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
||||||
|
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="../favicon.ico">
|
|
||||||
<link rel="apple-touch-icon" href="../favicon.ico">
|
|
||||||
|
|
||||||
<!-- jQuery -->
|
|
||||||
<script type="text/javascript" src="javascripts/jquery/jquery-1.5.1.js"></script>
|
|
||||||
<script type="text/javascript" src="javascripts/jquery/jquery-ui-1.8.10.min.js"></script>
|
|
||||||
<script type="text/javascript" src="javascripts/jquery/jquery-treeTable.js"></script>
|
|
||||||
<script type="text/javascript" src="javascripts/jquery/jquery-extensions.js"></script>
|
|
||||||
|
|
||||||
<!--[if IE]><script language="javascript" type="text/javascript" src="javascripts/flot/excanvas.min.js"></script><![endif]-->
|
|
||||||
<script type="text/javascript" src="javascripts/flot/jquery.flot.js"></script>
|
|
||||||
<script type="text/javascript" src="javascripts/flot/jquery.flot.crosshair.js"></script>
|
|
||||||
<script type="text/javascript" src="javascripts/flot/jquery.flot.selection.js"></script>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="javascripts/helper.js"></script>
|
|
||||||
<script type="text/javascript" src="javascripts/init.js"></script>
|
|
||||||
<script type="text/javascript" src="javascripts/options.js"></script>
|
|
||||||
<script type="text/javascript" src="javascripts/functions.js"></script>
|
|
||||||
<script type="text/javascript" src="javascripts/entities.js"></script>
|
|
||||||
<script type="text/javascript" src="javascripts/wui.js"></script>
|
|
||||||
<script type="text/javascript" src="javascripts/entity.js"></script>
|
|
||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="stylesheets/ui-lightness/jquery-ui-1.8.10.css" />
|
|
||||||
<link rel="stylesheet" type="text/css" href="stylesheets/jquery.treeTable.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="stylesheets/jquery.ui.custom.css">
|
|
||||||
<link rel="stylesheet" type="text/css" href="stylesheets/style.css">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="header"></div>
|
|
||||||
<div id="content">
|
|
||||||
<div id="headline">
|
|
||||||
<h2 id="title"></h2>
|
|
||||||
|
|
||||||
<div id="export">
|
|
||||||
<img alt="export" src="images/export.png" />
|
|
||||||
<select class="icons">
|
|
||||||
<option value="default" style="background-image: url(images/export.png)" selected="selected">Export...</option>
|
|
||||||
<option value="permalink" style="background-image: url(images/link.png)" >Permalink</option>
|
|
||||||
<option value="png" style="background-image: url(images/image.png)" disabled="disabled" >Snapshot</option>
|
|
||||||
<option value="csv" style="background-image: url(images/table.png)" >CSV</option>
|
|
||||||
<option value="xml" style="background-image: url(images/xml.png)" >XML</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<br style="clear: both" />
|
|
||||||
</div>
|
|
||||||
<div id="plot">
|
|
||||||
<div id="flot"></div>
|
|
||||||
<div id="overlay"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="accordion">
|
|
||||||
<div id="controls">
|
|
||||||
<button value="move-back" title="scroll backward"><img src="images/control_rewind_blue.png"/></button>
|
|
||||||
<button value="move-forward" title="scroll forward"><img src="images/control_fastforward_blue.png"/></button>
|
|
||||||
<button value="move-last" title="scroll to presence">Jetzt <img src="images/control_end_blue.png"/></button>
|
|
||||||
<button value="zoom-in" title="zoom in"><img src="images/zoom_in.png"/></button>
|
|
||||||
<button value="zoom-out" title="zoom out"><img src="images/zoom_out.png"/></button>
|
|
||||||
<button value="zoom-hour">Stunde</button>
|
|
||||||
<button value="zoom-day">Tag</button>
|
|
||||||
<button value="zoom-week">Woche</button>
|
|
||||||
<button value="zoom-month">Monat</button>
|
|
||||||
<button value="zoom-year">Jahr</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3><img src="images/table.png" alt="" /> Kanäle</h3>
|
|
||||||
<div id="entity-list">
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th><img src="images/eye.png" alt="Anzeige" title="Anzeige" /></th>
|
|
||||||
<th></th>
|
|
||||||
<th>Titel</th>
|
|
||||||
<th>Typ</th>
|
|
||||||
<th>Min.</th>
|
|
||||||
<th>Max.</th>
|
|
||||||
<th>∅</th>
|
|
||||||
<th>aktuell</th>
|
|
||||||
<th>Verbrauch</th>
|
|
||||||
<th>Kosten</th>
|
|
||||||
<th>Aktion</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody></tbody>
|
|
||||||
</table>
|
|
||||||
<div><button name="entity-add"><img src="images/add.png" alt="add" /> Kanal hinzufügen</button></div>
|
|
||||||
</div>
|
|
||||||
<h3><img src="images/wrench.png" alt="" /> Optionen</h3>
|
|
||||||
<div id="options">
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Option</th>
|
|
||||||
<th>Wert</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td><label for="refresh"><img src="images/arrow_refresh.png" alt="" /> Automatisch aktualisieren</label></td>
|
|
||||||
<td><input type="checkbox" id="refresh" /> <span id="refresh-time"><span></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div><button name="options-save"><img src="images/save.png" alt="save" /> Einstellungen speichern</button></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="footer">
|
|
||||||
© 2011 - <a href="http://volkszaehler.org/">volkszaehler.org</a> - the open smartmeter platform
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- dialogs -->
|
|
||||||
<div id="entity-move" class="dialog">
|
|
||||||
<p>
|
|
||||||
<span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>
|
|
||||||
Sie sind im Begriff einen Kanal oder eine Gruppe zu Verschieben!
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="entity-add" class="dialog">
|
|
||||||
<div class="tabs">
|
|
||||||
<ul>
|
|
||||||
<li><a href="#entity-subscribe">Kanal abonnieren</a></li>
|
|
||||||
<li><a href="#entity-public">öffentliche Kanäle</a></li>
|
|
||||||
<li><a href="#entity-create">Kanal erstellen</a></li>
|
|
||||||
</ul>
|
|
||||||
<div id="entity-subscribe">
|
|
||||||
<p>Hier können Sie einen existierenden Kanal über seine UUID hinzufügen</p>
|
|
||||||
<table>
|
|
||||||
<tr><td><label for="entity-subscribe-middleware">Middleware:</label></td><td><input id="entity-subscribe-middleware" type="text" size="36" /></td></tr>
|
|
||||||
<tr><td><label for="entity-subscribe-uuid">UUID:</label></td><td><input id="entity-subscribe-uuid" type="text" size="36" maxlength="36" /></td></tr>
|
|
||||||
</table>
|
|
||||||
<p><input type="button" value="Abonnieren" /> <label for="entity-subscribe-cookie">Cookie:</label> <input id="entity-subscribe-cookie" type="checkbox" /></p>
|
|
||||||
</div>
|
|
||||||
<div id="entity-public">
|
|
||||||
<p>Hier können Sie öffentliche Kanäle abonnieren.</p>
|
|
||||||
<table>
|
|
||||||
<tr><td><label for="entity-public-middleware">Middleware:</label></td><td><select id="entity-public-middleware"></select></td></tr>
|
|
||||||
<tr><td><label for="entity-public-entity">Kanal:</label></td><td><select id="entity-public-entity" size="1"></select></td></tr>
|
|
||||||
</table>
|
|
||||||
<p><input type="button" value="Abonnieren" /> <label for="entity-public-cookie">Cookie:</label> <input id="entity-public-cookie" type="checkbox" /></p>
|
|
||||||
</div>
|
|
||||||
<div id="entity-create">
|
|
||||||
<form method="get" target="_blank">
|
|
||||||
<table>
|
|
||||||
<tr class="property"><th>Eigenschaft</th><th>Wert</th></tr>
|
|
||||||
<tr class="property"><td>Middleware:</td><td><input type="text" id="entity-create-middleware" /></td></tr>
|
|
||||||
<tr class="property"><td>Typ:</td><td><select class="icons" name="type" size="1"></select></td></tr>
|
|
||||||
<tr class="property"><td>Öffentlich:</td><td><input type="radio" name="public" value="1"> ja <input type="radio" name="public" value="0"> nein</td></tr>
|
|
||||||
<tr class="property"><td>Titel:</td><td><input type="text" name="title" value="Kühlschrank" /></td></tr>
|
|
||||||
<tr class="property"><td>Auflösung:</td><td><input type="text" name="resolution" value="1000" /></td></tr>
|
|
||||||
<tr class="property"><td>Kosten:<br /><p style="font-size: small">pro Wh</p></td><td><input type="text" name="cost" value="0.00025" /> €</td></tr>
|
|
||||||
<tr class="property"><td>Beschreibung:</td><td><input type="text" name="description" value="Swissnox 1-phasig" /></td></tr>
|
|
||||||
</table>
|
|
||||||
<p><input type="submit" value="Erstellen" /> <label for="entity-create-cookie">Cookie:</label> <input id="entity-create-cookie" type="checkbox" /></p>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1,189 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @author Florian Ziegler <fz@f10-home.de>
|
|
||||||
* @author Justin Otherguy <justin@justinotherguy.org>
|
|
||||||
* @author Steffen Vogel <info@steffenvogel.de>
|
|
||||||
* @copyright Copyright (c) 2011, The volkszaehler.org project
|
|
||||||
* @package default
|
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* This file is part of volkzaehler.org
|
|
||||||
*
|
|
||||||
* volkzaehler.org is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, either version 3 of the License, or any later version.
|
|
||||||
*
|
|
||||||
* volkzaehler.org is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save minimal Entity in JSON cookie
|
|
||||||
*/
|
|
||||||
vz.entities.saveCookie = function() {
|
|
||||||
var expires = new Date(new Date().getTime() + 3e10); // in about a year
|
|
||||||
var arr = new Array;
|
|
||||||
|
|
||||||
this.each(function(entity) {
|
|
||||||
if (entity.cookie === true) {
|
|
||||||
arr.push(entity.uuid + '@' + entity.middleware);
|
|
||||||
}
|
|
||||||
}, true); // recursive!
|
|
||||||
|
|
||||||
$.setCookie('vz_entities', arr.join('|'), {expires: expires});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load entities from JSON cookie
|
|
||||||
*/
|
|
||||||
vz.entities.loadCookie = function() {
|
|
||||||
var cookie = $.getCookie('vz_entities');
|
|
||||||
if (cookie) {
|
|
||||||
var arr = cookie.split('|');
|
|
||||||
arr.each(function(index, entry) {
|
|
||||||
var entity = entry.split('@');
|
|
||||||
vz.entities.push(new Entity({
|
|
||||||
middleware: entity[1],
|
|
||||||
uuid: entity[0],
|
|
||||||
cookie: true
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load JSON data from the middleware
|
|
||||||
*/
|
|
||||||
vz.entities.loadData = function() {
|
|
||||||
$('#overlay').html('<img src="images/loading.gif" alt="loading..." /><p>loading...</p>');
|
|
||||||
|
|
||||||
var queue = new Array;
|
|
||||||
this.each(function(entity) {
|
|
||||||
if (entity.active && entity.definition.model == 'Volkszaehler\\Model\\Channel') {
|
|
||||||
queue.push(entity.loadData());
|
|
||||||
}
|
|
||||||
}, true); // recursive!
|
|
||||||
|
|
||||||
return $.when.apply($, queue);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Overwritten each iterator to iterate recursively throug all entities
|
|
||||||
*/
|
|
||||||
vz.entities.each = function(cb, recursive) {
|
|
||||||
for (var i = 0; i < this.length; i++) {
|
|
||||||
cb(this[i]);
|
|
||||||
|
|
||||||
if (recursive && this[i] !== undefined) {
|
|
||||||
this[i].each(cb, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create nested entity list
|
|
||||||
*
|
|
||||||
* @todo move to Entity class
|
|
||||||
*/
|
|
||||||
vz.entities.showTable = function() {
|
|
||||||
$('#entity-list tbody').empty();
|
|
||||||
|
|
||||||
vz.entities.sort(Entity.compare);
|
|
||||||
|
|
||||||
this.each(function(entity, parent) {
|
|
||||||
$('#entity-list tbody').append(entity.getDOMRow(parent));
|
|
||||||
}, true); // recursive!
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize treeTable
|
|
||||||
*
|
|
||||||
* http://ludo.cubicphuse.nl/jquery-plugins/treeTable/doc/index.html
|
|
||||||
* https://github.com/ludo/jquery-plugins/tree/master/treeTable
|
|
||||||
*/
|
|
||||||
// configure entities as draggable
|
|
||||||
$('#entity-list tr.channel span.indicator, #entity-list tr.aggregator span.indicator').draggable({
|
|
||||||
helper: 'clone',
|
|
||||||
opacity: 0.75,
|
|
||||||
refreshPositions: true, // Performance?
|
|
||||||
revert: 'invalid',
|
|
||||||
revertDuration: 300,
|
|
||||||
scroll: true
|
|
||||||
});
|
|
||||||
|
|
||||||
// configure aggregators as droppable
|
|
||||||
$('#entity-list tr.aggregator span.indicator').each(function() {
|
|
||||||
$(this).parents('tr').droppable({
|
|
||||||
//accept: 'tr.channel span.indicator, tr.aggregator span.indicator', // TODO
|
|
||||||
drop: function(event, ui) {
|
|
||||||
var child = $(ui.draggable.parents('tr')[0]).data('entity');
|
|
||||||
var from = child.parent;
|
|
||||||
var to = $(this).data('entity');
|
|
||||||
|
|
||||||
$('#entity-move').dialog({ // confirm prompt
|
|
||||||
resizable: false,
|
|
||||||
modal: true,
|
|
||||||
title: 'Verschieben',
|
|
||||||
width: 400,
|
|
||||||
buttons: {
|
|
||||||
'Verschieben': function() {
|
|
||||||
try {
|
|
||||||
var queue = new Array;
|
|
||||||
queue.push(to.addChild(child)); // add to new aggregator
|
|
||||||
|
|
||||||
if (from !== undefined) {
|
|
||||||
queue.push(from.removeChild(child)); // remove from aggregator
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
child.cookie = false; // remove from cookies
|
|
||||||
vz.entities.saveCookie();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
vz.wui.dialogs.exception(e);
|
|
||||||
} finally {
|
|
||||||
$.when(queue).done(function() {
|
|
||||||
// wait for middleware
|
|
||||||
$.when(from.loadDetails(), to.loadDetails).done(vz.entities.showTable);
|
|
||||||
});
|
|
||||||
$(this).dialog('close');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'Abbrechen': function() {
|
|
||||||
$(this).dialog('close');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
hoverClass: 'accept',
|
|
||||||
over: function(event, ui) {
|
|
||||||
// make the droppable branch expand when a draggable node is moved over it
|
|
||||||
if (this.id != $(ui.draggable.parents('tr')[0]).id && !$(this).hasClass('expanded')) {
|
|
||||||
$(this).expand();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// make visible that a row is clicked
|
|
||||||
$('#entity-list table tbody tr').mousedown(function() {
|
|
||||||
$('tr.selected').removeClass('selected'); // deselect currently selected rows
|
|
||||||
$(this).addClass('selected');
|
|
||||||
});
|
|
||||||
|
|
||||||
// make sure row is selected when span is clicked
|
|
||||||
$('#entity-list table tbody tr span').mousedown(function() {
|
|
||||||
$($(this).parents('tr')[0]).trigger('mousedown');
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#entity-list table').treeTable({
|
|
||||||
treeColumn: 2,
|
|
||||||
clickableNodeNames: true,
|
|
||||||
initialState: 'expanded'
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -1,455 +0,0 @@
|
||||||
/**
|
|
||||||
* Entity handling, parsing & validation
|
|
||||||
*
|
|
||||||
* @author Justin Otherguy <justin@justinotherguy.org>
|
|
||||||
* @author Steffen Vogel <info@steffenvogel.de>
|
|
||||||
* @copyright Copyright (c) 2011, The volkszaehler.org project
|
|
||||||
* @package default
|
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* This file is part of volkzaehler.org
|
|
||||||
*
|
|
||||||
* volkzaehler.org is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, either version 3 of the License, or any later version.
|
|
||||||
*
|
|
||||||
* volkzaehler.org is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Entity constructor
|
|
||||||
* @todo add validation
|
|
||||||
*/
|
|
||||||
var Entity = function(json) {
|
|
||||||
this.parseJSON(json);
|
|
||||||
};
|
|
||||||
|
|
||||||
Entity.colors = 0;
|
|
||||||
|
|
||||||
Entity.prototype.parseJSON = function(json) {
|
|
||||||
$.extend(true, this, json);
|
|
||||||
|
|
||||||
// parse children
|
|
||||||
if (this.children) {
|
|
||||||
for (var i = 0; i < this.children.length; i++) {
|
|
||||||
this.children[i].middleware = this.middleware; // children inherit parent middleware
|
|
||||||
this.children[i] = new Entity(this.children[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.children.sort(Entity.compare);
|
|
||||||
}
|
|
||||||
|
|
||||||
// setting defaults
|
|
||||||
if (this.type !== undefined) {
|
|
||||||
this.definition = vz.capabilities.definitions.get('entities', this.type);
|
|
||||||
|
|
||||||
if (this.style === undefined) {
|
|
||||||
if (this.definition.style) {
|
|
||||||
this.style = this.definition.style;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.style = (this.definition.interpreter == 'Volkszaehler\\Interpreter\\SensorInterpreter') ? 'lines' : 'steps';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.active === undefined) {
|
|
||||||
this.active = true; // activate by default
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.color === undefined) {
|
|
||||||
this.color = vz.options.plot.colors[Entity.colors++ % vz.options.plot.colors.length];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query middleware for details
|
|
||||||
*/
|
|
||||||
Entity.prototype.loadDetails = function() {
|
|
||||||
return vz.load({
|
|
||||||
url: this.middleware,
|
|
||||||
controller: 'entity',
|
|
||||||
identifier: this.uuid,
|
|
||||||
context: this,
|
|
||||||
success: function(json) {
|
|
||||||
this.parseJSON(json.entity);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Entity.prototype.loadData = function() {
|
|
||||||
return vz.load({
|
|
||||||
controller: 'data',
|
|
||||||
url: this.middleware,
|
|
||||||
identifier: this.uuid,
|
|
||||||
context: this,
|
|
||||||
data: {
|
|
||||||
from: Math.floor(vz.options.plot.xaxis.min),
|
|
||||||
to: Math.ceil(vz.options.plot.xaxis.max),
|
|
||||||
tuples: vz.options.tuples
|
|
||||||
},
|
|
||||||
success: function(json) {
|
|
||||||
this.data = json.data;
|
|
||||||
|
|
||||||
if (this.data.tuples && this.data.tuples.length > 0) {
|
|
||||||
if (this.data.min[1] < vz.options.plot.yaxis.min) { // allow negative values for temperature sensors
|
|
||||||
vz.options.plot.yaxis.min = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.updateDOMRow();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show and edit entity details
|
|
||||||
*/
|
|
||||||
Entity.prototype.showDetails = function() {
|
|
||||||
var entity = this;
|
|
||||||
|
|
||||||
$('<div>')
|
|
||||||
.addClass('details')
|
|
||||||
.append(this.getDOMDetails())
|
|
||||||
.dialog({
|
|
||||||
title: 'Details für ' + this.title,
|
|
||||||
width: 480,
|
|
||||||
resizable: false,
|
|
||||||
buttons : {
|
|
||||||
'Schließen': function() {
|
|
||||||
$(this).dialog('close');
|
|
||||||
},
|
|
||||||
'Löschen' : function() {
|
|
||||||
entity.cookie = false;
|
|
||||||
vz.entities.saveCookie();
|
|
||||||
|
|
||||||
entity.delete().done(function() {
|
|
||||||
vz.entities.each(function(it, parent) {
|
|
||||||
if (entity == it) {
|
|
||||||
var array = (parent) ? parent.children : vz.entities;
|
|
||||||
array.remove(it);
|
|
||||||
}
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
vz.entities.showTable();
|
|
||||||
vz.wui.drawPlot();
|
|
||||||
});
|
|
||||||
|
|
||||||
$(this).dialog('close');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show from for new Channel
|
|
||||||
*
|
|
||||||
* @todo implement/test
|
|
||||||
*/
|
|
||||||
Entity.prototype.getDOMDetails = function(edit) {
|
|
||||||
var table = $('<table><thead><tr><th>Eigenschaft</th><th>Wert</th></tr></thead></table>');
|
|
||||||
var data = $('<tbody>');
|
|
||||||
|
|
||||||
// general properties
|
|
||||||
var general = ['title', 'type', 'uuid', 'middleware', 'color', 'style', 'active', 'cookie'];
|
|
||||||
var sections = ['required', 'optional'];
|
|
||||||
|
|
||||||
general.each(function(index, property) {
|
|
||||||
var definition = vz.capabilities.definitions.get('properties', property);
|
|
||||||
var title = (definition) ? definition.translation[vz.options.language] : property;
|
|
||||||
var value = this[property];
|
|
||||||
|
|
||||||
switch(property) {
|
|
||||||
case 'type':
|
|
||||||
var title = 'Typ';
|
|
||||||
var icon = $('<img>').
|
|
||||||
attr('src', 'images/types/' + this.definition.icon)
|
|
||||||
.css('margin-right', 4);
|
|
||||||
var value = $('<span>')
|
|
||||||
.text(this.definition.translation[vz.options.language])
|
|
||||||
.prepend(icon);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'middleware':
|
|
||||||
var title = 'Middleware';
|
|
||||||
var value = '<a href="' + this.middleware + '/capabilities.json">' + this.middleware + '</a>';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'uuid':
|
|
||||||
var title = 'UUID';
|
|
||||||
var value = '<a href="' + this.middleware + '/entity/' + this.uuid + '.json">' + this.uuid + '</a>';
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'color':
|
|
||||||
var value = $('<span>')
|
|
||||||
.text(this.color)
|
|
||||||
.css('background-color', this.color)
|
|
||||||
.css('padding-left', 5)
|
|
||||||
.css('padding-right', 5);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'cookie':
|
|
||||||
var title = 'Cookie';
|
|
||||||
value = '<img src="images/' + ((this.cookie) ? 'tick' : 'cross') + '.png" alt="' + ((value) ? 'ja' : 'nein') + '" />';
|
|
||||||
break;
|
|
||||||
case 'active':
|
|
||||||
var value = '<img src="images/' + ((this.active) ? 'tick' : 'cross') + '.png" alt="' + ((this.active) ? 'ja' : 'nein') + '" />';
|
|
||||||
break;
|
|
||||||
case 'style':
|
|
||||||
switch (this.style) {
|
|
||||||
case 'lines': var value = 'Linien'; break;
|
|
||||||
case 'steps': var value = 'Stufen'; break;
|
|
||||||
case 'points': var value = 'Punkte'; break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
data.append($('<tr>')
|
|
||||||
.addClass('property')
|
|
||||||
.addClass('general')
|
|
||||||
.append($('<td>')
|
|
||||||
.addClass('key')
|
|
||||||
.text(title)
|
|
||||||
)
|
|
||||||
.append($('<td>')
|
|
||||||
.addClass('value')
|
|
||||||
.append(value)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
sections.each(function(index, section) {
|
|
||||||
this.definition[section].each(function(index, property) {
|
|
||||||
if (this.hasOwnProperty(property) && !general.contains(property)) {
|
|
||||||
var definition = vz.capabilities.definitions.get('properties', property);
|
|
||||||
var title = definition.translation[vz.options.language];
|
|
||||||
var value = this[property];
|
|
||||||
|
|
||||||
if (definition.type == 'boolean') {
|
|
||||||
value = '<img src="images/' + ((value) ? 'tick' : 'cross') + '.png" alt="' + ((value) ? 'ja' : 'nein') + '" />';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (property == 'cost') {
|
|
||||||
value = (value * 1000 * 100) + ' ct/k' + this.definition.unit + 'h'; // ct per kWh
|
|
||||||
}
|
|
||||||
|
|
||||||
data.append($('<tr>')
|
|
||||||
.addClass('property')
|
|
||||||
.addClass(section)
|
|
||||||
.append($('<td>')
|
|
||||||
.addClass('key')
|
|
||||||
.text(title)
|
|
||||||
)
|
|
||||||
.append($('<td>')
|
|
||||||
.addClass('value')
|
|
||||||
.append(value)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
}, this);
|
|
||||||
return table.append(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
Entity.prototype.getDOMRow = function(parent) {
|
|
||||||
var row = $('<tr>')
|
|
||||||
.addClass((parent) ? 'child-of-entity-' + parent.uuid : '')
|
|
||||||
.addClass((this.definition.model == 'Volkszaehler\\Model\\Aggregator') ? 'aggregator' : 'channel')
|
|
||||||
.addClass('entity')
|
|
||||||
.attr('id', 'entity-' + this.uuid)
|
|
||||||
.append($('<td>')
|
|
||||||
.addClass('visibility')
|
|
||||||
.css('background-color', this.color)
|
|
||||||
.append($('<input>')
|
|
||||||
.attr('type', 'checkbox')
|
|
||||||
.attr('checked', this.active)
|
|
||||||
.bind('change', this, function(event) {
|
|
||||||
var state = $(this).attr('checked');
|
|
||||||
|
|
||||||
event.data.active = state;
|
|
||||||
$('#entity-' + event.data.uuid + ((parent) ? '.child-of-entity-' + parent.uuid : '') + ' input[type=checkbox]');
|
|
||||||
|
|
||||||
event.data.each(function(entity, parent) {
|
|
||||||
$('#entity-' + entity.uuid + ((parent) ? '.child-of-entity-' + parent.uuid : '') + ' input[type=checkbox]')
|
|
||||||
.attr('checked', state);
|
|
||||||
entity.active = state;
|
|
||||||
}, true); // recursive!
|
|
||||||
|
|
||||||
vz.wui.drawPlot();
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.append($('<td>').addClass('expander'))
|
|
||||||
.append($('<td>')
|
|
||||||
.append($('<span>')
|
|
||||||
.text(this.title)
|
|
||||||
.addClass('indicator')
|
|
||||||
.css('background-image', 'url(images/types/' + this.definition.icon + ')')
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.append($('<td>').text(this.definition.translation[vz.options.language])) // channel type
|
|
||||||
.append($('<td>').addClass('min')) // min
|
|
||||||
.append($('<td>').addClass('max')) // max
|
|
||||||
.append($('<td>').addClass('average')) // avg
|
|
||||||
.append($('<td>').addClass('last')) // last value
|
|
||||||
.append($('<td>').addClass('consumption')) // consumption
|
|
||||||
.append($('<td>').addClass('cost')) // costs
|
|
||||||
.append($('<td>') // operations
|
|
||||||
.addClass('ops')
|
|
||||||
.append($('<input>')
|
|
||||||
.attr('type', 'image')
|
|
||||||
.attr('src', 'images/information.png')
|
|
||||||
.attr('alt', 'details')
|
|
||||||
.bind('click', this, function(event) {
|
|
||||||
event.data.showDetails();
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.data('entity', this);
|
|
||||||
|
|
||||||
if (this.cookie) {
|
|
||||||
$('td.ops', row).prepend($('<input>')
|
|
||||||
.attr('type', 'image')
|
|
||||||
.attr('src', 'images/delete.png')
|
|
||||||
.attr('alt', 'delete')
|
|
||||||
.bind('click', this, function(event) {
|
|
||||||
vz.entities.remove(event.data);
|
|
||||||
vz.entities.saveCookie();
|
|
||||||
vz.entities.showTable();
|
|
||||||
vz.wui.drawPlot();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return row;
|
|
||||||
};
|
|
||||||
|
|
||||||
Entity.prototype.updateDOMRow = function() {
|
|
||||||
var row = $('#entity-' + this.uuid);
|
|
||||||
|
|
||||||
var delta = this.data.to - this.data.from;
|
|
||||||
var year = 365*24*60*60*1000;
|
|
||||||
|
|
||||||
if (this.data.rows > 0) { // update statistics if data available
|
|
||||||
$('.min', row)
|
|
||||||
.text(vz.wui.formatNumber(this.data.min[1], true) + this.definition.unit)
|
|
||||||
.attr('title', $.plot.formatDate(new Date(this.data.min[0]), '%d. %b %y %h:%M:%S', vz.options.plot.xaxis.monthNames, true));
|
|
||||||
$('.max', row)
|
|
||||||
.text(vz.wui.formatNumber(this.data.max[1], true) + this.definition.unit)
|
|
||||||
.attr('title', $.plot.formatDate(new Date(this.data.max[0]), '%d. %b %y %h:%M:%S', vz.options.plot.xaxis.monthNames, true));
|
|
||||||
$('.average', row)
|
|
||||||
.text(vz.wui.formatNumber(this.data.average, true) + this.definition.unit);
|
|
||||||
$('.last', row)
|
|
||||||
.text(vz.wui.formatNumber(this.data.tuples.last()[1], true) + this.definition.unit);
|
|
||||||
|
|
||||||
$('.consumption', row)
|
|
||||||
.text(vz.wui.formatNumber(this.data.consumption, true) + this.definition.unit + 'h')
|
|
||||||
.attr('title', vz.wui.formatNumber(this.data.consumption * (year/delta), true) + this.definition.unit + 'h' + '/Jahr');
|
|
||||||
|
|
||||||
if (this.cost) {
|
|
||||||
$('.cost', row)
|
|
||||||
.text(vz.wui.formatNumber(this.cost * this.data.consumption) + ' €')
|
|
||||||
.attr('title', vz.wui.formatNumber(this.cost * this.data.consumption * (year/delta)) + ' €/Jahr');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { // no data available, clear table
|
|
||||||
$('.min', row).text('').attr('title', '');
|
|
||||||
$('.max', row).text('').attr('title', '');
|
|
||||||
$('.average', row).text('');
|
|
||||||
$('.last', row).text('');
|
|
||||||
$('.consumption', row).text('');
|
|
||||||
$('.cost', row).text('');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Permanently deletes this entity and its data from the middleware
|
|
||||||
*/
|
|
||||||
Entity.prototype.delete = function() {
|
|
||||||
return vz.load({
|
|
||||||
controller: 'entity',
|
|
||||||
context: this,
|
|
||||||
identifier: this.uuid,
|
|
||||||
url: this.middleware,
|
|
||||||
type: 'DELETE'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add entity as child
|
|
||||||
*/
|
|
||||||
Entity.prototype.addChild = function(child) {
|
|
||||||
if (this.definition.model != 'Volkszaehler\\Model\\Aggregator') {
|
|
||||||
throw new Exception('EntityException', 'Entity is not an Aggregator');
|
|
||||||
}
|
|
||||||
|
|
||||||
return vz.load({
|
|
||||||
controller: 'group',
|
|
||||||
identifier: this.uuid,
|
|
||||||
url: this.middleware,
|
|
||||||
data: {
|
|
||||||
uuid: child.uuid
|
|
||||||
},
|
|
||||||
type: 'POST'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove entity from children
|
|
||||||
*/
|
|
||||||
Entity.prototype.removeChild = function(child) {
|
|
||||||
if (this.definition.model != 'Volkszaehler\\Model\\Aggregator') {
|
|
||||||
throw new Exception('EntityException', 'Entity is not an Aggregator');
|
|
||||||
}
|
|
||||||
|
|
||||||
return vz.load({
|
|
||||||
controller: 'group',
|
|
||||||
identifier: this.uuid,
|
|
||||||
url: this.middleware,
|
|
||||||
data: {
|
|
||||||
uuid: child.uuid,
|
|
||||||
type: 'DELETE'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calls the callback function for the entity and all nested children
|
|
||||||
*
|
|
||||||
* @param cb callback function
|
|
||||||
*/
|
|
||||||
Entity.prototype.each = function(cb, recursive) {
|
|
||||||
if (this.children) {
|
|
||||||
for (var i = 0; i < this.children.length; i++) {
|
|
||||||
cb(this.children[i], this);
|
|
||||||
|
|
||||||
if (recursive && this.children[i] !== undefined) {
|
|
||||||
this.children[i].each(cb, true); // call recursive
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compares two entities for sorting
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @todo Channels before Aggregators
|
|
||||||
*/
|
|
||||||
Entity.compare = function(a, b) {
|
|
||||||
if (a.definition.model == 'Volkszaehler\\Model\\Channel' && // Channels before Aggregators
|
|
||||||
b.definition.model == 'Volkszaehler\\Model\\Aggregator')
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return ((a.title < b.title) ? -1 : ((a.title > b.title) ? 1 : 0));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,179 +0,0 @@
|
||||||
/* Plugin for jQuery for working with colors.
|
|
||||||
*
|
|
||||||
* Version 1.1.
|
|
||||||
*
|
|
||||||
* Inspiration from jQuery color animation plugin by John Resig.
|
|
||||||
*
|
|
||||||
* Released under the MIT license by Ole Laursen, October 2009.
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
*
|
|
||||||
* $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
|
|
||||||
* var c = $.color.extract($("#mydiv"), 'background-color');
|
|
||||||
* console.log(c.r, c.g, c.b, c.a);
|
|
||||||
* $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
|
|
||||||
*
|
|
||||||
* Note that .scale() and .add() return the same modified object
|
|
||||||
* instead of making a new one.
|
|
||||||
*
|
|
||||||
* V. 1.1: Fix error handling so e.g. parsing an empty string does
|
|
||||||
* produce a color rather than just crashing.
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function($) {
|
|
||||||
$.color = {};
|
|
||||||
|
|
||||||
// construct color object with some convenient chainable helpers
|
|
||||||
$.color.make = function (r, g, b, a) {
|
|
||||||
var o = {};
|
|
||||||
o.r = r || 0;
|
|
||||||
o.g = g || 0;
|
|
||||||
o.b = b || 0;
|
|
||||||
o.a = a != null ? a : 1;
|
|
||||||
|
|
||||||
o.add = function (c, d) {
|
|
||||||
for (var i = 0; i < c.length; ++i)
|
|
||||||
o[c.charAt(i)] += d;
|
|
||||||
return o.normalize();
|
|
||||||
};
|
|
||||||
|
|
||||||
o.scale = function (c, f) {
|
|
||||||
for (var i = 0; i < c.length; ++i)
|
|
||||||
o[c.charAt(i)] *= f;
|
|
||||||
return o.normalize();
|
|
||||||
};
|
|
||||||
|
|
||||||
o.toString = function () {
|
|
||||||
if (o.a >= 1.0) {
|
|
||||||
return "rgb("+[o.r, o.g, o.b].join(",")+")";
|
|
||||||
} else {
|
|
||||||
return "rgba("+[o.r, o.g, o.b, o.a].join(",")+")";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
o.normalize = function () {
|
|
||||||
function clamp(min, value, max) {
|
|
||||||
return value < min ? min: (value > max ? max: value);
|
|
||||||
}
|
|
||||||
|
|
||||||
o.r = clamp(0, parseInt(o.r), 255);
|
|
||||||
o.g = clamp(0, parseInt(o.g), 255);
|
|
||||||
o.b = clamp(0, parseInt(o.b), 255);
|
|
||||||
o.a = clamp(0, o.a, 1);
|
|
||||||
return o;
|
|
||||||
};
|
|
||||||
|
|
||||||
o.clone = function () {
|
|
||||||
return $.color.make(o.r, o.b, o.g, o.a);
|
|
||||||
};
|
|
||||||
|
|
||||||
return o.normalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
// extract CSS color property from element, going up in the DOM
|
|
||||||
// if it's "transparent"
|
|
||||||
$.color.extract = function (elem, css) {
|
|
||||||
var c;
|
|
||||||
do {
|
|
||||||
c = elem.css(css).toLowerCase();
|
|
||||||
// keep going until we find an element that has color, or
|
|
||||||
// we hit the body
|
|
||||||
if (c != '' && c != 'transparent')
|
|
||||||
break;
|
|
||||||
elem = elem.parent();
|
|
||||||
} while (!$.nodeName(elem.get(0), "body"));
|
|
||||||
|
|
||||||
// catch Safari's way of signalling transparent
|
|
||||||
if (c == "rgba(0, 0, 0, 0)")
|
|
||||||
c = "transparent";
|
|
||||||
|
|
||||||
return $.color.parse(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse CSS color string (like "rgb(10, 32, 43)" or "#fff"),
|
|
||||||
// returns color object, if parsing failed, you get black (0, 0,
|
|
||||||
// 0) out
|
|
||||||
$.color.parse = function (str) {
|
|
||||||
var res, m = $.color.make;
|
|
||||||
|
|
||||||
// Look for rgb(num,num,num)
|
|
||||||
if (res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))
|
|
||||||
return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10));
|
|
||||||
|
|
||||||
// Look for rgba(num,num,num,num)
|
|
||||||
if (res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
|
|
||||||
return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4]));
|
|
||||||
|
|
||||||
// Look for rgb(num%,num%,num%)
|
|
||||||
if (res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))
|
|
||||||
return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55);
|
|
||||||
|
|
||||||
// Look for rgba(num%,num%,num%,num)
|
|
||||||
if (res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
|
|
||||||
return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55, parseFloat(res[4]));
|
|
||||||
|
|
||||||
// Look for #a0b1c2
|
|
||||||
if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))
|
|
||||||
return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16));
|
|
||||||
|
|
||||||
// Look for #fff
|
|
||||||
if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))
|
|
||||||
return m(parseInt(res[1]+res[1], 16), parseInt(res[2]+res[2], 16), parseInt(res[3]+res[3], 16));
|
|
||||||
|
|
||||||
// Otherwise, we're most likely dealing with a named color
|
|
||||||
var name = $.trim(str).toLowerCase();
|
|
||||||
if (name == "transparent")
|
|
||||||
return m(255, 255, 255, 0);
|
|
||||||
else {
|
|
||||||
// default to black
|
|
||||||
res = lookupColors[name] || [0, 0, 0];
|
|
||||||
return m(res[0], res[1], res[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var lookupColors = {
|
|
||||||
aqua:[0,255,255],
|
|
||||||
azure:[240,255,255],
|
|
||||||
beige:[245,245,220],
|
|
||||||
black:[0,0,0],
|
|
||||||
blue:[0,0,255],
|
|
||||||
brown:[165,42,42],
|
|
||||||
cyan:[0,255,255],
|
|
||||||
darkblue:[0,0,139],
|
|
||||||
darkcyan:[0,139,139],
|
|
||||||
darkgrey:[169,169,169],
|
|
||||||
darkgreen:[0,100,0],
|
|
||||||
darkkhaki:[189,183,107],
|
|
||||||
darkmagenta:[139,0,139],
|
|
||||||
darkolivegreen:[85,107,47],
|
|
||||||
darkorange:[255,140,0],
|
|
||||||
darkorchid:[153,50,204],
|
|
||||||
darkred:[139,0,0],
|
|
||||||
darksalmon:[233,150,122],
|
|
||||||
darkviolet:[148,0,211],
|
|
||||||
fuchsia:[255,0,255],
|
|
||||||
gold:[255,215,0],
|
|
||||||
green:[0,128,0],
|
|
||||||
indigo:[75,0,130],
|
|
||||||
khaki:[240,230,140],
|
|
||||||
lightblue:[173,216,230],
|
|
||||||
lightcyan:[224,255,255],
|
|
||||||
lightgreen:[144,238,144],
|
|
||||||
lightgrey:[211,211,211],
|
|
||||||
lightpink:[255,182,193],
|
|
||||||
lightyellow:[255,255,224],
|
|
||||||
lime:[0,255,0],
|
|
||||||
magenta:[255,0,255],
|
|
||||||
maroon:[128,0,0],
|
|
||||||
navy:[0,0,128],
|
|
||||||
olive:[128,128,0],
|
|
||||||
orange:[255,165,0],
|
|
||||||
pink:[255,192,203],
|
|
||||||
purple:[128,0,128],
|
|
||||||
violet:[128,0,128],
|
|
||||||
red:[255,0,0],
|
|
||||||
silver:[192,192,192],
|
|
||||||
white:[255,255,255],
|
|
||||||
yellow:[255,255,0]
|
|
||||||
};
|
|
||||||
})(jQuery);
|
|
|
@ -1,167 +0,0 @@
|
||||||
/*
|
|
||||||
Flot plugin for showing crosshairs, thin lines, when the mouse hovers
|
|
||||||
over the plot.
|
|
||||||
|
|
||||||
crosshair: {
|
|
||||||
mode: null or "x" or "y" or "xy"
|
|
||||||
color: color
|
|
||||||
lineWidth: number
|
|
||||||
}
|
|
||||||
|
|
||||||
Set the mode to one of "x", "y" or "xy". The "x" mode enables a
|
|
||||||
vertical crosshair that lets you trace the values on the x axis, "y"
|
|
||||||
enables a horizontal crosshair and "xy" enables them both. "color" is
|
|
||||||
the color of the crosshair (default is "rgba(170, 0, 0, 0.80)"),
|
|
||||||
"lineWidth" is the width of the drawn lines (default is 1).
|
|
||||||
|
|
||||||
The plugin also adds four public methods:
|
|
||||||
|
|
||||||
- setCrosshair(pos)
|
|
||||||
|
|
||||||
Set the position of the crosshair. Note that this is cleared if
|
|
||||||
the user moves the mouse. "pos" is in coordinates of the plot and
|
|
||||||
should be on the form { x: xpos, y: ypos } (you can use x2/x3/...
|
|
||||||
if you're using multiple axes), which is coincidentally the same
|
|
||||||
format as what you get from a "plothover" event. If "pos" is null,
|
|
||||||
the crosshair is cleared.
|
|
||||||
|
|
||||||
- clearCrosshair()
|
|
||||||
|
|
||||||
Clear the crosshair.
|
|
||||||
|
|
||||||
- lockCrosshair(pos)
|
|
||||||
|
|
||||||
Cause the crosshair to lock to the current location, no longer
|
|
||||||
updating if the user moves the mouse. Optionally supply a position
|
|
||||||
(passed on to setCrosshair()) to move it to.
|
|
||||||
|
|
||||||
Example usage:
|
|
||||||
var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } };
|
|
||||||
$("#graph").bind("plothover", function (evt, position, item) {
|
|
||||||
if (item) {
|
|
||||||
// Lock the crosshair to the data point being hovered
|
|
||||||
myFlot.lockCrosshair({ x: item.datapoint[0], y: item.datapoint[1] });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Return normal crosshair operation
|
|
||||||
myFlot.unlockCrosshair();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
- unlockCrosshair()
|
|
||||||
|
|
||||||
Free the crosshair to move again after locking it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function ($) {
|
|
||||||
var options = {
|
|
||||||
crosshair: {
|
|
||||||
mode: null, // one of null, "x", "y" or "xy",
|
|
||||||
color: "rgba(170, 0, 0, 0.80)",
|
|
||||||
lineWidth: 1
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function init(plot) {
|
|
||||||
// position of crosshair in pixels
|
|
||||||
var crosshair = { x: -1, y: -1, locked: false };
|
|
||||||
|
|
||||||
plot.setCrosshair = function setCrosshair(pos) {
|
|
||||||
if (!pos)
|
|
||||||
crosshair.x = -1;
|
|
||||||
else {
|
|
||||||
var o = plot.p2c(pos);
|
|
||||||
crosshair.x = Math.max(0, Math.min(o.left, plot.width()));
|
|
||||||
crosshair.y = Math.max(0, Math.min(o.top, plot.height()));
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
};
|
|
||||||
|
|
||||||
plot.clearCrosshair = plot.setCrosshair; // passes null for pos
|
|
||||||
|
|
||||||
plot.lockCrosshair = function lockCrosshair(pos) {
|
|
||||||
if (pos)
|
|
||||||
plot.setCrosshair(pos);
|
|
||||||
crosshair.locked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.unlockCrosshair = function unlockCrosshair() {
|
|
||||||
crosshair.locked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMouseOut(e) {
|
|
||||||
if (crosshair.locked)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (crosshair.x != -1) {
|
|
||||||
crosshair.x = -1;
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMouseMove(e) {
|
|
||||||
if (crosshair.locked)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (plot.getSelection && plot.getSelection()) {
|
|
||||||
crosshair.x = -1; // hide the crosshair while selecting
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var offset = plot.offset();
|
|
||||||
crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));
|
|
||||||
crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.hooks.bindEvents.push(function (plot, eventHolder) {
|
|
||||||
if (!plot.getOptions().crosshair.mode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
eventHolder.mouseout(onMouseOut);
|
|
||||||
eventHolder.mousemove(onMouseMove);
|
|
||||||
});
|
|
||||||
|
|
||||||
plot.hooks.drawOverlay.push(function (plot, ctx) {
|
|
||||||
var c = plot.getOptions().crosshair;
|
|
||||||
if (!c.mode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var plotOffset = plot.getPlotOffset();
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate(plotOffset.left, plotOffset.top);
|
|
||||||
|
|
||||||
if (crosshair.x != -1) {
|
|
||||||
ctx.strokeStyle = c.color;
|
|
||||||
ctx.lineWidth = c.lineWidth;
|
|
||||||
ctx.lineJoin = "round";
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
if (c.mode.indexOf("x") != -1) {
|
|
||||||
ctx.moveTo(crosshair.x, 0);
|
|
||||||
ctx.lineTo(crosshair.x, plot.height());
|
|
||||||
}
|
|
||||||
if (c.mode.indexOf("y") != -1) {
|
|
||||||
ctx.moveTo(0, crosshair.y);
|
|
||||||
ctx.lineTo(plot.width(), crosshair.y);
|
|
||||||
}
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
ctx.restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
plot.hooks.shutdown.push(function (plot, eventHolder) {
|
|
||||||
eventHolder.unbind("mouseout", onMouseOut);
|
|
||||||
eventHolder.unbind("mousemove", onMouseMove);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$.plot.plugins.push({
|
|
||||||
init: init,
|
|
||||||
options: options,
|
|
||||||
name: 'crosshair',
|
|
||||||
version: '1.0'
|
|
||||||
});
|
|
||||||
})(jQuery);
|
|
|
@ -1,183 +0,0 @@
|
||||||
/*
|
|
||||||
Flot plugin for computing bottoms for filled line and bar charts.
|
|
||||||
|
|
||||||
The case: you've got two series that you want to fill the area
|
|
||||||
between. In Flot terms, you need to use one as the fill bottom of the
|
|
||||||
other. You can specify the bottom of each data point as the third
|
|
||||||
coordinate manually, or you can use this plugin to compute it for you.
|
|
||||||
|
|
||||||
In order to name the other series, you need to give it an id, like this
|
|
||||||
|
|
||||||
var dataset = [
|
|
||||||
{ data: [ ... ], id: "foo" } , // use default bottom
|
|
||||||
{ data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
|
|
||||||
];
|
|
||||||
|
|
||||||
$.plot($("#placeholder"), dataset, { line: { show: true, fill: true }});
|
|
||||||
|
|
||||||
As a convenience, if the id given is a number that doesn't appear as
|
|
||||||
an id in the series, it is interpreted as the index in the array
|
|
||||||
instead (so fillBetween: 0 can also mean the first series).
|
|
||||||
|
|
||||||
Internally, the plugin modifies the datapoints in each series. For
|
|
||||||
line series, extra data points might be inserted through
|
|
||||||
interpolation. Note that at points where the bottom line is not
|
|
||||||
defined (due to a null point or start/end of line), the current line
|
|
||||||
will show a gap too. The algorithm comes from the jquery.flot.stack.js
|
|
||||||
plugin, possibly some code could be shared.
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function ($) {
|
|
||||||
var options = {
|
|
||||||
series: { fillBetween: null } // or number
|
|
||||||
};
|
|
||||||
|
|
||||||
function init(plot) {
|
|
||||||
function findBottomSeries(s, allseries) {
|
|
||||||
var i;
|
|
||||||
for (i = 0; i < allseries.length; ++i) {
|
|
||||||
if (allseries[i].id == s.fillBetween)
|
|
||||||
return allseries[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof s.fillBetween == "number") {
|
|
||||||
i = s.fillBetween;
|
|
||||||
|
|
||||||
if (i < 0 || i >= allseries.length)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return allseries[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function computeFillBottoms(plot, s, datapoints) {
|
|
||||||
if (s.fillBetween == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var other = findBottomSeries(s, plot.getData());
|
|
||||||
if (!other)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var ps = datapoints.pointsize,
|
|
||||||
points = datapoints.points,
|
|
||||||
otherps = other.datapoints.pointsize,
|
|
||||||
otherpoints = other.datapoints.points,
|
|
||||||
newpoints = [],
|
|
||||||
px, py, intery, qx, qy, bottom,
|
|
||||||
withlines = s.lines.show,
|
|
||||||
withbottom = ps > 2 && datapoints.format[2].y,
|
|
||||||
withsteps = withlines && s.lines.steps,
|
|
||||||
fromgap = true,
|
|
||||||
i = 0, j = 0, l;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (i >= points.length)
|
|
||||||
break;
|
|
||||||
|
|
||||||
l = newpoints.length;
|
|
||||||
|
|
||||||
if (points[i] == null) {
|
|
||||||
// copy gaps
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
i += ps;
|
|
||||||
}
|
|
||||||
else if (j >= otherpoints.length) {
|
|
||||||
// for lines, we can't use the rest of the points
|
|
||||||
if (!withlines) {
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
}
|
|
||||||
i += ps;
|
|
||||||
}
|
|
||||||
else if (otherpoints[j] == null) {
|
|
||||||
// oops, got a gap
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(null);
|
|
||||||
fromgap = true;
|
|
||||||
j += otherps;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// cases where we actually got two points
|
|
||||||
px = points[i];
|
|
||||||
py = points[i + 1];
|
|
||||||
qx = otherpoints[j];
|
|
||||||
qy = otherpoints[j + 1];
|
|
||||||
bottom = 0;
|
|
||||||
|
|
||||||
if (px == qx) {
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
|
|
||||||
//newpoints[l + 1] += qy;
|
|
||||||
bottom = qy;
|
|
||||||
|
|
||||||
i += ps;
|
|
||||||
j += otherps;
|
|
||||||
}
|
|
||||||
else if (px > qx) {
|
|
||||||
// we got past point below, might need to
|
|
||||||
// insert interpolated extra point
|
|
||||||
if (withlines && i > 0 && points[i - ps] != null) {
|
|
||||||
intery = py + (points[i - ps + 1] - py) * (qx - px) / (points[i - ps] - px);
|
|
||||||
newpoints.push(qx);
|
|
||||||
newpoints.push(intery)
|
|
||||||
for (m = 2; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
bottom = qy;
|
|
||||||
}
|
|
||||||
|
|
||||||
j += otherps;
|
|
||||||
}
|
|
||||||
else { // px < qx
|
|
||||||
if (fromgap && withlines) {
|
|
||||||
// if we come from a gap, we just skip this point
|
|
||||||
i += ps;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
|
|
||||||
// we might be able to interpolate a point below,
|
|
||||||
// this can give us a better y
|
|
||||||
if (withlines && j > 0 && otherpoints[j - otherps] != null)
|
|
||||||
bottom = qy + (otherpoints[j - otherps + 1] - qy) * (px - qx) / (otherpoints[j - otherps] - qx);
|
|
||||||
|
|
||||||
//newpoints[l + 1] += bottom;
|
|
||||||
|
|
||||||
i += ps;
|
|
||||||
}
|
|
||||||
|
|
||||||
fromgap = false;
|
|
||||||
|
|
||||||
if (l != newpoints.length && withbottom)
|
|
||||||
newpoints[l + 2] = bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
// maintain the line steps invariant
|
|
||||||
if (withsteps && l != newpoints.length && l > 0
|
|
||||||
&& newpoints[l] != null
|
|
||||||
&& newpoints[l] != newpoints[l - ps]
|
|
||||||
&& newpoints[l + 1] != newpoints[l - ps + 1]) {
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints[l + ps + m] = newpoints[l + m];
|
|
||||||
newpoints[l + 1] = newpoints[l - ps + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
datapoints.points = newpoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.hooks.processDatapoints.push(computeFillBottoms);
|
|
||||||
}
|
|
||||||
|
|
||||||
$.plot.plugins.push({
|
|
||||||
init: init,
|
|
||||||
options: options,
|
|
||||||
name: 'fillbetween',
|
|
||||||
version: '1.0'
|
|
||||||
});
|
|
||||||
})(jQuery);
|
|
|
@ -1,238 +0,0 @@
|
||||||
/*
|
|
||||||
Flot plugin for plotting images, e.g. useful for putting ticks on a
|
|
||||||
prerendered complex visualization.
|
|
||||||
|
|
||||||
The data syntax is [[image, x1, y1, x2, y2], ...] where (x1, y1) and
|
|
||||||
(x2, y2) are where you intend the two opposite corners of the image to
|
|
||||||
end up in the plot. Image must be a fully loaded Javascript image (you
|
|
||||||
can make one with new Image()). If the image is not complete, it's
|
|
||||||
skipped when plotting.
|
|
||||||
|
|
||||||
There are two helpers included for retrieving images. The easiest work
|
|
||||||
the way that you put in URLs instead of images in the data (like
|
|
||||||
["myimage.png", 0, 0, 10, 10]), then call $.plot.image.loadData(data,
|
|
||||||
options, callback) where data and options are the same as you pass in
|
|
||||||
to $.plot. This loads the images, replaces the URLs in the data with
|
|
||||||
the corresponding images and calls "callback" when all images are
|
|
||||||
loaded (or failed loading). In the callback, you can then call $.plot
|
|
||||||
with the data set. See the included example.
|
|
||||||
|
|
||||||
A more low-level helper, $.plot.image.load(urls, callback) is also
|
|
||||||
included. Given a list of URLs, it calls callback with an object
|
|
||||||
mapping from URL to Image object when all images are loaded or have
|
|
||||||
failed loading.
|
|
||||||
|
|
||||||
Options for the plugin are
|
|
||||||
|
|
||||||
series: {
|
|
||||||
images: {
|
|
||||||
show: boolean
|
|
||||||
anchor: "corner" or "center"
|
|
||||||
alpha: [0,1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
which can be specified for a specific series
|
|
||||||
|
|
||||||
$.plot($("#placeholder"), [{ data: [ ... ], images: { ... } ])
|
|
||||||
|
|
||||||
Note that because the data format is different from usual data points,
|
|
||||||
you can't use images with anything else in a specific data series.
|
|
||||||
|
|
||||||
Setting "anchor" to "center" causes the pixels in the image to be
|
|
||||||
anchored at the corner pixel centers inside of at the pixel corners,
|
|
||||||
effectively letting half a pixel stick out to each side in the plot.
|
|
||||||
|
|
||||||
|
|
||||||
A possible future direction could be support for tiling for large
|
|
||||||
images (like Google Maps).
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function ($) {
|
|
||||||
var options = {
|
|
||||||
series: {
|
|
||||||
images: {
|
|
||||||
show: false,
|
|
||||||
alpha: 1,
|
|
||||||
anchor: "corner" // or "center"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$.plot.image = {};
|
|
||||||
|
|
||||||
$.plot.image.loadDataImages = function (series, options, callback) {
|
|
||||||
var urls = [], points = [];
|
|
||||||
|
|
||||||
var defaultShow = options.series.images.show;
|
|
||||||
|
|
||||||
$.each(series, function (i, s) {
|
|
||||||
if (!(defaultShow || s.images.show))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (s.data)
|
|
||||||
s = s.data;
|
|
||||||
|
|
||||||
$.each(s, function (i, p) {
|
|
||||||
if (typeof p[0] == "string") {
|
|
||||||
urls.push(p[0]);
|
|
||||||
points.push(p);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$.plot.image.load(urls, function (loadedImages) {
|
|
||||||
$.each(points, function (i, p) {
|
|
||||||
var url = p[0];
|
|
||||||
if (loadedImages[url])
|
|
||||||
p[0] = loadedImages[url];
|
|
||||||
});
|
|
||||||
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$.plot.image.load = function (urls, callback) {
|
|
||||||
var missing = urls.length, loaded = {};
|
|
||||||
if (missing == 0)
|
|
||||||
callback({});
|
|
||||||
|
|
||||||
$.each(urls, function (i, url) {
|
|
||||||
var handler = function () {
|
|
||||||
--missing;
|
|
||||||
|
|
||||||
loaded[url] = this;
|
|
||||||
|
|
||||||
if (missing == 0)
|
|
||||||
callback(loaded);
|
|
||||||
};
|
|
||||||
|
|
||||||
$('<img />').load(handler).error(handler).attr('src', url);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawSeries(plot, ctx, series) {
|
|
||||||
var plotOffset = plot.getPlotOffset();
|
|
||||||
|
|
||||||
if (!series.images || !series.images.show)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var points = series.datapoints.points,
|
|
||||||
ps = series.datapoints.pointsize;
|
|
||||||
|
|
||||||
for (var i = 0; i < points.length; i += ps) {
|
|
||||||
var img = points[i],
|
|
||||||
x1 = points[i + 1], y1 = points[i + 2],
|
|
||||||
x2 = points[i + 3], y2 = points[i + 4],
|
|
||||||
xaxis = series.xaxis, yaxis = series.yaxis,
|
|
||||||
tmp;
|
|
||||||
|
|
||||||
// actually we should check img.complete, but it
|
|
||||||
// appears to be a somewhat unreliable indicator in
|
|
||||||
// IE6 (false even after load event)
|
|
||||||
if (!img || img.width <= 0 || img.height <= 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (x1 > x2) {
|
|
||||||
tmp = x2;
|
|
||||||
x2 = x1;
|
|
||||||
x1 = tmp;
|
|
||||||
}
|
|
||||||
if (y1 > y2) {
|
|
||||||
tmp = y2;
|
|
||||||
y2 = y1;
|
|
||||||
y1 = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the anchor is at the center of the pixel, expand the
|
|
||||||
// image by 1/2 pixel in each direction
|
|
||||||
if (series.images.anchor == "center") {
|
|
||||||
tmp = 0.5 * (x2-x1) / (img.width - 1);
|
|
||||||
x1 -= tmp;
|
|
||||||
x2 += tmp;
|
|
||||||
tmp = 0.5 * (y2-y1) / (img.height - 1);
|
|
||||||
y1 -= tmp;
|
|
||||||
y2 += tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// clip
|
|
||||||
if (x1 == x2 || y1 == y2 ||
|
|
||||||
x1 >= xaxis.max || x2 <= xaxis.min ||
|
|
||||||
y1 >= yaxis.max || y2 <= yaxis.min)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;
|
|
||||||
if (x1 < xaxis.min) {
|
|
||||||
sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);
|
|
||||||
x1 = xaxis.min;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x2 > xaxis.max) {
|
|
||||||
sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);
|
|
||||||
x2 = xaxis.max;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y1 < yaxis.min) {
|
|
||||||
sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);
|
|
||||||
y1 = yaxis.min;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y2 > yaxis.max) {
|
|
||||||
sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);
|
|
||||||
y2 = yaxis.max;
|
|
||||||
}
|
|
||||||
|
|
||||||
x1 = xaxis.p2c(x1);
|
|
||||||
x2 = xaxis.p2c(x2);
|
|
||||||
y1 = yaxis.p2c(y1);
|
|
||||||
y2 = yaxis.p2c(y2);
|
|
||||||
|
|
||||||
// the transformation may have swapped us
|
|
||||||
if (x1 > x2) {
|
|
||||||
tmp = x2;
|
|
||||||
x2 = x1;
|
|
||||||
x1 = tmp;
|
|
||||||
}
|
|
||||||
if (y1 > y2) {
|
|
||||||
tmp = y2;
|
|
||||||
y2 = y1;
|
|
||||||
y1 = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = ctx.globalAlpha;
|
|
||||||
ctx.globalAlpha *= series.images.alpha;
|
|
||||||
ctx.drawImage(img,
|
|
||||||
sx1, sy1, sx2 - sx1, sy2 - sy1,
|
|
||||||
x1 + plotOffset.left, y1 + plotOffset.top,
|
|
||||||
x2 - x1, y2 - y1);
|
|
||||||
ctx.globalAlpha = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function processRawData(plot, series, data, datapoints) {
|
|
||||||
if (!series.images.show)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// format is Image, x1, y1, x2, y2 (opposite corners)
|
|
||||||
datapoints.format = [
|
|
||||||
{ required: true },
|
|
||||||
{ x: true, number: true, required: true },
|
|
||||||
{ y: true, number: true, required: true },
|
|
||||||
{ x: true, number: true, required: true },
|
|
||||||
{ y: true, number: true, required: true }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
function init(plot) {
|
|
||||||
plot.hooks.processRawData.push(processRawData);
|
|
||||||
plot.hooks.drawSeries.push(drawSeries);
|
|
||||||
}
|
|
||||||
|
|
||||||
$.plot.plugins.push({
|
|
||||||
init: init,
|
|
||||||
options: options,
|
|
||||||
name: 'image',
|
|
||||||
version: '1.1'
|
|
||||||
});
|
|
||||||
})(jQuery);
|
|
|
@ -1,336 +0,0 @@
|
||||||
/*
|
|
||||||
Flot plugin for adding panning and zooming capabilities to a plot.
|
|
||||||
|
|
||||||
The default behaviour is double click and scrollwheel up/down to zoom
|
|
||||||
in, drag to pan. The plugin defines plot.zoom({ center }),
|
|
||||||
plot.zoomOut() and plot.pan(offset) so you easily can add custom
|
|
||||||
controls. It also fires a "plotpan" and "plotzoom" event when
|
|
||||||
something happens, useful for synchronizing plots.
|
|
||||||
|
|
||||||
Options:
|
|
||||||
|
|
||||||
zoom: {
|
|
||||||
interactive: false
|
|
||||||
trigger: "dblclick" // or "click" for single click
|
|
||||||
amount: 1.5 // 2 = 200% (zoom in), 0.5 = 50% (zoom out)
|
|
||||||
}
|
|
||||||
|
|
||||||
pan: {
|
|
||||||
interactive: false
|
|
||||||
cursor: "move" // CSS mouse cursor value used when dragging, e.g. "pointer"
|
|
||||||
frameRate: 20
|
|
||||||
}
|
|
||||||
|
|
||||||
xaxis, yaxis, x2axis, y2axis: {
|
|
||||||
zoomRange: null // or [number, number] (min range, max range) or false
|
|
||||||
panRange: null // or [number, number] (min, max) or false
|
|
||||||
}
|
|
||||||
|
|
||||||
"interactive" enables the built-in drag/click behaviour. If you enable
|
|
||||||
interactive for pan, then you'll have a basic plot that supports
|
|
||||||
moving around; the same for zoom.
|
|
||||||
|
|
||||||
"amount" specifies the default amount to zoom in (so 1.5 = 150%)
|
|
||||||
relative to the current viewport.
|
|
||||||
|
|
||||||
"cursor" is a standard CSS mouse cursor string used for visual
|
|
||||||
feedback to the user when dragging.
|
|
||||||
|
|
||||||
"frameRate" specifies the maximum number of times per second the plot
|
|
||||||
will update itself while the user is panning around on it (set to null
|
|
||||||
to disable intermediate pans, the plot will then not update until the
|
|
||||||
mouse button is released).
|
|
||||||
|
|
||||||
"zoomRange" is the interval in which zooming can happen, e.g. with
|
|
||||||
zoomRange: [1, 100] the zoom will never scale the axis so that the
|
|
||||||
difference between min and max is smaller than 1 or larger than 100.
|
|
||||||
You can set either end to null to ignore, e.g. [1, null]. If you set
|
|
||||||
zoomRange to false, zooming on that axis will be disabled.
|
|
||||||
|
|
||||||
"panRange" confines the panning to stay within a range, e.g. with
|
|
||||||
panRange: [-10, 20] panning stops at -10 in one end and at 20 in the
|
|
||||||
other. Either can be null, e.g. [-10, null]. If you set
|
|
||||||
panRange to false, panning on that axis will be disabled.
|
|
||||||
|
|
||||||
Example API usage:
|
|
||||||
|
|
||||||
plot = $.plot(...);
|
|
||||||
|
|
||||||
// zoom default amount in on the pixel (10, 20)
|
|
||||||
plot.zoom({ center: { left: 10, top: 20 } });
|
|
||||||
|
|
||||||
// zoom out again
|
|
||||||
plot.zoomOut({ center: { left: 10, top: 20 } });
|
|
||||||
|
|
||||||
// zoom 200% in on the pixel (10, 20)
|
|
||||||
plot.zoom({ amount: 2, center: { left: 10, top: 20 } });
|
|
||||||
|
|
||||||
// pan 100 pixels to the left and 20 down
|
|
||||||
plot.pan({ left: -100, top: 20 })
|
|
||||||
|
|
||||||
Here, "center" specifies where the center of the zooming should
|
|
||||||
happen. Note that this is defined in pixel space, not the space of the
|
|
||||||
data points (you can use the p2c helpers on the axes in Flot to help
|
|
||||||
you convert between these).
|
|
||||||
|
|
||||||
"amount" is the amount to zoom the viewport relative to the current
|
|
||||||
range, so 1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is
|
|
||||||
70% (zoom out). You can set the default in the options.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// First two dependencies, jquery.event.drag.js and
|
|
||||||
// jquery.mousewheel.js, we put them inline here to save people the
|
|
||||||
// effort of downloading them.
|
|
||||||
|
|
||||||
/*
|
|
||||||
jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
|
|
||||||
Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt
|
|
||||||
*/
|
|
||||||
(function(E){E.fn.drag=function(L,K,J){if(K){this.bind("dragstart",L)}if(J){this.bind("dragend",J)}return !L?this.trigger("drag"):this.bind("drag",K?K:L)};var A=E.event,B=A.special,F=B.drag={not:":input",distance:0,which:1,dragging:false,setup:function(J){J=E.extend({distance:F.distance,which:F.which,not:F.not},J||{});J.distance=I(J.distance);A.add(this,"mousedown",H,J);if(this.attachEvent){this.attachEvent("ondragstart",D)}},teardown:function(){A.remove(this,"mousedown",H);if(this===F.dragging){F.dragging=F.proxy=false}G(this,true);if(this.detachEvent){this.detachEvent("ondragstart",D)}}};B.dragstart=B.dragend={setup:function(){},teardown:function(){}};function H(L){var K=this,J,M=L.data||{};if(M.elem){K=L.dragTarget=M.elem;L.dragProxy=F.proxy||K;L.cursorOffsetX=M.pageX-M.left;L.cursorOffsetY=M.pageY-M.top;L.offsetX=L.pageX-L.cursorOffsetX;L.offsetY=L.pageY-L.cursorOffsetY}else{if(F.dragging||(M.which>0&&L.which!=M.which)||E(L.target).is(M.not)){return }}switch(L.type){case"mousedown":E.extend(M,E(K).offset(),{elem:K,target:L.target,pageX:L.pageX,pageY:L.pageY});A.add(document,"mousemove mouseup",H,M);G(K,false);F.dragging=null;return false;case !F.dragging&&"mousemove":if(I(L.pageX-M.pageX)+I(L.pageY-M.pageY)<M.distance){break}L.target=M.target;J=C(L,"dragstart",K);if(J!==false){F.dragging=K;F.proxy=L.dragProxy=E(J||K)[0]}case"mousemove":if(F.dragging){J=C(L,"drag",K);if(B.drop){B.drop.allowed=(J!==false);B.drop.handler(L)}if(J!==false){break}L.type="mouseup"}case"mouseup":A.remove(document,"mousemove mouseup",H);if(F.dragging){if(B.drop){B.drop.handler(L)}C(L,"dragend",K)}G(K,true);F.dragging=F.proxy=M.elem=false;break}return true}function C(M,K,L){M.type=K;var J=E.event.handle.call(L,M);return J===false?false:J||M.result}function I(J){return Math.pow(J,2)}function D(){return(F.dragging===false)}function G(K,J){if(!K){return }K.unselectable=J?"off":"on";K.onselectstart=function(){return J};if(K.style){K.style.MozUserSelect=J?"":"none"}}})(jQuery);
|
|
||||||
|
|
||||||
|
|
||||||
/* jquery.mousewheel.min.js
|
|
||||||
* Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
|
|
||||||
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
|
||||||
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
|
|
||||||
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
|
|
||||||
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
|
|
||||||
*
|
|
||||||
* Version: 3.0.2
|
|
||||||
*
|
|
||||||
* Requires: 1.2.2+
|
|
||||||
*/
|
|
||||||
(function(c){var a=["DOMMouseScroll","mousewheel"];c.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var d=a.length;d;){this.addEventListener(a[--d],b,false)}}else{this.onmousewheel=b}},teardown:function(){if(this.removeEventListener){for(var d=a.length;d;){this.removeEventListener(a[--d],b,false)}}else{this.onmousewheel=null}}};c.fn.extend({mousewheel:function(d){return d?this.bind("mousewheel",d):this.trigger("mousewheel")},unmousewheel:function(d){return this.unbind("mousewheel",d)}});function b(f){var d=[].slice.call(arguments,1),g=0,e=true;f=c.event.fix(f||window.event);f.type="mousewheel";if(f.wheelDelta){g=f.wheelDelta/120}if(f.detail){g=-f.detail/3}d.unshift(f,g);return c.event.handle.apply(this,d)}})(jQuery);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(function ($) {
|
|
||||||
var options = {
|
|
||||||
xaxis: {
|
|
||||||
zoomRange: null, // or [number, number] (min range, max range)
|
|
||||||
panRange: null // or [number, number] (min, max)
|
|
||||||
},
|
|
||||||
zoom: {
|
|
||||||
interactive: false,
|
|
||||||
trigger: "dblclick", // or "click" for single click
|
|
||||||
amount: 1.5 // how much to zoom relative to current position, 2 = 200% (zoom in), 0.5 = 50% (zoom out)
|
|
||||||
},
|
|
||||||
pan: {
|
|
||||||
interactive: false,
|
|
||||||
cursor: "move",
|
|
||||||
frameRate: 20
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function init(plot) {
|
|
||||||
function onZoomClick(e, zoomOut) {
|
|
||||||
var c = plot.offset();
|
|
||||||
c.left = e.pageX - c.left;
|
|
||||||
c.top = e.pageY - c.top;
|
|
||||||
if (zoomOut)
|
|
||||||
plot.zoomOut({ center: c });
|
|
||||||
else
|
|
||||||
plot.zoom({ center: c });
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMouseWheel(e, delta) {
|
|
||||||
onZoomClick(e, delta < 0);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var prevCursor = 'default', prevPageX = 0, prevPageY = 0,
|
|
||||||
panTimeout = null;
|
|
||||||
|
|
||||||
function onDragStart(e) {
|
|
||||||
if (e.which != 1) // only accept left-click
|
|
||||||
return false;
|
|
||||||
var c = plot.getPlaceholder().css('cursor');
|
|
||||||
if (c)
|
|
||||||
prevCursor = c;
|
|
||||||
plot.getPlaceholder().css('cursor', plot.getOptions().pan.cursor);
|
|
||||||
prevPageX = e.pageX;
|
|
||||||
prevPageY = e.pageY;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDrag(e) {
|
|
||||||
var frameRate = plot.getOptions().pan.frameRate;
|
|
||||||
if (panTimeout || !frameRate)
|
|
||||||
return;
|
|
||||||
|
|
||||||
panTimeout = setTimeout(function () {
|
|
||||||
plot.pan({ left: prevPageX - e.pageX,
|
|
||||||
top: prevPageY - e.pageY });
|
|
||||||
prevPageX = e.pageX;
|
|
||||||
prevPageY = e.pageY;
|
|
||||||
|
|
||||||
panTimeout = null;
|
|
||||||
}, 1 / frameRate * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDragEnd(e) {
|
|
||||||
if (panTimeout) {
|
|
||||||
clearTimeout(panTimeout);
|
|
||||||
panTimeout = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.getPlaceholder().css('cursor', prevCursor);
|
|
||||||
plot.pan({ left: prevPageX - e.pageX,
|
|
||||||
top: prevPageY - e.pageY });
|
|
||||||
}
|
|
||||||
|
|
||||||
function bindEvents(plot, eventHolder) {
|
|
||||||
var o = plot.getOptions();
|
|
||||||
if (o.zoom.interactive) {
|
|
||||||
eventHolder[o.zoom.trigger](onZoomClick);
|
|
||||||
eventHolder.mousewheel(onMouseWheel);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o.pan.interactive) {
|
|
||||||
eventHolder.bind("dragstart", { distance: 10 }, onDragStart);
|
|
||||||
eventHolder.bind("drag", onDrag);
|
|
||||||
eventHolder.bind("dragend", onDragEnd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.zoomOut = function (args) {
|
|
||||||
if (!args)
|
|
||||||
args = {};
|
|
||||||
|
|
||||||
if (!args.amount)
|
|
||||||
args.amount = plot.getOptions().zoom.amount
|
|
||||||
|
|
||||||
args.amount = 1 / args.amount;
|
|
||||||
plot.zoom(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.zoom = function (args) {
|
|
||||||
if (!args)
|
|
||||||
args = {};
|
|
||||||
|
|
||||||
var c = args.center,
|
|
||||||
amount = args.amount || plot.getOptions().zoom.amount,
|
|
||||||
w = plot.width(), h = plot.height();
|
|
||||||
|
|
||||||
if (!c)
|
|
||||||
c = { left: w / 2, top: h / 2 };
|
|
||||||
|
|
||||||
var xf = c.left / w,
|
|
||||||
yf = c.top / h,
|
|
||||||
minmax = {
|
|
||||||
x: {
|
|
||||||
min: c.left - xf * w / amount,
|
|
||||||
max: c.left + (1 - xf) * w / amount
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
min: c.top - yf * h / amount,
|
|
||||||
max: c.top + (1 - yf) * h / amount
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$.each(plot.getAxes(), function(_, axis) {
|
|
||||||
var opts = axis.options,
|
|
||||||
min = minmax[axis.direction].min,
|
|
||||||
max = minmax[axis.direction].max,
|
|
||||||
zr = opts.zoomRange;
|
|
||||||
|
|
||||||
if (zr === false) // no zooming on this axis
|
|
||||||
return;
|
|
||||||
|
|
||||||
min = axis.c2p(min);
|
|
||||||
max = axis.c2p(max);
|
|
||||||
if (min > max) {
|
|
||||||
// make sure min < max
|
|
||||||
var tmp = min;
|
|
||||||
min = max;
|
|
||||||
max = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
var range = max - min;
|
|
||||||
if (zr &&
|
|
||||||
((zr[0] != null && range < zr[0]) ||
|
|
||||||
(zr[1] != null && range > zr[1])))
|
|
||||||
return;
|
|
||||||
|
|
||||||
opts.min = min;
|
|
||||||
opts.max = max;
|
|
||||||
});
|
|
||||||
|
|
||||||
plot.setupGrid();
|
|
||||||
plot.draw();
|
|
||||||
|
|
||||||
if (!args.preventEvent)
|
|
||||||
plot.getPlaceholder().trigger("plotzoom", [ plot ]);
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.pan = function (args) {
|
|
||||||
var delta = {
|
|
||||||
x: +args.left,
|
|
||||||
y: +args.top
|
|
||||||
};
|
|
||||||
|
|
||||||
if (isNaN(delta.x))
|
|
||||||
delta.x = 0;
|
|
||||||
if (isNaN(delta.y))
|
|
||||||
delta.y = 0;
|
|
||||||
|
|
||||||
$.each(plot.getAxes(), function (_, axis) {
|
|
||||||
var opts = axis.options,
|
|
||||||
min, max, d = delta[axis.direction];
|
|
||||||
|
|
||||||
min = axis.c2p(axis.p2c(axis.min) + d),
|
|
||||||
max = axis.c2p(axis.p2c(axis.max) + d);
|
|
||||||
|
|
||||||
var pr = opts.panRange;
|
|
||||||
if (pr === false) // no panning on this axis
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (pr) {
|
|
||||||
// check whether we hit the wall
|
|
||||||
if (pr[0] != null && pr[0] > min) {
|
|
||||||
d = pr[0] - min;
|
|
||||||
min += d;
|
|
||||||
max += d;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pr[1] != null && pr[1] < max) {
|
|
||||||
d = pr[1] - max;
|
|
||||||
min += d;
|
|
||||||
max += d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
opts.min = min;
|
|
||||||
opts.max = max;
|
|
||||||
});
|
|
||||||
|
|
||||||
plot.setupGrid();
|
|
||||||
plot.draw();
|
|
||||||
|
|
||||||
if (!args.preventEvent)
|
|
||||||
plot.getPlaceholder().trigger("plotpan", [ plot ]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function shutdown(plot, eventHolder) {
|
|
||||||
eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick);
|
|
||||||
eventHolder.unbind("mousewheel", onMouseWheel);
|
|
||||||
eventHolder.unbind("dragstart", onDragStart);
|
|
||||||
eventHolder.unbind("drag", onDrag);
|
|
||||||
eventHolder.unbind("dragend", onDragEnd);
|
|
||||||
if (panTimeout)
|
|
||||||
clearTimeout(panTimeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.hooks.bindEvents.push(bindEvents);
|
|
||||||
plot.hooks.shutdown.push(shutdown);
|
|
||||||
}
|
|
||||||
|
|
||||||
$.plot.plugins.push({
|
|
||||||
init: init,
|
|
||||||
options: options,
|
|
||||||
name: 'navigate',
|
|
||||||
version: '1.3'
|
|
||||||
});
|
|
||||||
})(jQuery);
|
|
|
@ -1,750 +0,0 @@
|
||||||
/*
|
|
||||||
Flot plugin for rendering pie charts. The plugin assumes the data is
|
|
||||||
coming is as a single data value for each series, and each of those
|
|
||||||
values is a positive value or zero (negative numbers don't make
|
|
||||||
any sense and will cause strange effects). The data values do
|
|
||||||
NOT need to be passed in as percentage values because it
|
|
||||||
internally calculates the total and percentages.
|
|
||||||
|
|
||||||
* Created by Brian Medendorp, June 2009
|
|
||||||
* Updated November 2009 with contributions from: btburnett3, Anthony Aragues and Xavi Ivars
|
|
||||||
|
|
||||||
* Changes:
|
|
||||||
2009-10-22: lineJoin set to round
|
|
||||||
2009-10-23: IE full circle fix, donut
|
|
||||||
2009-11-11: Added basic hover from btburnett3 - does not work in IE, and center is off in Chrome and Opera
|
|
||||||
2009-11-17: Added IE hover capability submitted by Anthony Aragues
|
|
||||||
2009-11-18: Added bug fix submitted by Xavi Ivars (issues with arrays when other JS libraries are included as well)
|
|
||||||
|
|
||||||
|
|
||||||
Available options are:
|
|
||||||
series: {
|
|
||||||
pie: {
|
|
||||||
show: true/false
|
|
||||||
radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
|
|
||||||
innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
|
|
||||||
startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
|
|
||||||
tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
|
|
||||||
offset: {
|
|
||||||
top: integer value to move the pie up or down
|
|
||||||
left: integer value to move the pie left or right, or 'auto'
|
|
||||||
},
|
|
||||||
stroke: {
|
|
||||||
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
|
|
||||||
width: integer pixel width of the stroke
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
show: true/false, or 'auto'
|
|
||||||
formatter: a user-defined function that modifies the text/style of the label text
|
|
||||||
radius: 0-1 for percentage of fullsize, or a specified pixel length
|
|
||||||
background: {
|
|
||||||
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')
|
|
||||||
opacity: 0-1
|
|
||||||
},
|
|
||||||
threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
|
|
||||||
},
|
|
||||||
combine: {
|
|
||||||
threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
|
|
||||||
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
|
|
||||||
label: any text value of what the combined slice should be labeled
|
|
||||||
}
|
|
||||||
highlight: {
|
|
||||||
opacity: 0-1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
More detail and specific examples can be found in the included HTML file.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function ($)
|
|
||||||
{
|
|
||||||
function init(plot) // this is the "body" of the plugin
|
|
||||||
{
|
|
||||||
var canvas = null;
|
|
||||||
var target = null;
|
|
||||||
var maxRadius = null;
|
|
||||||
var centerLeft = null;
|
|
||||||
var centerTop = null;
|
|
||||||
var total = 0;
|
|
||||||
var redraw = true;
|
|
||||||
var redrawAttempts = 10;
|
|
||||||
var shrink = 0.95;
|
|
||||||
var legendWidth = 0;
|
|
||||||
var processed = false;
|
|
||||||
var raw = false;
|
|
||||||
|
|
||||||
// interactive variables
|
|
||||||
var highlights = [];
|
|
||||||
|
|
||||||
// add hook to determine if pie plugin in enabled, and then perform necessary operations
|
|
||||||
plot.hooks.processOptions.push(checkPieEnabled);
|
|
||||||
plot.hooks.bindEvents.push(bindEvents);
|
|
||||||
|
|
||||||
// check to see if the pie plugin is enabled
|
|
||||||
function checkPieEnabled(plot, options)
|
|
||||||
{
|
|
||||||
if (options.series.pie.show)
|
|
||||||
{
|
|
||||||
//disable grid
|
|
||||||
options.grid.show = false;
|
|
||||||
|
|
||||||
// set labels.show
|
|
||||||
if (options.series.pie.label.show=='auto')
|
|
||||||
if (options.legend.show)
|
|
||||||
options.series.pie.label.show = false;
|
|
||||||
else
|
|
||||||
options.series.pie.label.show = true;
|
|
||||||
|
|
||||||
// set radius
|
|
||||||
if (options.series.pie.radius=='auto')
|
|
||||||
if (options.series.pie.label.show)
|
|
||||||
options.series.pie.radius = 3/4;
|
|
||||||
else
|
|
||||||
options.series.pie.radius = 1;
|
|
||||||
|
|
||||||
// ensure sane tilt
|
|
||||||
if (options.series.pie.tilt>1)
|
|
||||||
options.series.pie.tilt=1;
|
|
||||||
if (options.series.pie.tilt<0)
|
|
||||||
options.series.pie.tilt=0;
|
|
||||||
|
|
||||||
// add processData hook to do transformations on the data
|
|
||||||
plot.hooks.processDatapoints.push(processDatapoints);
|
|
||||||
plot.hooks.drawOverlay.push(drawOverlay);
|
|
||||||
|
|
||||||
// add draw hook
|
|
||||||
plot.hooks.draw.push(draw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// bind hoverable events
|
|
||||||
function bindEvents(plot, eventHolder)
|
|
||||||
{
|
|
||||||
var options = plot.getOptions();
|
|
||||||
|
|
||||||
if (options.series.pie.show && options.grid.hoverable)
|
|
||||||
eventHolder.unbind('mousemove').mousemove(onMouseMove);
|
|
||||||
|
|
||||||
if (options.series.pie.show && options.grid.clickable)
|
|
||||||
eventHolder.unbind('click').click(onClick);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// debugging function that prints out an object
|
|
||||||
function alertObject(obj)
|
|
||||||
{
|
|
||||||
var msg = '';
|
|
||||||
function traverse(obj, depth)
|
|
||||||
{
|
|
||||||
if (!depth)
|
|
||||||
depth = 0;
|
|
||||||
for (var i = 0; i < obj.length; ++i)
|
|
||||||
{
|
|
||||||
for (var j=0; j<depth; j++)
|
|
||||||
msg += '\t';
|
|
||||||
|
|
||||||
if( typeof obj[i] == "object")
|
|
||||||
{ // its an object
|
|
||||||
msg += ''+i+':\n';
|
|
||||||
traverse(obj[i], depth+1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // its a value
|
|
||||||
msg += ''+i+': '+obj[i]+'\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
traverse(obj);
|
|
||||||
alert(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
function calcTotal(data)
|
|
||||||
{
|
|
||||||
for (var i = 0; i < data.length; ++i)
|
|
||||||
{
|
|
||||||
var item = parseFloat(data[i].data[0][1]);
|
|
||||||
if (item)
|
|
||||||
total += item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function processDatapoints(plot, series, data, datapoints)
|
|
||||||
{
|
|
||||||
if (!processed)
|
|
||||||
{
|
|
||||||
processed = true;
|
|
||||||
|
|
||||||
canvas = plot.getCanvas();
|
|
||||||
target = $(canvas).parent();
|
|
||||||
options = plot.getOptions();
|
|
||||||
|
|
||||||
plot.setData(combine(plot.getData()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupPie()
|
|
||||||
{
|
|
||||||
legendWidth = target.children().filter('.legend').children().width();
|
|
||||||
|
|
||||||
// calculate maximum radius and center point
|
|
||||||
maxRadius = Math.min(canvas.width,(canvas.height/options.series.pie.tilt))/2;
|
|
||||||
centerTop = (canvas.height/2)+options.series.pie.offset.top;
|
|
||||||
centerLeft = (canvas.width/2);
|
|
||||||
|
|
||||||
if (options.series.pie.offset.left=='auto')
|
|
||||||
if (options.legend.position.match('w'))
|
|
||||||
centerLeft += legendWidth/2;
|
|
||||||
else
|
|
||||||
centerLeft -= legendWidth/2;
|
|
||||||
else
|
|
||||||
centerLeft += options.series.pie.offset.left;
|
|
||||||
|
|
||||||
if (centerLeft<maxRadius)
|
|
||||||
centerLeft = maxRadius;
|
|
||||||
else if (centerLeft>canvas.width-maxRadius)
|
|
||||||
centerLeft = canvas.width-maxRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fixData(data)
|
|
||||||
{
|
|
||||||
for (var i = 0; i < data.length; ++i)
|
|
||||||
{
|
|
||||||
if (typeof(data[i].data)=='number')
|
|
||||||
data[i].data = [[1,data[i].data]];
|
|
||||||
else if (typeof(data[i].data)=='undefined' || typeof(data[i].data[0])=='undefined')
|
|
||||||
{
|
|
||||||
if (typeof(data[i].data)!='undefined' && typeof(data[i].data.label)!='undefined')
|
|
||||||
data[i].label = data[i].data.label; // fix weirdness coming from flot
|
|
||||||
data[i].data = [[1,0]];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
function combine(data)
|
|
||||||
{
|
|
||||||
data = fixData(data);
|
|
||||||
calcTotal(data);
|
|
||||||
var combined = 0;
|
|
||||||
var numCombined = 0;
|
|
||||||
var color = options.series.pie.combine.color;
|
|
||||||
|
|
||||||
var newdata = [];
|
|
||||||
for (var i = 0; i < data.length; ++i)
|
|
||||||
{
|
|
||||||
// make sure its a number
|
|
||||||
data[i].data[0][1] = parseFloat(data[i].data[0][1]);
|
|
||||||
if (!data[i].data[0][1])
|
|
||||||
data[i].data[0][1] = 0;
|
|
||||||
|
|
||||||
if (data[i].data[0][1]/total<=options.series.pie.combine.threshold)
|
|
||||||
{
|
|
||||||
combined += data[i].data[0][1];
|
|
||||||
numCombined++;
|
|
||||||
if (!color)
|
|
||||||
color = data[i].color;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
newdata.push({
|
|
||||||
data: [[1,data[i].data[0][1]]],
|
|
||||||
color: data[i].color,
|
|
||||||
label: data[i].label,
|
|
||||||
angle: (data[i].data[0][1]*(Math.PI*2))/total,
|
|
||||||
percent: (data[i].data[0][1]/total*100)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (numCombined>0)
|
|
||||||
newdata.push({
|
|
||||||
data: [[1,combined]],
|
|
||||||
color: color,
|
|
||||||
label: options.series.pie.combine.label,
|
|
||||||
angle: (combined*(Math.PI*2))/total,
|
|
||||||
percent: (combined/total*100)
|
|
||||||
});
|
|
||||||
return newdata;
|
|
||||||
}
|
|
||||||
|
|
||||||
function draw(plot, newCtx)
|
|
||||||
{
|
|
||||||
if (!target) return; // if no series were passed
|
|
||||||
ctx = newCtx;
|
|
||||||
|
|
||||||
setupPie();
|
|
||||||
var slices = plot.getData();
|
|
||||||
|
|
||||||
var attempts = 0;
|
|
||||||
while (redraw && attempts<redrawAttempts)
|
|
||||||
{
|
|
||||||
redraw = false;
|
|
||||||
if (attempts>0)
|
|
||||||
maxRadius *= shrink;
|
|
||||||
attempts += 1;
|
|
||||||
clear();
|
|
||||||
if (options.series.pie.tilt<=0.8)
|
|
||||||
drawShadow();
|
|
||||||
drawPie();
|
|
||||||
}
|
|
||||||
if (attempts >= redrawAttempts) {
|
|
||||||
clear();
|
|
||||||
target.prepend('<div class="error">Could not draw pie with labels contained inside canvas</div>');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( plot.setSeries && plot.insertLegend )
|
|
||||||
{
|
|
||||||
plot.setSeries(slices);
|
|
||||||
plot.insertLegend();
|
|
||||||
}
|
|
||||||
|
|
||||||
// we're actually done at this point, just defining internal functions at this point
|
|
||||||
|
|
||||||
function clear()
|
|
||||||
{
|
|
||||||
ctx.clearRect(0,0,canvas.width,canvas.height);
|
|
||||||
target.children().filter('.pieLabel, .pieLabelBackground').remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawShadow()
|
|
||||||
{
|
|
||||||
var shadowLeft = 5;
|
|
||||||
var shadowTop = 15;
|
|
||||||
var edge = 10;
|
|
||||||
var alpha = 0.02;
|
|
||||||
|
|
||||||
// set radius
|
|
||||||
if (options.series.pie.radius>1)
|
|
||||||
var radius = options.series.pie.radius;
|
|
||||||
else
|
|
||||||
var radius = maxRadius * options.series.pie.radius;
|
|
||||||
|
|
||||||
if (radius>=(canvas.width/2)-shadowLeft || radius*options.series.pie.tilt>=(canvas.height/2)-shadowTop || radius<=edge)
|
|
||||||
return; // shadow would be outside canvas, so don't draw it
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate(shadowLeft,shadowTop);
|
|
||||||
ctx.globalAlpha = alpha;
|
|
||||||
ctx.fillStyle = '#000';
|
|
||||||
|
|
||||||
// center and rotate to starting position
|
|
||||||
ctx.translate(centerLeft,centerTop);
|
|
||||||
ctx.scale(1, options.series.pie.tilt);
|
|
||||||
|
|
||||||
//radius -= edge;
|
|
||||||
for (var i=1; i<=edge; i++)
|
|
||||||
{
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(0,0,radius,0,Math.PI*2,false);
|
|
||||||
ctx.fill();
|
|
||||||
radius -= i;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawPie()
|
|
||||||
{
|
|
||||||
startAngle = Math.PI*options.series.pie.startAngle;
|
|
||||||
|
|
||||||
// set radius
|
|
||||||
if (options.series.pie.radius>1)
|
|
||||||
var radius = options.series.pie.radius;
|
|
||||||
else
|
|
||||||
var radius = maxRadius * options.series.pie.radius;
|
|
||||||
|
|
||||||
// center and rotate to starting position
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate(centerLeft,centerTop);
|
|
||||||
ctx.scale(1, options.series.pie.tilt);
|
|
||||||
//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
|
|
||||||
|
|
||||||
// draw slices
|
|
||||||
ctx.save();
|
|
||||||
var currentAngle = startAngle;
|
|
||||||
for (var i = 0; i < slices.length; ++i)
|
|
||||||
{
|
|
||||||
slices[i].startAngle = currentAngle;
|
|
||||||
drawSlice(slices[i].angle, slices[i].color, true);
|
|
||||||
}
|
|
||||||
ctx.restore();
|
|
||||||
|
|
||||||
// draw slice outlines
|
|
||||||
ctx.save();
|
|
||||||
ctx.lineWidth = options.series.pie.stroke.width;
|
|
||||||
currentAngle = startAngle;
|
|
||||||
for (var i = 0; i < slices.length; ++i)
|
|
||||||
drawSlice(slices[i].angle, options.series.pie.stroke.color, false);
|
|
||||||
ctx.restore();
|
|
||||||
|
|
||||||
// draw donut hole
|
|
||||||
drawDonutHole(ctx);
|
|
||||||
|
|
||||||
// draw labels
|
|
||||||
if (options.series.pie.label.show)
|
|
||||||
drawLabels();
|
|
||||||
|
|
||||||
// restore to original state
|
|
||||||
ctx.restore();
|
|
||||||
|
|
||||||
function drawSlice(angle, color, fill)
|
|
||||||
{
|
|
||||||
if (angle<=0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (fill)
|
|
||||||
ctx.fillStyle = color;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ctx.strokeStyle = color;
|
|
||||||
ctx.lineJoin = 'round';
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
if (Math.abs(angle - Math.PI*2) > 0.000000001)
|
|
||||||
ctx.moveTo(0,0); // Center of the pie
|
|
||||||
else if ($.browser.msie)
|
|
||||||
angle -= 0.0001;
|
|
||||||
//ctx.arc(0,0,radius,0,angle,false); // This doesn't work properly in Opera
|
|
||||||
ctx.arc(0,0,radius,currentAngle,currentAngle+angle,false);
|
|
||||||
ctx.closePath();
|
|
||||||
//ctx.rotate(angle); // This doesn't work properly in Opera
|
|
||||||
currentAngle += angle;
|
|
||||||
|
|
||||||
if (fill)
|
|
||||||
ctx.fill();
|
|
||||||
else
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawLabels()
|
|
||||||
{
|
|
||||||
var currentAngle = startAngle;
|
|
||||||
|
|
||||||
// set radius
|
|
||||||
if (options.series.pie.label.radius>1)
|
|
||||||
var radius = options.series.pie.label.radius;
|
|
||||||
else
|
|
||||||
var radius = maxRadius * options.series.pie.label.radius;
|
|
||||||
|
|
||||||
for (var i = 0; i < slices.length; ++i)
|
|
||||||
{
|
|
||||||
if (slices[i].percent >= options.series.pie.label.threshold*100)
|
|
||||||
drawLabel(slices[i], currentAngle, i);
|
|
||||||
currentAngle += slices[i].angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawLabel(slice, startAngle, index)
|
|
||||||
{
|
|
||||||
if (slice.data[0][1]==0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// format label text
|
|
||||||
var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;
|
|
||||||
if (lf)
|
|
||||||
text = lf(slice.label, slice);
|
|
||||||
else
|
|
||||||
text = slice.label;
|
|
||||||
if (plf)
|
|
||||||
text = plf(text, slice);
|
|
||||||
|
|
||||||
var halfAngle = ((startAngle+slice.angle) + startAngle)/2;
|
|
||||||
var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
|
|
||||||
var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;
|
|
||||||
|
|
||||||
var html = '<span class="pieLabel" id="pieLabel'+index+'" style="position:absolute;top:' + y + 'px;left:' + x + 'px;">' + text + "</span>";
|
|
||||||
target.append(html);
|
|
||||||
var label = target.children('#pieLabel'+index);
|
|
||||||
var labelTop = (y - label.height()/2);
|
|
||||||
var labelLeft = (x - label.width()/2);
|
|
||||||
label.css('top', labelTop);
|
|
||||||
label.css('left', labelLeft);
|
|
||||||
|
|
||||||
// check to make sure that the label is not outside the canvas
|
|
||||||
if (0-labelTop>0 || 0-labelLeft>0 || canvas.height-(labelTop+label.height())<0 || canvas.width-(labelLeft+label.width())<0)
|
|
||||||
redraw = true;
|
|
||||||
|
|
||||||
if (options.series.pie.label.background.opacity != 0) {
|
|
||||||
// put in the transparent background separately to avoid blended labels and label boxes
|
|
||||||
var c = options.series.pie.label.background.color;
|
|
||||||
if (c == null) {
|
|
||||||
c = slice.color;
|
|
||||||
}
|
|
||||||
var pos = 'top:'+labelTop+'px;left:'+labelLeft+'px;';
|
|
||||||
$('<div class="pieLabelBackground" style="position:absolute;width:' + label.width() + 'px;height:' + label.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').insertBefore(label).css('opacity', options.series.pie.label.background.opacity);
|
|
||||||
}
|
|
||||||
} // end individual label function
|
|
||||||
} // end drawLabels function
|
|
||||||
} // end drawPie function
|
|
||||||
} // end draw function
|
|
||||||
|
|
||||||
// Placed here because it needs to be accessed from multiple locations
|
|
||||||
function drawDonutHole(layer)
|
|
||||||
{
|
|
||||||
// draw donut hole
|
|
||||||
if(options.series.pie.innerRadius > 0)
|
|
||||||
{
|
|
||||||
// subtract the center
|
|
||||||
layer.save();
|
|
||||||
innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;
|
|
||||||
layer.globalCompositeOperation = 'destination-out'; // this does not work with excanvas, but it will fall back to using the stroke color
|
|
||||||
layer.beginPath();
|
|
||||||
layer.fillStyle = options.series.pie.stroke.color;
|
|
||||||
layer.arc(0,0,innerRadius,0,Math.PI*2,false);
|
|
||||||
layer.fill();
|
|
||||||
layer.closePath();
|
|
||||||
layer.restore();
|
|
||||||
|
|
||||||
// add inner stroke
|
|
||||||
layer.save();
|
|
||||||
layer.beginPath();
|
|
||||||
layer.strokeStyle = options.series.pie.stroke.color;
|
|
||||||
layer.arc(0,0,innerRadius,0,Math.PI*2,false);
|
|
||||||
layer.stroke();
|
|
||||||
layer.closePath();
|
|
||||||
layer.restore();
|
|
||||||
// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-- Additional Interactive related functions --
|
|
||||||
|
|
||||||
function isPointInPoly(poly, pt)
|
|
||||||
{
|
|
||||||
for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
|
|
||||||
((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))
|
|
||||||
&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
|
|
||||||
&& (c = !c);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
function findNearbySlice(mouseX, mouseY)
|
|
||||||
{
|
|
||||||
var slices = plot.getData(),
|
|
||||||
options = plot.getOptions(),
|
|
||||||
radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
|
|
||||||
|
|
||||||
for (var i = 0; i < slices.length; ++i)
|
|
||||||
{
|
|
||||||
var s = slices[i];
|
|
||||||
|
|
||||||
if(s.pie.show)
|
|
||||||
{
|
|
||||||
ctx.save();
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(0,0); // Center of the pie
|
|
||||||
//ctx.scale(1, options.series.pie.tilt); // this actually seems to break everything when here.
|
|
||||||
ctx.arc(0,0,radius,s.startAngle,s.startAngle+s.angle,false);
|
|
||||||
ctx.closePath();
|
|
||||||
x = mouseX-centerLeft;
|
|
||||||
y = mouseY-centerTop;
|
|
||||||
if(ctx.isPointInPath)
|
|
||||||
{
|
|
||||||
if (ctx.isPointInPath(mouseX-centerLeft, mouseY-centerTop))
|
|
||||||
{
|
|
||||||
//alert('found slice!');
|
|
||||||
ctx.restore();
|
|
||||||
return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// excanvas for IE doesn;t support isPointInPath, this is a workaround.
|
|
||||||
p1X = (radius * Math.cos(s.startAngle));
|
|
||||||
p1Y = (radius * Math.sin(s.startAngle));
|
|
||||||
p2X = (radius * Math.cos(s.startAngle+(s.angle/4)));
|
|
||||||
p2Y = (radius * Math.sin(s.startAngle+(s.angle/4)));
|
|
||||||
p3X = (radius * Math.cos(s.startAngle+(s.angle/2)));
|
|
||||||
p3Y = (radius * Math.sin(s.startAngle+(s.angle/2)));
|
|
||||||
p4X = (radius * Math.cos(s.startAngle+(s.angle/1.5)));
|
|
||||||
p4Y = (radius * Math.sin(s.startAngle+(s.angle/1.5)));
|
|
||||||
p5X = (radius * Math.cos(s.startAngle+s.angle));
|
|
||||||
p5Y = (radius * Math.sin(s.startAngle+s.angle));
|
|
||||||
arrPoly = [[0,0],[p1X,p1Y],[p2X,p2Y],[p3X,p3Y],[p4X,p4Y],[p5X,p5Y]];
|
|
||||||
arrPoint = [x,y];
|
|
||||||
// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
|
|
||||||
if(isPointInPoly(arrPoly, arrPoint))
|
|
||||||
{
|
|
||||||
ctx.restore();
|
|
||||||
return {datapoint: [s.percent, s.data], dataIndex: 0, series: s, seriesIndex: i};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMouseMove(e)
|
|
||||||
{
|
|
||||||
triggerClickHoverEvent('plothover', e);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onClick(e)
|
|
||||||
{
|
|
||||||
triggerClickHoverEvent('plotclick', e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// trigger click or hover event (they send the same parameters so we share their code)
|
|
||||||
function triggerClickHoverEvent(eventname, e)
|
|
||||||
{
|
|
||||||
var offset = plot.offset(),
|
|
||||||
canvasX = parseInt(e.pageX - offset.left),
|
|
||||||
canvasY = parseInt(e.pageY - offset.top),
|
|
||||||
item = findNearbySlice(canvasX, canvasY);
|
|
||||||
|
|
||||||
if (options.grid.autoHighlight)
|
|
||||||
{
|
|
||||||
// clear auto-highlights
|
|
||||||
for (var i = 0; i < highlights.length; ++i)
|
|
||||||
{
|
|
||||||
var h = highlights[i];
|
|
||||||
if (h.auto == eventname && !(item && h.series == item.series))
|
|
||||||
unhighlight(h.series);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// highlight the slice
|
|
||||||
if (item)
|
|
||||||
highlight(item.series, eventname);
|
|
||||||
|
|
||||||
// trigger any hover bind events
|
|
||||||
var pos = { pageX: e.pageX, pageY: e.pageY };
|
|
||||||
target.trigger(eventname, [ pos, item ]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function highlight(s, auto)
|
|
||||||
{
|
|
||||||
if (typeof s == "number")
|
|
||||||
s = series[s];
|
|
||||||
|
|
||||||
var i = indexOfHighlight(s);
|
|
||||||
if (i == -1)
|
|
||||||
{
|
|
||||||
highlights.push({ series: s, auto: auto });
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
}
|
|
||||||
else if (!auto)
|
|
||||||
highlights[i].auto = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function unhighlight(s)
|
|
||||||
{
|
|
||||||
if (s == null)
|
|
||||||
{
|
|
||||||
highlights = [];
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof s == "number")
|
|
||||||
s = series[s];
|
|
||||||
|
|
||||||
var i = indexOfHighlight(s);
|
|
||||||
if (i != -1)
|
|
||||||
{
|
|
||||||
highlights.splice(i, 1);
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function indexOfHighlight(s)
|
|
||||||
{
|
|
||||||
for (var i = 0; i < highlights.length; ++i)
|
|
||||||
{
|
|
||||||
var h = highlights[i];
|
|
||||||
if (h.series == s)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawOverlay(plot, octx)
|
|
||||||
{
|
|
||||||
//alert(options.series.pie.radius);
|
|
||||||
var options = plot.getOptions();
|
|
||||||
//alert(options.series.pie.radius);
|
|
||||||
|
|
||||||
var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
|
|
||||||
|
|
||||||
octx.save();
|
|
||||||
octx.translate(centerLeft, centerTop);
|
|
||||||
octx.scale(1, options.series.pie.tilt);
|
|
||||||
|
|
||||||
for (i = 0; i < highlights.length; ++i)
|
|
||||||
drawHighlight(highlights[i].series);
|
|
||||||
|
|
||||||
drawDonutHole(octx);
|
|
||||||
|
|
||||||
octx.restore();
|
|
||||||
|
|
||||||
function drawHighlight(series)
|
|
||||||
{
|
|
||||||
if (series.angle < 0) return;
|
|
||||||
|
|
||||||
//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
|
|
||||||
octx.fillStyle = "rgba(255, 255, 255, "+options.series.pie.highlight.opacity+")"; // this is temporary until we have access to parseColor
|
|
||||||
|
|
||||||
octx.beginPath();
|
|
||||||
if (Math.abs(series.angle - Math.PI*2) > 0.000000001)
|
|
||||||
octx.moveTo(0,0); // Center of the pie
|
|
||||||
octx.arc(0,0,radius,series.startAngle,series.startAngle+series.angle,false);
|
|
||||||
octx.closePath();
|
|
||||||
octx.fill();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end init (plugin body)
|
|
||||||
|
|
||||||
// define pie specific options and their default values
|
|
||||||
var options = {
|
|
||||||
series: {
|
|
||||||
pie: {
|
|
||||||
show: false,
|
|
||||||
radius: 'auto', // actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
|
|
||||||
innerRadius:0, /* for donut */
|
|
||||||
startAngle: 3/2,
|
|
||||||
tilt: 1,
|
|
||||||
offset: {
|
|
||||||
top: 0,
|
|
||||||
left: 'auto'
|
|
||||||
},
|
|
||||||
stroke: {
|
|
||||||
color: '#FFF',
|
|
||||||
width: 1
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
show: 'auto',
|
|
||||||
formatter: function(label, slice){
|
|
||||||
return '<div style="font-size:x-small;text-align:center;padding:2px;color:'+slice.color+';">'+label+'<br/>'+Math.round(slice.percent)+'%</div>';
|
|
||||||
}, // formatter function
|
|
||||||
radius: 1, // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
|
|
||||||
background: {
|
|
||||||
color: null,
|
|
||||||
opacity: 0
|
|
||||||
},
|
|
||||||
threshold: 0 // percentage at which to hide the label (i.e. the slice is too narrow)
|
|
||||||
},
|
|
||||||
combine: {
|
|
||||||
threshold: -1, // percentage at which to combine little slices into one larger slice
|
|
||||||
color: null, // color to give the new slice (auto-generated if null)
|
|
||||||
label: 'Other' // label to give the new slice
|
|
||||||
},
|
|
||||||
highlight: {
|
|
||||||
//color: '#FFF', // will add this functionality once parseColor is available
|
|
||||||
opacity: 0.5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$.plot.plugins.push({
|
|
||||||
init: init,
|
|
||||||
options: options,
|
|
||||||
name: "pie",
|
|
||||||
version: "1.0"
|
|
||||||
});
|
|
||||||
})(jQuery);
|
|
|
@ -1,344 +0,0 @@
|
||||||
/*
|
|
||||||
Flot plugin for selecting regions.
|
|
||||||
|
|
||||||
The plugin defines the following options:
|
|
||||||
|
|
||||||
selection: {
|
|
||||||
mode: null or "x" or "y" or "xy",
|
|
||||||
color: color
|
|
||||||
}
|
|
||||||
|
|
||||||
Selection support is enabled by setting the mode to one of "x", "y" or
|
|
||||||
"xy". In "x" mode, the user will only be able to specify the x range,
|
|
||||||
similarly for "y" mode. For "xy", the selection becomes a rectangle
|
|
||||||
where both ranges can be specified. "color" is color of the selection
|
|
||||||
(if you need to change the color later on, you can get to it with
|
|
||||||
plot.getOptions().selection.color).
|
|
||||||
|
|
||||||
When selection support is enabled, a "plotselected" event will be
|
|
||||||
emitted on the DOM element you passed into the plot function. The
|
|
||||||
event handler gets a parameter with the ranges selected on the axes,
|
|
||||||
like this:
|
|
||||||
|
|
||||||
placeholder.bind("plotselected", function(event, ranges) {
|
|
||||||
alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
|
|
||||||
// similar for yaxis - with multiple axes, the extra ones are in
|
|
||||||
// x2axis, x3axis, ...
|
|
||||||
});
|
|
||||||
|
|
||||||
The "plotselected" event is only fired when the user has finished
|
|
||||||
making the selection. A "plotselecting" event is fired during the
|
|
||||||
process with the same parameters as the "plotselected" event, in case
|
|
||||||
you want to know what's happening while it's happening,
|
|
||||||
|
|
||||||
A "plotunselected" event with no arguments is emitted when the user
|
|
||||||
clicks the mouse to remove the selection.
|
|
||||||
|
|
||||||
The plugin allso adds the following methods to the plot object:
|
|
||||||
|
|
||||||
- setSelection(ranges, preventEvent)
|
|
||||||
|
|
||||||
Set the selection rectangle. The passed in ranges is on the same
|
|
||||||
form as returned in the "plotselected" event. If the selection mode
|
|
||||||
is "x", you should put in either an xaxis range, if the mode is "y"
|
|
||||||
you need to put in an yaxis range and both xaxis and yaxis if the
|
|
||||||
selection mode is "xy", like this:
|
|
||||||
|
|
||||||
setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
|
|
||||||
|
|
||||||
setSelection will trigger the "plotselected" event when called. If
|
|
||||||
you don't want that to happen, e.g. if you're inside a
|
|
||||||
"plotselected" handler, pass true as the second parameter. If you
|
|
||||||
are using multiple axes, you can specify the ranges on any of those,
|
|
||||||
e.g. as x2axis/x3axis/... instead of xaxis, the plugin picks the
|
|
||||||
first one it sees.
|
|
||||||
|
|
||||||
- clearSelection(preventEvent)
|
|
||||||
|
|
||||||
Clear the selection rectangle. Pass in true to avoid getting a
|
|
||||||
"plotunselected" event.
|
|
||||||
|
|
||||||
- getSelection()
|
|
||||||
|
|
||||||
Returns the current selection in the same format as the
|
|
||||||
"plotselected" event. If there's currently no selection, the
|
|
||||||
function returns null.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function ($) {
|
|
||||||
function init(plot) {
|
|
||||||
var selection = {
|
|
||||||
first: { x: -1, y: -1}, second: { x: -1, y: -1},
|
|
||||||
show: false,
|
|
||||||
active: false
|
|
||||||
};
|
|
||||||
|
|
||||||
// FIXME: The drag handling implemented here should be
|
|
||||||
// abstracted out, there's some similar code from a library in
|
|
||||||
// the navigation plugin, this should be massaged a bit to fit
|
|
||||||
// the Flot cases here better and reused. Doing this would
|
|
||||||
// make this plugin much slimmer.
|
|
||||||
var savedhandlers = {};
|
|
||||||
|
|
||||||
var mouseUpHandler = null;
|
|
||||||
|
|
||||||
function onMouseMove(e) {
|
|
||||||
if (selection.active) {
|
|
||||||
updateSelection(e);
|
|
||||||
|
|
||||||
plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMouseDown(e) {
|
|
||||||
if (e.which != 1) // only accept left-click
|
|
||||||
return;
|
|
||||||
|
|
||||||
// cancel out any text selections
|
|
||||||
document.body.focus();
|
|
||||||
|
|
||||||
// prevent text selection and drag in old-school browsers
|
|
||||||
if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {
|
|
||||||
savedhandlers.onselectstart = document.onselectstart;
|
|
||||||
document.onselectstart = function () { return false; };
|
|
||||||
}
|
|
||||||
if (document.ondrag !== undefined && savedhandlers.ondrag == null) {
|
|
||||||
savedhandlers.ondrag = document.ondrag;
|
|
||||||
document.ondrag = function () { return false; };
|
|
||||||
}
|
|
||||||
|
|
||||||
setSelectionPos(selection.first, e);
|
|
||||||
|
|
||||||
selection.active = true;
|
|
||||||
|
|
||||||
// this is a bit silly, but we have to use a closure to be
|
|
||||||
// able to whack the same handler again
|
|
||||||
mouseUpHandler = function (e) { onMouseUp(e); };
|
|
||||||
|
|
||||||
$(document).one("mouseup", mouseUpHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMouseUp(e) {
|
|
||||||
mouseUpHandler = null;
|
|
||||||
|
|
||||||
// revert drag stuff for old-school browsers
|
|
||||||
if (document.onselectstart !== undefined)
|
|
||||||
document.onselectstart = savedhandlers.onselectstart;
|
|
||||||
if (document.ondrag !== undefined)
|
|
||||||
document.ondrag = savedhandlers.ondrag;
|
|
||||||
|
|
||||||
// no more dragging
|
|
||||||
selection.active = false;
|
|
||||||
updateSelection(e);
|
|
||||||
|
|
||||||
if (selectionIsSane())
|
|
||||||
triggerSelectedEvent();
|
|
||||||
else {
|
|
||||||
// this counts as a clear
|
|
||||||
plot.getPlaceholder().trigger("plotunselected", [ ]);
|
|
||||||
plot.getPlaceholder().trigger("plotselecting", [ null ]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSelection() {
|
|
||||||
if (!selectionIsSane())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var r = {}, c1 = selection.first, c2 = selection.second;
|
|
||||||
$.each(plot.getAxes(), function (name, axis) {
|
|
||||||
if (axis.used) {
|
|
||||||
var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]);
|
|
||||||
r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
function triggerSelectedEvent() {
|
|
||||||
var r = getSelection();
|
|
||||||
|
|
||||||
plot.getPlaceholder().trigger("plotselected", [ r ]);
|
|
||||||
|
|
||||||
// backwards-compat stuff, to be removed in future
|
|
||||||
if (r.xaxis && r.yaxis)
|
|
||||||
plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function clamp(min, value, max) {
|
|
||||||
return value < min ? min: (value > max ? max: value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSelectionPos(pos, e) {
|
|
||||||
var o = plot.getOptions();
|
|
||||||
var offset = plot.getPlaceholder().offset();
|
|
||||||
var plotOffset = plot.getPlotOffset();
|
|
||||||
pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());
|
|
||||||
pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());
|
|
||||||
|
|
||||||
if (o.selection.mode == "y")
|
|
||||||
pos.x = pos == selection.first ? 0 : plot.width();
|
|
||||||
|
|
||||||
if (o.selection.mode == "x")
|
|
||||||
pos.y = pos == selection.first ? 0 : plot.height();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateSelection(pos) {
|
|
||||||
if (pos.pageX == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
setSelectionPos(selection.second, pos);
|
|
||||||
if (selectionIsSane()) {
|
|
||||||
selection.show = true;
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
clearSelection(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearSelection(preventEvent) {
|
|
||||||
if (selection.show) {
|
|
||||||
selection.show = false;
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
if (!preventEvent)
|
|
||||||
plot.getPlaceholder().trigger("plotunselected", [ ]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// function taken from markings support in Flot
|
|
||||||
function extractRange(ranges, coord) {
|
|
||||||
var axis, from, to, key, axes = plot.getAxes();
|
|
||||||
|
|
||||||
for (var k in axes) {
|
|
||||||
axis = axes[k];
|
|
||||||
if (axis.direction == coord) {
|
|
||||||
key = coord + axis.n + "axis";
|
|
||||||
if (!ranges[key] && axis.n == 1)
|
|
||||||
key = coord + "axis"; // support x1axis as xaxis
|
|
||||||
if (ranges[key]) {
|
|
||||||
from = ranges[key].from;
|
|
||||||
to = ranges[key].to;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// backwards-compat stuff - to be removed in future
|
|
||||||
if (!ranges[key]) {
|
|
||||||
axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0];
|
|
||||||
from = ranges[coord + "1"];
|
|
||||||
to = ranges[coord + "2"];
|
|
||||||
}
|
|
||||||
|
|
||||||
// auto-reverse as an added bonus
|
|
||||||
if (from != null && to != null && from > to) {
|
|
||||||
var tmp = from;
|
|
||||||
from = to;
|
|
||||||
to = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { from: from, to: to, axis: axis };
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSelection(ranges, preventEvent) {
|
|
||||||
var axis, range, o = plot.getOptions();
|
|
||||||
|
|
||||||
if (o.selection.mode == "y") {
|
|
||||||
selection.first.x = 0;
|
|
||||||
selection.second.x = plot.width();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
range = extractRange(ranges, "x");
|
|
||||||
|
|
||||||
selection.first.x = range.axis.p2c(range.from);
|
|
||||||
selection.second.x = range.axis.p2c(range.to);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o.selection.mode == "x") {
|
|
||||||
selection.first.y = 0;
|
|
||||||
selection.second.y = plot.height();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
range = extractRange(ranges, "y");
|
|
||||||
|
|
||||||
selection.first.y = range.axis.p2c(range.from);
|
|
||||||
selection.second.y = range.axis.p2c(range.to);
|
|
||||||
}
|
|
||||||
|
|
||||||
selection.show = true;
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
if (!preventEvent && selectionIsSane())
|
|
||||||
triggerSelectedEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
function selectionIsSane() {
|
|
||||||
var minSize = 5;
|
|
||||||
return Math.abs(selection.second.x - selection.first.x) >= minSize &&
|
|
||||||
Math.abs(selection.second.y - selection.first.y) >= minSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.clearSelection = clearSelection;
|
|
||||||
plot.setSelection = setSelection;
|
|
||||||
plot.getSelection = getSelection;
|
|
||||||
|
|
||||||
plot.hooks.bindEvents.push(function(plot, eventHolder) {
|
|
||||||
var o = plot.getOptions();
|
|
||||||
if (o.selection.mode != null) {
|
|
||||||
eventHolder.mousemove(onMouseMove);
|
|
||||||
eventHolder.mousedown(onMouseDown);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
plot.hooks.drawOverlay.push(function (plot, ctx) {
|
|
||||||
// draw selection
|
|
||||||
if (selection.show && selectionIsSane()) {
|
|
||||||
var plotOffset = plot.getPlotOffset();
|
|
||||||
var o = plot.getOptions();
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate(plotOffset.left, plotOffset.top);
|
|
||||||
|
|
||||||
var c = $.color.parse(o.selection.color);
|
|
||||||
|
|
||||||
ctx.strokeStyle = c.scale('a', 0.8).toString();
|
|
||||||
ctx.lineWidth = 1;
|
|
||||||
ctx.lineJoin = "round";
|
|
||||||
ctx.fillStyle = c.scale('a', 0.4).toString();
|
|
||||||
|
|
||||||
var x = Math.min(selection.first.x, selection.second.x),
|
|
||||||
y = Math.min(selection.first.y, selection.second.y),
|
|
||||||
w = Math.abs(selection.second.x - selection.first.x),
|
|
||||||
h = Math.abs(selection.second.y - selection.first.y);
|
|
||||||
|
|
||||||
ctx.fillRect(x, y, w, h);
|
|
||||||
ctx.strokeRect(x, y, w, h);
|
|
||||||
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
plot.hooks.shutdown.push(function (plot, eventHolder) {
|
|
||||||
eventHolder.unbind("mousemove", onMouseMove);
|
|
||||||
eventHolder.unbind("mousedown", onMouseDown);
|
|
||||||
|
|
||||||
if (mouseUpHandler)
|
|
||||||
$(document).unbind("mouseup", mouseUpHandler);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
$.plot.plugins.push({
|
|
||||||
init: init,
|
|
||||||
options: {
|
|
||||||
selection: {
|
|
||||||
mode: null, // one of null, "x", "y" or "xy"
|
|
||||||
color: "#e8cfac"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
name: 'selection',
|
|
||||||
version: '1.1'
|
|
||||||
});
|
|
||||||
})(jQuery);
|
|
|
@ -1,184 +0,0 @@
|
||||||
/*
|
|
||||||
Flot plugin for stacking data sets, i.e. putting them on top of each
|
|
||||||
other, for accumulative graphs.
|
|
||||||
|
|
||||||
The plugin assumes the data is sorted on x (or y if stacking
|
|
||||||
horizontally). For line charts, it is assumed that if a line has an
|
|
||||||
undefined gap (from a null point), then the line above it should have
|
|
||||||
the same gap - insert zeros instead of "null" if you want another
|
|
||||||
behaviour. This also holds for the start and end of the chart. Note
|
|
||||||
that stacking a mix of positive and negative values in most instances
|
|
||||||
doesn't make sense (so it looks weird).
|
|
||||||
|
|
||||||
Two or more series are stacked when their "stack" attribute is set to
|
|
||||||
the same key (which can be any number or string or just "true"). To
|
|
||||||
specify the default stack, you can set
|
|
||||||
|
|
||||||
series: {
|
|
||||||
stack: null or true or key (number/string)
|
|
||||||
}
|
|
||||||
|
|
||||||
or specify it for a specific series
|
|
||||||
|
|
||||||
$.plot($("#placeholder"), [{ data: [ ... ], stack: true }])
|
|
||||||
|
|
||||||
The stacking order is determined by the order of the data series in
|
|
||||||
the array (later series end up on top of the previous).
|
|
||||||
|
|
||||||
Internally, the plugin modifies the datapoints in each series, adding
|
|
||||||
an offset to the y value. For line series, extra data points are
|
|
||||||
inserted through interpolation. If there's a second y value, it's also
|
|
||||||
adjusted (e.g for bar charts or filled areas).
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function ($) {
|
|
||||||
var options = {
|
|
||||||
series: { stack: null } // or number/string
|
|
||||||
};
|
|
||||||
|
|
||||||
function init(plot) {
|
|
||||||
function findMatchingSeries(s, allseries) {
|
|
||||||
var res = null
|
|
||||||
for (var i = 0; i < allseries.length; ++i) {
|
|
||||||
if (s == allseries[i])
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (allseries[i].stack == s.stack)
|
|
||||||
res = allseries[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
function stackData(plot, s, datapoints) {
|
|
||||||
if (s.stack == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var other = findMatchingSeries(s, plot.getData());
|
|
||||||
if (!other)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var ps = datapoints.pointsize,
|
|
||||||
points = datapoints.points,
|
|
||||||
otherps = other.datapoints.pointsize,
|
|
||||||
otherpoints = other.datapoints.points,
|
|
||||||
newpoints = [],
|
|
||||||
px, py, intery, qx, qy, bottom,
|
|
||||||
withlines = s.lines.show,
|
|
||||||
horizontal = s.bars.horizontal,
|
|
||||||
withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),
|
|
||||||
withsteps = withlines && s.lines.steps,
|
|
||||||
fromgap = true,
|
|
||||||
keyOffset = horizontal ? 1 : 0,
|
|
||||||
accumulateOffset = horizontal ? 0 : 1,
|
|
||||||
i = 0, j = 0, l;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (i >= points.length)
|
|
||||||
break;
|
|
||||||
|
|
||||||
l = newpoints.length;
|
|
||||||
|
|
||||||
if (points[i] == null) {
|
|
||||||
// copy gaps
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
i += ps;
|
|
||||||
}
|
|
||||||
else if (j >= otherpoints.length) {
|
|
||||||
// for lines, we can't use the rest of the points
|
|
||||||
if (!withlines) {
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
}
|
|
||||||
i += ps;
|
|
||||||
}
|
|
||||||
else if (otherpoints[j] == null) {
|
|
||||||
// oops, got a gap
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(null);
|
|
||||||
fromgap = true;
|
|
||||||
j += otherps;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// cases where we actually got two points
|
|
||||||
px = points[i + keyOffset];
|
|
||||||
py = points[i + accumulateOffset];
|
|
||||||
qx = otherpoints[j + keyOffset];
|
|
||||||
qy = otherpoints[j + accumulateOffset];
|
|
||||||
bottom = 0;
|
|
||||||
|
|
||||||
if (px == qx) {
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
|
|
||||||
newpoints[l + accumulateOffset] += qy;
|
|
||||||
bottom = qy;
|
|
||||||
|
|
||||||
i += ps;
|
|
||||||
j += otherps;
|
|
||||||
}
|
|
||||||
else if (px > qx) {
|
|
||||||
// we got past point below, might need to
|
|
||||||
// insert interpolated extra point
|
|
||||||
if (withlines && i > 0 && points[i - ps] != null) {
|
|
||||||
intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);
|
|
||||||
newpoints.push(qx);
|
|
||||||
newpoints.push(intery + qy);
|
|
||||||
for (m = 2; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
bottom = qy;
|
|
||||||
}
|
|
||||||
|
|
||||||
j += otherps;
|
|
||||||
}
|
|
||||||
else { // px < qx
|
|
||||||
if (fromgap && withlines) {
|
|
||||||
// if we come from a gap, we just skip this point
|
|
||||||
i += ps;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
|
|
||||||
// we might be able to interpolate a point below,
|
|
||||||
// this can give us a better y
|
|
||||||
if (withlines && j > 0 && otherpoints[j - otherps] != null)
|
|
||||||
bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);
|
|
||||||
|
|
||||||
newpoints[l + accumulateOffset] += bottom;
|
|
||||||
|
|
||||||
i += ps;
|
|
||||||
}
|
|
||||||
|
|
||||||
fromgap = false;
|
|
||||||
|
|
||||||
if (l != newpoints.length && withbottom)
|
|
||||||
newpoints[l + 2] += bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
// maintain the line steps invariant
|
|
||||||
if (withsteps && l != newpoints.length && l > 0
|
|
||||||
&& newpoints[l] != null
|
|
||||||
&& newpoints[l] != newpoints[l - ps]
|
|
||||||
&& newpoints[l + 1] != newpoints[l - ps + 1]) {
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints[l + ps + m] = newpoints[l + m];
|
|
||||||
newpoints[l + 1] = newpoints[l - ps + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
datapoints.points = newpoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.hooks.processDatapoints.push(stackData);
|
|
||||||
}
|
|
||||||
|
|
||||||
$.plot.plugins.push({
|
|
||||||
init: init,
|
|
||||||
options: options,
|
|
||||||
name: 'stack',
|
|
||||||
version: '1.2'
|
|
||||||
});
|
|
||||||
})(jQuery);
|
|
|
@ -1,70 +0,0 @@
|
||||||
/*
|
|
||||||
Flot plugin that adds some extra symbols for plotting points.
|
|
||||||
|
|
||||||
The symbols are accessed as strings through the standard symbol
|
|
||||||
choice:
|
|
||||||
|
|
||||||
series: {
|
|
||||||
points: {
|
|
||||||
symbol: "square" // or "diamond", "triangle", "cross"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function ($) {
|
|
||||||
function processRawData(plot, series, datapoints) {
|
|
||||||
// we normalize the area of each symbol so it is approximately the
|
|
||||||
// same as a circle of the given radius
|
|
||||||
|
|
||||||
var handlers = {
|
|
||||||
square: function (ctx, x, y, radius, shadow) {
|
|
||||||
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
|
|
||||||
var size = radius * Math.sqrt(Math.PI) / 2;
|
|
||||||
ctx.rect(x - size, y - size, size + size, size + size);
|
|
||||||
},
|
|
||||||
diamond: function (ctx, x, y, radius, shadow) {
|
|
||||||
// pi * r^2 = 2s^2 => s = r * sqrt(pi/2)
|
|
||||||
var size = radius * Math.sqrt(Math.PI / 2);
|
|
||||||
ctx.moveTo(x - size, y);
|
|
||||||
ctx.lineTo(x, y - size);
|
|
||||||
ctx.lineTo(x + size, y);
|
|
||||||
ctx.lineTo(x, y + size);
|
|
||||||
ctx.lineTo(x - size, y);
|
|
||||||
},
|
|
||||||
triangle: function (ctx, x, y, radius, shadow) {
|
|
||||||
// pi * r^2 = 1/2 * s^2 * sin (pi / 3) => s = r * sqrt(2 * pi / sin(pi / 3))
|
|
||||||
var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));
|
|
||||||
var height = size * Math.sin(Math.PI / 3);
|
|
||||||
ctx.moveTo(x - size/2, y + height/2);
|
|
||||||
ctx.lineTo(x + size/2, y + height/2);
|
|
||||||
if (!shadow) {
|
|
||||||
ctx.lineTo(x, y - height/2);
|
|
||||||
ctx.lineTo(x - size/2, y + height/2);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
cross: function (ctx, x, y, radius, shadow) {
|
|
||||||
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
|
|
||||||
var size = radius * Math.sqrt(Math.PI) / 2;
|
|
||||||
ctx.moveTo(x - size, y - size);
|
|
||||||
ctx.lineTo(x + size, y + size);
|
|
||||||
ctx.moveTo(x - size, y + size);
|
|
||||||
ctx.lineTo(x + size, y - size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var s = series.points.symbol;
|
|
||||||
if (handlers[s])
|
|
||||||
series.points.symbol = handlers[s];
|
|
||||||
}
|
|
||||||
|
|
||||||
function init(plot) {
|
|
||||||
plot.hooks.processDatapoints.push(processRawData);
|
|
||||||
}
|
|
||||||
|
|
||||||
$.plot.plugins.push({
|
|
||||||
init: init,
|
|
||||||
name: 'symbols',
|
|
||||||
version: '1.0'
|
|
||||||
});
|
|
||||||
})(jQuery);
|
|
|
@ -1,103 +0,0 @@
|
||||||
/*
|
|
||||||
Flot plugin for thresholding data. Controlled through the option
|
|
||||||
"threshold" in either the global series options
|
|
||||||
|
|
||||||
series: {
|
|
||||||
threshold: {
|
|
||||||
below: number
|
|
||||||
color: colorspec
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
or in a specific series
|
|
||||||
|
|
||||||
$.plot($("#placeholder"), [{ data: [ ... ], threshold: { ... }}])
|
|
||||||
|
|
||||||
The data points below "below" are drawn with the specified color. This
|
|
||||||
makes it easy to mark points below 0, e.g. for budget data.
|
|
||||||
|
|
||||||
Internally, the plugin works by splitting the data into two series,
|
|
||||||
above and below the threshold. The extra series below the threshold
|
|
||||||
will have its label cleared and the special "originSeries" attribute
|
|
||||||
set to the original series. You may need to check for this in hover
|
|
||||||
events.
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function ($) {
|
|
||||||
var options = {
|
|
||||||
series: { threshold: null } // or { below: number, color: color spec}
|
|
||||||
};
|
|
||||||
|
|
||||||
function init(plot) {
|
|
||||||
function thresholdData(plot, s, datapoints) {
|
|
||||||
if (!s.threshold)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var ps = datapoints.pointsize, i, x, y, p, prevp,
|
|
||||||
thresholded = $.extend({}, s); // note: shallow copy
|
|
||||||
|
|
||||||
thresholded.datapoints = { points: [], pointsize: ps };
|
|
||||||
thresholded.label = null;
|
|
||||||
thresholded.color = s.threshold.color;
|
|
||||||
thresholded.threshold = null;
|
|
||||||
thresholded.originSeries = s;
|
|
||||||
thresholded.data = [];
|
|
||||||
|
|
||||||
var below = s.threshold.below,
|
|
||||||
origpoints = datapoints.points,
|
|
||||||
addCrossingPoints = s.lines.show;
|
|
||||||
|
|
||||||
threspoints = [];
|
|
||||||
newpoints = [];
|
|
||||||
|
|
||||||
for (i = 0; i < origpoints.length; i += ps) {
|
|
||||||
x = origpoints[i]
|
|
||||||
y = origpoints[i + 1];
|
|
||||||
|
|
||||||
prevp = p;
|
|
||||||
if (y < below)
|
|
||||||
p = threspoints;
|
|
||||||
else
|
|
||||||
p = newpoints;
|
|
||||||
|
|
||||||
if (addCrossingPoints && prevp != p && x != null
|
|
||||||
&& i > 0 && origpoints[i - ps] != null) {
|
|
||||||
var interx = (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]) * (below - y) + x;
|
|
||||||
prevp.push(interx);
|
|
||||||
prevp.push(below);
|
|
||||||
for (m = 2; m < ps; ++m)
|
|
||||||
prevp.push(origpoints[i + m]);
|
|
||||||
|
|
||||||
p.push(null); // start new segment
|
|
||||||
p.push(null);
|
|
||||||
for (m = 2; m < ps; ++m)
|
|
||||||
p.push(origpoints[i + m]);
|
|
||||||
p.push(interx);
|
|
||||||
p.push(below);
|
|
||||||
for (m = 2; m < ps; ++m)
|
|
||||||
p.push(origpoints[i + m]);
|
|
||||||
}
|
|
||||||
|
|
||||||
p.push(x);
|
|
||||||
p.push(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
datapoints.points = newpoints;
|
|
||||||
thresholded.datapoints.points = threspoints;
|
|
||||||
|
|
||||||
if (thresholded.datapoints.points.length > 0)
|
|
||||||
plot.getData().push(thresholded);
|
|
||||||
|
|
||||||
// FIXME: there are probably some edge cases left in bars
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.hooks.processDatapoints.push(thresholdData);
|
|
||||||
}
|
|
||||||
|
|
||||||
$.plot.plugins.push({
|
|
||||||
init: init,
|
|
||||||
options: options,
|
|
||||||
name: 'threshold',
|
|
||||||
version: '1.0'
|
|
||||||
});
|
|
||||||
})(jQuery);
|
|
|
@ -1,161 +0,0 @@
|
||||||
/**
|
|
||||||
* Some general functions we need for the frontend
|
|
||||||
*
|
|
||||||
* @author Florian Ziegler <fz@f10-home.de>
|
|
||||||
* @author Justin Otherguy <justin@justinotherguy.org>
|
|
||||||
* @author Steffen Vogel <info@steffenvogel.de>
|
|
||||||
* @copyright Copyright (c) 2011, The volkszaehler.org project
|
|
||||||
* @package default
|
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* This file is part of volkzaehler.org
|
|
||||||
*
|
|
||||||
* volkzaehler.org is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, either version 3 of the License, or any later version.
|
|
||||||
*
|
|
||||||
* volkzaehler.org is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
var Exception = function(type, message, code) {
|
|
||||||
return {
|
|
||||||
type: type,
|
|
||||||
message: message,
|
|
||||||
code: code
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Universal helper for middleware ajax requests with error handling
|
|
||||||
*/
|
|
||||||
vz.load = function(args) {
|
|
||||||
$.extend(args, {
|
|
||||||
accepts: 'application/json',
|
|
||||||
error: function(xhr) {
|
|
||||||
try {
|
|
||||||
if (xhr.getResponseHeader('Content-type') == 'application/json') {
|
|
||||||
var json = $.parseJSON(xhr.responseText);
|
|
||||||
|
|
||||||
if (json.exception) {
|
|
||||||
throw new Exception(json.exception.type, json.exception.message, (json.exception.code) ? json.exception.code : xhr.status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Exception(xhr.statusText, 'Unknown middleware response', xhr.status)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
vz.wui.dialogs.exception(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (args.url === undefined) { // local middleware by default
|
|
||||||
args.url = vz.middleware[0].url;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.url == vz.middleware[0].url) { // local request
|
|
||||||
args.dataType = 'json';
|
|
||||||
}
|
|
||||||
else { // remote request
|
|
||||||
args.dataType = 'jsonp';
|
|
||||||
args.jsonp = 'padding';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.controller !== undefined) {
|
|
||||||
args.url += '/' + args.controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.identifier !== undefined) {
|
|
||||||
args.url += '/' + args.identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
args.url += '.json';
|
|
||||||
|
|
||||||
if (args.data === undefined) {
|
|
||||||
args.data = { };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.type) {
|
|
||||||
args.data.operation = args.type.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
return $.ajax(args);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse URL GET parameters
|
|
||||||
*/
|
|
||||||
vz.parseUrlParams = function() {
|
|
||||||
var vars = $.getUrlParams();
|
|
||||||
var uuids = new Array;
|
|
||||||
var save = false;
|
|
||||||
|
|
||||||
for (var key in vars) {
|
|
||||||
if (vars.hasOwnProperty(key)) {
|
|
||||||
switch (key) {
|
|
||||||
case 'uuid': // add optional uuid from url
|
|
||||||
uuids = (typeof vars[key] == 'string') ? [vars[key]] : vars[key]; // handle multiple uuids
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'save': // save new uuids in cookie
|
|
||||||
save = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'from':
|
|
||||||
vz.options.plot.xaxis.min = parseInt(vars[key]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'to':
|
|
||||||
vz.options.plot.xaxis.max = parseInt(vars[key]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uuids.each(function(index, uuid) {
|
|
||||||
try {
|
|
||||||
vz.entities.push(new Entity({
|
|
||||||
middleware: vz.middleware[0].url,
|
|
||||||
uuid: uuid,
|
|
||||||
cookie: save
|
|
||||||
}));
|
|
||||||
} catch (exception) {
|
|
||||||
/* ignore exception */
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (save) {
|
|
||||||
vz.entities.saveCookie();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load capabilities from middleware
|
|
||||||
*/
|
|
||||||
vz.capabilities.load = function() {
|
|
||||||
return vz.load({
|
|
||||||
controller: 'capabilities',
|
|
||||||
success: function(json) {
|
|
||||||
$.extend(true, vz.capabilities, json.capabilities);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lookup definition
|
|
||||||
*/
|
|
||||||
vz.capabilities.definitions.get = function(section, name) {
|
|
||||||
for (var i in this[section]) {
|
|
||||||
if (this[section][i].name == name) {
|
|
||||||
return this[section][i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
/**
|
|
||||||
* Some functions and prototypes which make our life easier
|
|
||||||
*
|
|
||||||
* not volkszaehler.org related
|
|
||||||
*
|
|
||||||
* @author Florian Ziegler <fz@f10-home.de>
|
|
||||||
* @author Justin Otherguy <justin@justinotherguy.org>
|
|
||||||
* @author Steffen Vogel <info@steffenvogel.de>
|
|
||||||
* @copyright Copyright (c) 2011, The volkszaehler.org project
|
|
||||||
* @package default
|
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* This file is part of volkzaehler.org
|
|
||||||
*
|
|
||||||
* volkzaehler.org is free software: you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU General Public License as published by the Free
|
|
||||||
* Software Foundation, either version 3 of the License, or any later version.
|
|
||||||
*
|
|
||||||
* volkzaehler.org is distributed in the hope that it will be useful, but
|
|
||||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
||||||
* details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with
|
|
||||||
* volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Array extensions
|
|
||||||
* according to js language specification ECMA 1.6
|
|
||||||
*/
|
|
||||||
Array.prototype.indexOf = function(n) {
|
|
||||||
for (var i = 0, l = this.length; i < l; i++) {
|
|
||||||
if (n == this[i]) return i;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Array.prototype.remove = function(n) {
|
|
||||||
this.splice(this.indexOf(n), 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
Array.prototype.each = function(cb, ctx) {
|
|
||||||
for (var i = 0, l = this.length; i < l; i++) {
|
|
||||||
if (cb.call((ctx === undefined) ? this[i] : ctx, i, this[i]) === false) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Array.prototype.contains = function(n) {
|
|
||||||
return this.indexOf(n) !== undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
Array.prototype.clear = function() {
|
|
||||||
this.length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Array.prototype.unique = function() {
|
|
||||||
var r = new Array;
|
|
||||||
this.each(function(key, value) {
|
|
||||||
if (!r.contains(value)) {
|
|
||||||
r.push(value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
Array.prototype.last = function() {
|
|
||||||
if (this.length > 0) {
|
|
||||||
return this[this.length-1];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,105 +0,0 @@
|
||||||
/**
|
|
||||||
* Initialization and configuration of frontend
|
|
||||||
*
|
|
||||||
* @author Florian Ziegler <fz@f10-home.de>
|
|
||||||
* @author Justin Otherguy <justin@justinotherguy.org>
|
|
||||||
* @author Steffen Vogel <info@steffenvogel.de>
|
|
||||||
* @copyright Copyright (c) 2011, The volkszaehler.org project
|
|
||||||
* @package default
|
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* This file is part of volkzaehler.org
|
|
||||||
*
|
|
||||||
* volkzaehler.org is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* any later version.
|
|
||||||
*
|
|
||||||
* volkzaehler.org is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with volkszaehler.org. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* volkszaehler.org namespace
|
|
||||||
*
|
|
||||||
* holds all data, options and functions for the frontend
|
|
||||||
* we dont want to pollute the global namespace
|
|
||||||
*/
|
|
||||||
var vz = {
|
|
||||||
entities: new Array, // entity properties + data
|
|
||||||
middleware: [{ // default middleware
|
|
||||||
url: '../middleware.php',
|
|
||||||
public: [ ] // public entities
|
|
||||||
/* capabilities: { } */
|
|
||||||
}],
|
|
||||||
|
|
||||||
// web user interface
|
|
||||||
wui: {
|
|
||||||
dialogs: { },
|
|
||||||
timeout: null
|
|
||||||
},
|
|
||||||
|
|
||||||
// debugging and runtime information from middleware
|
|
||||||
capabilities: {
|
|
||||||
definitions: { } // definitions of entities & properties
|
|
||||||
},
|
|
||||||
|
|
||||||
// flot instance
|
|
||||||
plot: { },
|
|
||||||
|
|
||||||
// options loaded from cookies in options.js
|
|
||||||
options: { }
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executed on document loaded complete
|
|
||||||
* this is where it all starts...
|
|
||||||
*/
|
|
||||||
$(document).ready(function() {
|
|
||||||
// late binding
|
|
||||||
$(window).resize(function() {
|
|
||||||
vz.options.tuples = Math.round($('#flot').width() / 3);
|
|
||||||
$('#tuples').val(vz.options.tuples);
|
|
||||||
vz.wui.drawPlot();
|
|
||||||
});
|
|
||||||
|
|
||||||
window.onerror = function(errorMsg, url, lineNumber) {
|
|
||||||
vz.wui.dialogs.error('Javascript Runtime Error', errorMsg);
|
|
||||||
};
|
|
||||||
|
|
||||||
vz.entities.loadCookie(); // load uuids from cookie
|
|
||||||
vz.options.loadCookies(); // load options from cookie
|
|
||||||
vz.parseUrlParams(); // parse additional url params (new uuid etc..)
|
|
||||||
|
|
||||||
// initialize user interface
|
|
||||||
vz.wui.init();
|
|
||||||
vz.wui.initEvents();
|
|
||||||
|
|
||||||
// chaining ajax request with jquery deferred object
|
|
||||||
vz.capabilities.load().done(function() {
|
|
||||||
if (vz.capabilities.formats.contains('png')) {
|
|
||||||
$('#export option[value=png]').removeAttr('disabled');
|
|
||||||
}
|
|
||||||
|
|
||||||
var queue = new Array;
|
|
||||||
vz.entities.each(function(entity) {
|
|
||||||
queue.push(entity.loadDetails());
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
$.when.apply($, queue).done(function() {
|
|
||||||
if (vz.entities.length == 0) {
|
|
||||||
vz.wui.dialogs.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
vz.entities.showTable();
|
|
||||||
vz.entities.loadData().done(vz.wui.drawPlot);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|