Compare commits

..

No commits in common. "0.2-rc1" and "master" have entirely different histories.

282 changed files with 5804 additions and 58516 deletions

41
.gitignore vendored
View file

@ -1,6 +1,35 @@
etc/volkszaehler.conf.php
misc/sql/demo/pulses.dummy.copy
.project
.buildpath
.settings/
lib/vendor/*
*~
# Binaries
/src/vzlogger
# 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
View file

@ -1,3 +0,0 @@
[submodule "misc/frontend/fnordlicht"]
path = misc/frontend/fnordlicht
url = git://github.com/stv0g/libfn.git

View file

@ -1,2 +0,0 @@
Deny from all
Allow from localhost

1
AUTHORS Normal file
View file

@ -0,0 +1 @@
Written by Steffen Vogel <info@steffenvogel.de>

View file

@ -1 +0,0 @@
There is no stable release yet. Have some patience please or contribute.

53
COPYING
View file

@ -619,56 +619,3 @@ Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
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
View file

View file

@ -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
View file

@ -0,0 +1,3 @@
sysconf_DATA = etc/vzlogger.conf
SUBDIRS = src docs

View file

@ -36,7 +36,7 @@ subdir = .
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
depcomp install-sh missing
compile depcomp install-sh missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@ -137,8 +137,12 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DEPS_CFLAGS = @DEPS_CFLAGS@
DEPS_LIBS = @DEPS_LIBS@
DEPS_LOCAL_CFLAGS = @DEPS_LOCAL_CFLAGS@
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_N = @ECHO_N@
ECHO_T = @ECHO_T@
@ -168,6 +172,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
@ -214,7 +219,7 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
sysconf_DATA = vzlogger.conf
sysconf_DATA = etc/vzlogger.conf
SUBDIRS = src docs
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive

0
NEWS Normal file
View file

35
README
View file

@ -1,28 +1,11 @@
This are the scripts running on volkszaehler.org
Feel free to setup your own installation and protect your privacy!
vzlogger...
* 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/
|_ htdocs/ static files accessible through the web
| |_ 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
Feel free to implement support your own hardware ;)
If you have questions, contact Steffen Vogel <info@steffenvogel.de>
Wiki: http://wiki.volkszaehler.org
Other: http://volkszaehler.org
Or contact our mailing list: volkszaehler-dev@lists.volkszaehler.org
More information is available in our wiki:
http://wiki.volkszaehler.org/software/controller/vzlogger

View file

@ -797,6 +797,41 @@ AC_MSG_RESULT([$_am_result])
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 -*-
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008

143
compile Executable file
View 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:

View file

@ -10,6 +10,9 @@
/* Define to 1 if you have the <fcntl.h> header file. */
#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. */
#undef HAVE_GETTIMEOFDAY
@ -26,10 +29,16 @@
/* Define to 1 if you have the `memset' function. */
#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,
and to 0 otherwise. */
#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. */
#undef HAVE_SQRT
@ -72,8 +81,11 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* No-debug Mode */
#undef NDEBUG
/* Local interface */
#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 */
#undef PACKAGE
@ -96,6 +108,9 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Smart Messaging Language */
#undef SML_SUPPORT
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS

View file

@ -1,8 +1,8 @@
#! /bin/sh
# 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,
@ -231,10 +231,10 @@ fi
$as_echo "$0: be upgraded to zsh 4.3.4 or later."
else
$as_echo "$0: Please tell bug-autoconf@gnu.org and
$0: info@steffenvogel.de about your system, including any
$0: error possibly output before this message. Then install
$0: a modern shell, or manually run the script under such a
$0: shell if you do have one."
$0: http://bugs.volkszaehler.org about your system,
$0: including any error possibly output before this
$0: message. Then install a modern shell, or manually run
$0: the script under such a shell if you do have one."
fi
exit 1
fi
@ -552,12 +552,12 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='vzlogger'
PACKAGE_TARNAME='vzlogger'
PACKAGE_VERSION='0.2'
PACKAGE_STRING='vzlogger 0.2'
PACKAGE_BUGREPORT='info@steffenvogel.de'
PACKAGE_VERSION='0.3.3'
PACKAGE_STRING='vzlogger 0.3.3'
PACKAGE_BUGREPORT='http://bugs.volkszaehler.org'
PACKAGE_URL=''
ac_unique_file="src/main.c"
ac_unique_file="src/meter.c"
# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
@ -597,15 +597,26 @@ ac_includes_default="\
ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
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
EGREP
GREP
CPP
DEPS_LIBS
DEPS_CFLAGS
DEPS_VZ_LIBS
DEPS_VZ_CFLAGS
PKG_CONFIG_LIBDIR
PKG_CONFIG_PATH
PKG_CONFIG
RANLIB
am__fastdepCC_FALSE
am__fastdepCC_TRUE
CCDEPMODE
@ -687,6 +698,9 @@ ac_subst_files=''
ac_user_opts='
enable_option_checking
enable_dependency_tracking
enable_sml
enable_local
with_reader
enable_debug
'
ac_precious_vars='build_alias
@ -700,9 +714,13 @@ CPPFLAGS
PKG_CONFIG
PKG_CONFIG_PATH
PKG_CONFIG_LIBDIR
DEPS_CFLAGS
DEPS_LIBS
CPP'
DEPS_VZ_CFLAGS
DEPS_VZ_LIBS
CPP
DEPS_SML_CFLAGS
DEPS_SML_LIBS
DEPS_LOCAL_CFLAGS
DEPS_LOCAL_LIBS'
# 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.
# This message is too long to be a string in the A/UX 3.1 sh.
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]...
@ -1311,7 +1329,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of vzlogger 0.2:";;
short | recursive ) echo "Configuration of vzlogger 0.3.3:";;
esac
cat <<\_ACEOF
@ -1321,8 +1339,16 @@ Optional Features:
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-dependency-tracking speeds up one-time build
--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)
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:
CC C compiler command
CFLAGS C compiler flags
@ -1336,14 +1362,24 @@ Some influential environment variables:
directories to add to pkg-config's search path
PKG_CONFIG_LIBDIR
path overriding pkg-config's built-in search path
DEPS_CFLAGS C compiler flags for DEPS, overriding pkg-config
DEPS_LIBS linker flags for DEPS, overriding pkg-config
DEPS_VZ_CFLAGS
C compiler flags for DEPS_VZ, overriding pkg-config
DEPS_VZ_LIBS
linker flags for DEPS_VZ, overriding pkg-config
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
it to find libraries and programs with nonstandard names/locations.
Report bugs to <info@steffenvogel.de>.
Report bugs to <http://bugs.volkszaehler.org>.
_ACEOF
ac_status=$?
fi
@ -1406,7 +1442,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
vzlogger configure 0.2
vzlogger configure 0.3.3
generated by GNU Autoconf 2.67
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:${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 "## ----------------------------------- ##
## Report this to info@steffenvogel.de ##
## ----------------------------------- ##"
( $as_echo "## ------------------------------------------- ##
## Report this to http://bugs.volkszaehler.org ##
## ------------------------------------------- ##"
) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
@ -1875,7 +1911,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
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
$ $0 $@
@ -2690,7 +2726,7 @@ fi
# Define the identity of the package.
PACKAGE=vzlogger
VERSION=0.2
VERSION=0.3.3
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_files="$ac_config_files Makefile src/Makefile docs/Makefile"
ac_config_files="$ac_config_files Makefile docs/Makefile src/Makefile"
# 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.
@ -3839,35 +4098,35 @@ $as_echo "no" >&6; }
fi
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEPS" >&5
$as_echo_n "checking for DEPS... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for DEPS_VZ" >&5
$as_echo_n "checking for DEPS_VZ... " >&6; }
if test -n "$DEPS_CFLAGS"; then
pkg_cv_DEPS_CFLAGS="$DEPS_CFLAGS"
if test -n "$DEPS_VZ_CFLAGS"; then
pkg_cv_DEPS_VZ_CFLAGS="$DEPS_VZ_CFLAGS"
elif test -n "$PKG_CONFIG"; then
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
($PKG_CONFIG --exists --print-errors "json >= 0.9 libcurl >= 7.21.0 libmicrohttpd >= 0.9.3") 2>&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.19") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
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
pkg_failed=yes
fi
else
pkg_failed=untried
fi
if test -n "$DEPS_LIBS"; then
pkg_cv_DEPS_LIBS="$DEPS_LIBS"
if test -n "$DEPS_VZ_LIBS"; then
pkg_cv_DEPS_VZ_LIBS="$DEPS_VZ_LIBS"
elif test -n "$PKG_CONFIG"; then
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
($PKG_CONFIG --exists --print-errors "json >= 0.9 libcurl >= 7.21.0 libmicrohttpd >= 0.9.3") 2>&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.19") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
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
pkg_failed=yes
fi
@ -3887,22 +4146,22 @@ else
_pkg_short_errors_supported=no
fi
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
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
# 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
installed software in a non-standard prefix.
Alternatively, you may set the environment variables DEPS_CFLAGS
and DEPS_LIBS to avoid the need to call pkg-config.
Alternatively, you may set the environment variables DEPS_VZ_CFLAGS
and DEPS_VZ_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
@ -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
path to pkg-config.
Alternatively, you may set the environment variables DEPS_CFLAGS
and DEPS_LIBS to avoid the need to call pkg-config.
Alternatively, you may set the environment variables DEPS_VZ_CFLAGS
and DEPS_VZ_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_CFLAGS=$pkg_cv_DEPS_CFLAGS
DEPS_LIBS=$pkg_cv_DEPS_LIBS
DEPS_VZ_CFLAGS=$pkg_cv_DEPS_VZ_CFLAGS
DEPS_VZ_LIBS=$pkg_cv_DEPS_VZ_LIBS
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
@ -4326,7 +4585,7 @@ fi
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 :
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"
@ -4604,28 +4863,267 @@ fi
done
# debug compilation support
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with debug information" >&5
$as_echo_n "checking whether to build with debug information... " >&6; }
# Check whether --enable-debug was given.
if test "${enable_debug+set}" = set; then :
enableval=$enable_debug; debugit="$enableval"
# SML support
# Check whether --enable-sml was given.
if test "${enable_sml+set}" = set; then :
enableval=$enable_sml; sml=$enableval
else
debugit=no
sml=yes
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
AM_CXXFLAGS="$AM_CXXFLAGS -g -Wall -Werror -Wno-uninitialized -O0"
else
$as_echo "#define NDEBUG /**/" >>confdefs.h
AM_CXXFLAGS="$AM_CXXFLAGS -O3"
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.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
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}
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
# values after options handling.
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
CONFIG_FILES = $CONFIG_FILES
@ -5211,13 +5721,13 @@ $config_headers
Configuration commands:
$config_commands
Report bugs to <info@steffenvogel.de>."
Report bugs to <http://bugs.volkszaehler.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
vzlogger config.status 0.2
vzlogger config.status 0.3.3
configured by $0, generated by GNU Autoconf 2.67,
with options \\"\$ac_cs_config\\"
@ -5348,8 +5858,8 @@ do
case $ac_config_target in
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
"docs/Makefile") CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;;
"src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
"depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;

96
configure.ac Normal file
View 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
View 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
View 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.

View file

@ -12,12 +12,14 @@
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC=vzlogger # Introduce a short description here
NAME=vzlogger # Introduce the short server's name here
DAEMON=/usr/sbin/vzlogger # Introduce the server's location here
DAEMON_ARGS="" # Arguments to run the daemon with
DESC="smartmetering server"
NAME=vzlogger
DAEMON=/usr/bin/vzlogger
DAEMON_ARGS="-d" # Arguments to run the daemon with
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
USER=vzlogger
GROUP=vzlogger
# Exit if the package is not installed
[ -x $DAEMON ] || exit 0
@ -41,9 +43,9 @@ do_start()
# 0 if daemon has been started
# 1 if daemon was already running
# 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
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
start-stop-daemon --start --chuid $USER --group $GROUP --quiet --pidfile $PIDFILE --exec $DAEMON -- \
$DAEMON_ARGS \
|| return 2
# Add code here, if necessary, that waits for the process to be ready

26
debian/vzlogger.postinst vendored Normal file
View 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#

View file

@ -83,8 +83,12 @@ CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DEPS_CFLAGS = @DEPS_CFLAGS@
DEPS_LIBS = @DEPS_LIBS@
DEPS_LOCAL_CFLAGS = @DEPS_LOCAL_CFLAGS@
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_N = @ECHO_N@
ECHO_T = @ECHO_T@
@ -114,6 +118,7 @@ PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@

View file

@ -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
View 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. */
}
}
]}

View file

@ -1,6 +0,0 @@
Allow from all
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^middleware/(.*) middleware.php/$1 [L]
</IfModule>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 685 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 526 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 736 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 745 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 720 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 915 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 750 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 778 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 530 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 670 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 566 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 882 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 626 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 741 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 610 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 742 B

View file

@ -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&nbsp;<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>&empty;</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&uuml;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">
&copy; 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">&ouml;ffentliche Kan&auml;le</a></li>
<li><a href="#entity-create">Kanal erstellen</a></li>
</ul>
<div id="entity-subscribe">
<p>Hier k&ouml;nnen Sie einen existierenden Kanal über seine UUID hinzuf&uuml;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&ouml;nnen Sie &ouml;ffentliche Kan&auml;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>&Ouml;ffentlich:</td><td><input type="radio" name="public" value="1"> ja&nbsp;&nbsp;<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&ouml;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>

View file

@ -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'
});
};

View file

@ -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&uuml;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));
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

File diff suppressed because it is too large Load diff

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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];
}
}
}

View file

@ -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];
}
}

View file

@ -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);
});
});
});

Some files were not shown because too many files have changed in this diff Show more