Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
F
flot
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
HS-public
flot
Commits
0a601d03
Commit
0a601d03
authored
Nov 25, 2012
by
David Schnur
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleaned up whitespace, braces and strings.
parent
2f7cfcb5
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
414 additions
and
373 deletions
+414
-373
jquery.flot.pie.js
jquery.flot.pie.js
+414
-373
No files found.
jquery.flot.pie.js
View file @
0a601d03
/*
/*
Flot plugin for rendering pie charts. The plugin assumes the data is
Flot plugin for rendering pie charts.
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
Copyright (c) 2007-2012 IOLA and Ole Laursen.
any sense and will cause strange effects). The data values do
Licensed under the MIT license.
NOT need to be passed in as percentage values because it
internally calculates the total and percentages.
The plugin assumes that each series has a single data value, and that
each value is a positive integer or zero. Negative numbers don't make
sense for a pie chart, and have unpredictable results. The values do
NOT need to be passed in as percentages; the plugin will calculate the
total and per-slice percentages internally.
* Created by Brian Medendorp, June 2009
* Created by Brian Medendorp, June 2009
* Updated November 2009 with contributions from: btburnett3, Anthony Aragues and Xavi Ivars
* Updated November 2009 with contributions from: btburnett3, Anthony Aragues and Xavi Ivars
...
@@ -15,7 +19,6 @@ internally calculates the total and percentages.
...
@@ -15,7 +19,6 @@ internally calculates the total and percentages.
2009-11-11: Added basic hover from btburnett3 - does not work in IE, and center is off in Chrome and Opera
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-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)
2009-11-18: Added bug fix submitted by Xavi Ivars (issues with arrays when other JS libraries are included as well)
Available options are:
Available options are:
series: {
series: {
...
@@ -58,10 +61,10 @@ More detail and specific examples can be found in the included HTML file.
...
@@ -58,10 +61,10 @@ More detail and specific examples can be found in the included HTML file.
*/
*/
(
function
(
$
)
(
function
(
$
)
{
{
function
init
(
plot
)
// this is the "body" of the plugin
function
init
(
plot
)
{
{
var
canvas
=
null
;
var
canvas
=
null
;
var
canvasWidth
=
0
;
var
canvasWidth
=
0
;
var
canvasHeight
=
0
;
var
canvasHeight
=
0
;
...
@@ -76,301 +79,313 @@ More detail and specific examples can be found in the included HTML file.
...
@@ -76,301 +79,313 @@ More detail and specific examples can be found in the included HTML file.
var
legendWidth
=
0
;
var
legendWidth
=
0
;
var
processed
=
false
;
var
processed
=
false
;
var
raw
=
false
;
var
raw
=
false
;
// interactive variables
// interactive variables
var
highlights
=
[];
var
highlights
=
[];
// add hook to determine if pie plugin in enabled, and then perform necessary operations
// add hook to determine if pie plugin in enabled, and then perform necessary operations
plot
.
hooks
.
processOptions
.
push
(
checkPieEnabled
);
plot
.
hooks
.
processOptions
.
push
(
checkPieEnabled
);
plot
.
hooks
.
bindEvents
.
push
(
bindEvents
);
plot
.
hooks
.
bindEvents
.
push
(
bindEvents
);
// check to see if the pie plugin is enabled
// check to see if the pie plugin is enabled
function
checkPieEnabled
(
plot
,
options
)
{
function
checkPieEnabled
(
plot
,
options
)
{
if
(
options
.
series
.
pie
.
show
)
if
(
options
.
series
.
pie
.
show
)
{
{
//disable grid
//disable grid
options
.
grid
.
show
=
false
;
options
.
grid
.
show
=
false
;
// set labels.show
// set labels.show
if
(
options
.
series
.
pie
.
label
.
show
==
'auto'
)
if
(
options
.
legend
.
show
)
if
(
options
.
series
.
pie
.
label
.
show
==
"auto"
)
{
if
(
options
.
legend
.
show
)
{
options
.
series
.
pie
.
label
.
show
=
false
;
options
.
series
.
pie
.
label
.
show
=
false
;
else
}
else
{
options
.
series
.
pie
.
label
.
show
=
true
;
options
.
series
.
pie
.
label
.
show
=
true
;
}
}
// set radius
// set radius
if
(
options
.
series
.
pie
.
radius
==
'auto'
)
if
(
options
.
series
.
pie
.
label
.
show
)
if
(
options
.
series
.
pie
.
radius
==
"auto"
)
{
if
(
options
.
series
.
pie
.
label
.
show
)
{
options
.
series
.
pie
.
radius
=
3
/
4
;
options
.
series
.
pie
.
radius
=
3
/
4
;
else
}
else
{
options
.
series
.
pie
.
radius
=
1
;
options
.
series
.
pie
.
radius
=
1
;
}
}
// ensure sane tilt
// ensure sane tilt
if
(
options
.
series
.
pie
.
tilt
>
1
)
options
.
series
.
pie
.
tilt
=
1
;
if
(
options
.
series
.
pie
.
tilt
>
1
)
{
if
(
options
.
series
.
pie
.
tilt
<
0
)
options
.
series
.
pie
.
tilt
=
1
;
options
.
series
.
pie
.
tilt
=
0
;
}
else
if
(
options
.
series
.
pie
.
tilt
<
0
)
{
options
.
series
.
pie
.
tilt
=
0
;
}
// add processData hook to do transformations on the data
// add processData hook to do transformations on the data
plot
.
hooks
.
processDatapoints
.
push
(
processDatapoints
);
plot
.
hooks
.
processDatapoints
.
push
(
processDatapoints
);
plot
.
hooks
.
drawOverlay
.
push
(
drawOverlay
);
plot
.
hooks
.
drawOverlay
.
push
(
drawOverlay
);
// add draw hook
// draw hook
plot
.
hooks
.
draw
.
push
(
draw
);
plot
.
hooks
.
draw
.
push
(
draw
);
}
}
}
}
// bind hoverable events
// bind hoverable events
function
bindEvents
(
plot
,
eventHolder
)
{
function
bindEvents
(
plot
,
eventHolder
)
{
var
options
=
plot
.
getOptions
();
var
options
=
plot
.
getOptions
();
if
(
options
.
series
.
pie
.
show
)
{
if
(
options
.
series
.
pie
.
show
&&
options
.
grid
.
hoverable
)
if
(
options
.
grid
.
hoverable
)
{
eventHolder
.
unbind
(
'mousemove'
).
mousemove
(
onMouseMove
);
eventHolder
.
unbind
(
"mousemove"
).
mousemove
(
onMouseMove
);
}
if
(
options
.
series
.
pie
.
show
&&
options
.
grid
.
clickable
)
if
(
options
.
grid
.
clickable
)
{
eventHolder
.
unbind
(
'click'
).
click
(
onClick
);
eventHolder
.
unbind
(
"click"
).
click
(
onClick
);
}
}
}
}
// debugging function that prints out an object
// debugging function that prints out an object
function
alertObject
(
obj
)
{
function
alertObject
(
obj
)
{
var
msg
=
''
;
function
traverse
(
obj
,
depth
)
var
msg
=
""
;
{
if
(
!
depth
)
function
traverse
(
obj
,
depth
)
{
if
(
!
depth
)
{
depth
=
0
;
depth
=
0
;
}
for
(
var
i
=
0
;
i
<
obj
.
length
;
++
i
)
for
(
var
i
=
0
;
i
<
obj
.
length
;
++
i
)
{
{
for
(
var
j
=
0
;
j
<
depth
;
j
++
)
for
(
var
j
=
0
;
j
<
depth
;
j
++
)
{
msg
+=
'
\
t'
;
msg
+=
"
\
t"
;
if
(
typeof
obj
[
i
]
==
"object"
)
{
// its an object
msg
+=
''
+
i
+
':
\
n'
;
traverse
(
obj
[
i
],
depth
+
1
);
}
}
else
{
// its a value
if
(
typeof
obj
[
i
]
==
"object"
)
{
msg
+=
''
+
i
+
': '
+
obj
[
i
]
+
'
\
n'
;
msg
+=
""
+
i
+
":
\n
"
;
traverse
(
obj
[
i
],
depth
+
1
);
}
else
{
msg
+=
""
+
i
+
": "
+
obj
[
i
]
+
"
\n
"
;
}
}
}
}
}
}
traverse
(
obj
);
traverse
(
obj
);
alert
(
msg
);
alert
(
msg
);
}
}
function
calcTotal
(
data
)
function
calcTotal
(
data
)
{
{
for
(
var
i
=
0
;
i
<
data
.
length
;
++
i
)
{
for
(
var
i
=
0
;
i
<
data
.
length
;
++
i
)
{
var
item
=
parseFloat
(
data
[
i
].
data
[
0
][
1
]);
var
item
=
parseFloat
(
data
[
i
].
data
[
0
][
1
]);
if
(
item
)
if
(
item
)
{
total
+=
item
;
total
+=
item
;
}
}
}
}
}
function
processDatapoints
(
plot
,
series
,
data
,
datapoints
)
{
if
(
!
processed
)
{
processed
=
true
;
function
processDatapoints
(
plot
,
series
,
data
,
datapoints
)
{
if
(
!
processed
)
{
processed
=
true
;
canvas
=
plot
.
getCanvas
();
canvas
=
plot
.
getCanvas
();
target
=
$
(
canvas
).
parent
();
target
=
$
(
canvas
).
parent
();
options
=
plot
.
getOptions
();
options
=
plot
.
getOptions
();
canvasWidth
=
plot
.
getPlaceholder
().
width
();
canvasWidth
=
plot
.
getPlaceholder
().
width
();
canvasHeight
=
plot
.
getPlaceholder
().
height
();
canvasHeight
=
plot
.
getPlaceholder
().
height
();
plot
.
setData
(
combine
(
plot
.
getData
()));
plot
.
setData
(
combine
(
plot
.
getData
()));
}
}
}
}
function
setupPie
()
function
setupPie
()
{
{
legendWidth
=
target
.
children
().
filter
(
'.legend'
).
children
().
width
()
||
0
;
legendWidth
=
target
.
children
().
filter
(
".legend"
).
children
().
width
()
||
0
;
// calculate maximum radius and center point
// calculate maximum radius and center point
maxRadius
=
Math
.
min
(
canvasWidth
,(
canvasHeight
/
options
.
series
.
pie
.
tilt
))
/
2
;
centerTop
=
(
canvasHeight
/
2
)
+
options
.
series
.
pie
.
offset
.
top
;
maxRadius
=
Math
.
min
(
canvasWidth
,
canvasHeight
/
options
.
series
.
pie
.
tilt
)
/
2
;
centerLeft
=
(
canvasWidth
/
2
);
centerTop
=
canvasHeight
/
2
+
options
.
series
.
pie
.
offset
.
top
;
centerLeft
=
canvasWidth
/
2
;
if
(
options
.
series
.
pie
.
offset
.
left
==
'auto'
)
if
(
options
.
legend
.
position
.
match
(
'w'
))
if
(
options
.
series
.
pie
.
offset
.
left
==
"auto"
)
{
centerLeft
+=
legendWidth
/
2
;
if
(
options
.
legend
.
position
.
match
(
"w"
))
{
else
centerLeft
+=
legendWidth
/
2
;
centerLeft
-=
legendWidth
/
2
;
}
else
{
else
centerLeft
-=
legendWidth
/
2
;
}
}
else
{
centerLeft
+=
options
.
series
.
pie
.
offset
.
left
;
centerLeft
+=
options
.
series
.
pie
.
offset
.
left
;
}
if
(
centerLeft
<
maxRadius
)
if
(
centerLeft
<
maxRadius
)
{
centerLeft
=
maxRadius
;
centerLeft
=
maxRadius
;
else
if
(
centerLeft
>
canvasWidth
-
maxRadius
)
}
else
if
(
centerLeft
>
canvasWidth
-
maxRadius
)
{
centerLeft
=
canvasWidth
-
maxRadius
;
centerLeft
=
canvasWidth
-
maxRadius
;
}
}
}
function
fixData
(
data
)
function
fixData
(
data
)
{
{
for
(
var
i
=
0
;
i
<
data
.
length
;
++
i
)
{
for
(
var
i
=
0
;
i
<
data
.
length
;
++
i
)
if
(
typeof
(
data
[
i
].
data
)
==
"number"
)
{
{
data
[
i
].
data
=
[[
1
,
data
[
i
].
data
]];
if
(
typeof
(
data
[
i
].
data
)
==
'number'
)
}
else
if
(
typeof
(
data
[
i
].
data
)
==
"undefined"
||
typeof
(
data
[
i
].
data
[
0
])
==
"undefined"
)
{
data
[
i
].
data
=
[[
1
,
data
[
i
].
data
]];
if
(
typeof
(
data
[
i
].
data
)
!=
"undefined"
&&
typeof
(
data
[
i
].
data
.
label
)
!=
"undefined"
)
{
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
].
label
=
data
[
i
].
data
.
label
;
// fix weirdness coming from flot
data
[
i
].
data
=
[[
1
,
0
]];
}
data
[
i
].
data
=
[[
1
,
0
]];
}
}
}
}
return
data
;
return
data
;
}
}
function
combine
(
data
)
function
combine
(
data
)
{
{
data
=
fixData
(
data
);
data
=
fixData
(
data
);
calcTotal
(
data
);
calcTotal
(
data
);
var
combined
=
0
;
var
combined
=
0
;
var
numCombined
=
0
;
var
numCombined
=
0
;
var
color
=
options
.
series
.
pie
.
combine
.
color
;
var
color
=
options
.
series
.
pie
.
combine
.
color
;
var
newdata
=
[];
var
newdata
=
[];
for
(
var
i
=
0
;
i
<
data
.
length
;
++
i
)
{
for
(
var
i
=
0
;
i
<
data
.
length
;
++
i
)
{
// make sure its a number
// make sure its a number
data
[
i
].
data
[
0
][
1
]
=
parseFloat
(
data
[
i
].
data
[
0
][
1
]);
data
[
i
].
data
[
0
][
1
]
=
parseFloat
(
data
[
i
].
data
[
0
][
1
]);
if
(
!
data
[
i
].
data
[
0
][
1
])
if
(
!
data
[
i
].
data
[
0
][
1
])
{
data
[
i
].
data
[
0
][
1
]
=
0
;
data
[
i
].
data
[
0
][
1
]
=
0
;
}
if
(
data
[
i
].
data
[
0
][
1
]
/
total
<=
options
.
series
.
pie
.
combine
.
threshold
)
{
if
(
data
[
i
].
data
[
0
][
1
]
/
total
<=
options
.
series
.
pie
.
combine
.
threshold
)
{
combined
+=
data
[
i
].
data
[
0
][
1
];
combined
+=
data
[
i
].
data
[
0
][
1
];
numCombined
++
;
numCombined
++
;
if
(
!
color
)
if
(
!
color
)
{
color
=
data
[
i
].
color
;
color
=
data
[
i
].
color
;
}
}
else
}
else
{
{
newdata
.
push
({
newdata
.
push
({
data
:
[[
1
,
data
[
i
].
data
[
0
][
1
]]],
data
:
[[
1
,
data
[
i
].
data
[
0
][
1
]]],
color
:
data
[
i
].
color
,
color
:
data
[
i
].
color
,
label
:
data
[
i
].
label
,
label
:
data
[
i
].
label
,
angle
:
(
data
[
i
].
data
[
0
][
1
]
*
(
Math
.
PI
*
2
))
/
total
,
angle
:
data
[
i
].
data
[
0
][
1
]
*
Math
.
PI
*
2
/
total
,
percent
:
(
data
[
i
].
data
[
0
][
1
]
/
total
*
100
)
percent
:
data
[
i
].
data
[
0
][
1
]
/
total
*
100
});
});
}
}
}
}
if
(
numCombined
>
0
)
if
(
numCombined
>
0
)
{
newdata
.
push
({
newdata
.
push
({
data
:
[[
1
,
combined
]],
data
:
[[
1
,
combined
]],
color
:
color
,
color
:
color
,
label
:
options
.
series
.
pie
.
combine
.
label
,
label
:
options
.
series
.
pie
.
combine
.
label
,
angle
:
(
combined
*
(
Math
.
PI
*
2
))
/
total
,
angle
:
combined
*
Math
.
PI
*
2
/
total
,
percent
:
(
combined
/
total
*
100
)
percent
:
combined
/
total
*
100
});
});
return
newdata
;
return
newdata
;
}
}
function
draw
(
plot
,
newCtx
)
function
draw
(
plot
,
newCtx
)
{
{
if
(
!
target
)
return
;
// if no series were passed
if
(
!
target
)
{
return
;
// if no series were passed
}
ctx
=
newCtx
;
ctx
=
newCtx
;
setupPie
();
setupPie
();
var
slices
=
plot
.
getData
();
var
slices
=
plot
.
getData
();
var
attempts
=
0
;
var
attempts
=
0
;
while
(
redraw
&&
attempts
<
redrawAttempts
)
{
while
(
redraw
&&
attempts
<
redrawAttempts
)
{
redraw
=
false
;
redraw
=
false
;
if
(
attempts
>
0
)
if
(
attempts
>
0
)
{
maxRadius
*=
shrink
;
maxRadius
*=
shrink
;
}
attempts
+=
1
;
attempts
+=
1
;
clear
();
clear
();
if
(
options
.
series
.
pie
.
tilt
<=
0.8
)
if
(
options
.
series
.
pie
.
tilt
<=
0.8
)
{
drawShadow
();
drawShadow
();
}
drawPie
();
drawPie
();
}
}
if
(
attempts
>=
redrawAttempts
)
{
if
(
attempts
>=
redrawAttempts
)
{
clear
();
clear
();
target
.
prepend
(
'<div class="error">Could not draw pie with labels contained inside canvas</div>'
);
target
.
prepend
(
"<div class='error'>Could not draw pie with labels contained inside canvas</div>"
);
}
}
if
(
plot
.
setSeries
&&
plot
.
insertLegend
)
if
(
plot
.
setSeries
&&
plot
.
insertLegend
)
{
{
plot
.
setSeries
(
slices
);
plot
.
setSeries
(
slices
);
plot
.
insertLegend
();
plot
.
insertLegend
();
}
}
// we're actually done at this point, just defining internal functions at this point
// we're actually done at this point, just defining internal functions at this point
function
clear
()
function
clear
()
{
{
ctx
.
clearRect
(
0
,
0
,
canvasWidth
,
canvasHeight
);
ctx
.
clearRect
(
0
,
0
,
canvasWidth
,
canvasHeight
);
target
.
children
().
filter
(
".pieLabel, .pieLabelBackground"
).
remove
();
target
.
children
().
filter
(
'.pieLabel, .pieLabelBackground'
).
remove
();
}
}
function
drawShadow
()
function
drawShadow
()
{
{
var
shadowLeft
=
options
.
series
.
pie
.
shadow
.
left
;
var
shadowLeft
=
options
.
series
.
pie
.
shadow
.
left
;
var
shadowTop
=
options
.
series
.
pie
.
shadow
.
top
;
var
shadowTop
=
options
.
series
.
pie
.
shadow
.
top
;
var
edge
=
10
;
var
edge
=
10
;
var
alpha
=
options
.
series
.
pie
.
shadow
.
alpha
;
var
alpha
=
options
.
series
.
pie
.
shadow
.
alpha
;
var
radius
=
options
.
series
.
pie
.
radius
>
1
?
options
.
series
.
pie
.
radius
:
maxRadius
*
options
.
series
.
pie
.
radius
;
// set radius
if
(
options
.
series
.
pie
.
radius
>
1
)
if
(
radius
>=
canvasWidth
/
2
-
shadowLeft
||
radius
*
options
.
series
.
pie
.
tilt
>=
canvasHeight
/
2
-
shadowTop
||
radius
<=
edge
)
{
var
radius
=
options
.
series
.
pie
.
radius
;
else
var
radius
=
maxRadius
*
options
.
series
.
pie
.
radius
;
if
(
radius
>=
(
canvasWidth
/
2
)
-
shadowLeft
||
radius
*
options
.
series
.
pie
.
tilt
>=
(
canvasHeight
/
2
)
-
shadowTop
||
radius
<=
edge
)
return
;
// shadow would be outside canvas, so don't draw it
return
;
// shadow would be outside canvas, so don't draw it
}
ctx
.
save
();
ctx
.
save
();
ctx
.
translate
(
shadowLeft
,
shadowTop
);
ctx
.
translate
(
shadowLeft
,
shadowTop
);
ctx
.
globalAlpha
=
alpha
;
ctx
.
globalAlpha
=
alpha
;
ctx
.
fillStyle
=
'#000'
;
ctx
.
fillStyle
=
"#000"
;
// center and rotate to starting position
// center and rotate to starting position
ctx
.
translate
(
centerLeft
,
centerTop
);
ctx
.
translate
(
centerLeft
,
centerTop
);
ctx
.
scale
(
1
,
options
.
series
.
pie
.
tilt
);
ctx
.
scale
(
1
,
options
.
series
.
pie
.
tilt
);
//radius -= edge;
//radius -= edge;
for
(
var
i
=
1
;
i
<=
edge
;
i
++
)
{
for
(
var
i
=
1
;
i
<=
edge
;
i
++
)
{
ctx
.
beginPath
();
ctx
.
beginPath
();
ctx
.
arc
(
0
,
0
,
radius
,
0
,
Math
.
PI
*
2
,
false
);
ctx
.
arc
(
0
,
0
,
radius
,
0
,
Math
.
PI
*
2
,
false
);
ctx
.
fill
();
ctx
.
fill
();
radius
-=
i
;
radius
-=
i
;
}
}
ctx
.
restore
();
ctx
.
restore
();
}
}
function
drawPie
()
{
var
startAngle
=
Math
.
PI
*
options
.
series
.
pie
.
startAngle
;
var
radius
;
// set radius
function
drawPie
()
{
if
(
options
.
series
.
pie
.
radius
>
1
)
radius
=
options
.
series
.
pie
.
radius
;
var
startAngle
=
Math
.
PI
*
options
.
series
.
pie
.
startAngle
;
else
radius
=
maxRadius
*
options
.
series
.
pie
.
radius
;
var
radius
=
options
.
series
.
pie
.
radius
>
1
?
options
.
series
.
pie
.
radius
:
maxRadius
*
options
.
series
.
pie
.
radius
;
// center and rotate to starting position
// center and rotate to starting position
ctx
.
save
();
ctx
.
save
();
ctx
.
translate
(
centerLeft
,
centerTop
);
ctx
.
translate
(
centerLeft
,
centerTop
);
ctx
.
scale
(
1
,
options
.
series
.
pie
.
tilt
);
ctx
.
scale
(
1
,
options
.
series
.
pie
.
tilt
);
//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
// draw slices
// draw slices
ctx
.
save
();
ctx
.
save
();
var
currentAngle
=
startAngle
;
var
currentAngle
=
startAngle
;
for
(
var
i
=
0
;
i
<
slices
.
length
;
++
i
)
for
(
var
i
=
0
;
i
<
slices
.
length
;
++
i
)
{
{
slices
[
i
].
startAngle
=
currentAngle
;
slices
[
i
].
startAngle
=
currentAngle
;
drawSlice
(
slices
[
i
].
angle
,
slices
[
i
].
color
,
true
);
drawSlice
(
slices
[
i
].
angle
,
slices
[
i
].
color
,
true
);
}
}
...
@@ -382,286 +397,313 @@ More detail and specific examples can be found in the included HTML file.
...
@@ -382,286 +397,313 @@ More detail and specific examples can be found in the included HTML file.
ctx
.
save
();
ctx
.
save
();
ctx
.
lineWidth
=
options
.
series
.
pie
.
stroke
.
width
;
ctx
.
lineWidth
=
options
.
series
.
pie
.
stroke
.
width
;
currentAngle
=
startAngle
;
currentAngle
=
startAngle
;
for
(
var
i
=
0
;
i
<
slices
.
length
;
++
i
)
for
(
var
i
=
0
;
i
<
slices
.
length
;
++
i
)
{
drawSlice
(
slices
[
i
].
angle
,
options
.
series
.
pie
.
stroke
.
color
,
false
);
drawSlice
(
slices
[
i
].
angle
,
options
.
series
.
pie
.
stroke
.
color
,
false
);
}
ctx
.
restore
();
ctx
.
restore
();
}
}
// draw donut hole
// draw donut hole
drawDonutHole
(
ctx
);
drawDonutHole
(
ctx
);
// draw labels
// draw labels
if
(
options
.
series
.
pie
.
label
.
show
)
if
(
options
.
series
.
pie
.
label
.
show
)
{
drawLabels
();
drawLabels
();
}
// restore to original state
// restore to original state
ctx
.
restore
();
ctx
.
restore
();
function
drawSlice
(
angle
,
color
,
fill
)
function
drawSlice
(
angle
,
color
,
fill
)
{
{
if
(
angle
<=
0
||
isNaN
(
angle
))
if
(
angle
<=
0
||
isNaN
(
angle
))
{
return
;
return
;
}
if
(
fill
)
if
(
fill
)
{
ctx
.
fillStyle
=
color
;
ctx
.
fillStyle
=
color
;
else
}
else
{
{
ctx
.
strokeStyle
=
color
;
ctx
.
strokeStyle
=
color
;
ctx
.
lineJoin
=
'round'
;
ctx
.
lineJoin
=
"round"
;
}
}
ctx
.
beginPath
();
ctx
.
beginPath
();
if
(
Math
.
abs
(
angle
-
Math
.
PI
*
2
)
>
0.000000001
)
if
(
Math
.
abs
(
angle
-
Math
.
PI
*
2
)
>
0.000000001
)
{
ctx
.
moveTo
(
0
,
0
);
// Center of the pie
ctx
.
moveTo
(
0
,
0
);
// Center of the pie
else
if
(
$
.
browser
.
msie
)
}
else
if
(
$
.
browser
.
msie
)
{
angle
-=
0.0001
;
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.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
.
closePath
();
//ctx.rotate(angle); // This doesn't work properly in Opera
//ctx.rotate(angle); // This doesn't work properly in Opera
currentAngle
+=
angle
;
currentAngle
+=
angle
;
if
(
fill
)
if
(
fill
)
{
ctx
.
fill
();
ctx
.
fill
();
else
}
else
{
ctx
.
stroke
();
ctx
.
stroke
();
}
}
}
function
drawLabels
()
function
drawLabels
()
{
{
var
currentAngle
=
startAngle
;
var
currentAngle
=
startAngle
;
var
radius
=
options
.
series
.
pie
.
label
.
radius
>
1
?
options
.
series
.
pie
.
label
.
radius
:
maxRadius
*
options
.
series
.
pie
.
label
.
radius
;
// set radius
if
(
options
.
series
.
pie
.
label
.
radius
>
1
)
for
(
var
i
=
0
;
i
<
slices
.
length
;
++
i
)
{
var
radius
=
options
.
series
.
pie
.
label
.
radius
;
if
(
slices
[
i
].
percent
>=
options
.
series
.
pie
.
label
.
threshold
*
100
)
{
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
);
drawLabel
(
slices
[
i
],
currentAngle
,
i
);
}
currentAngle
+=
slices
[
i
].
angle
;
currentAngle
+=
slices
[
i
].
angle
;
}
}
function
drawLabel
(
slice
,
startAngle
,
index
)
function
drawLabel
(
slice
,
startAngle
,
index
)
{
{
if
(
slice
.
data
[
0
][
1
]
==
0
)
{
if
(
slice
.
data
[
0
][
1
]
==
0
)
return
;
return
;
}
// format label text
// format label text
var
lf
=
options
.
legend
.
labelFormatter
,
text
,
plf
=
options
.
series
.
pie
.
label
.
formatter
;
var
lf
=
options
.
legend
.
labelFormatter
,
text
,
plf
=
options
.
series
.
pie
.
label
.
formatter
;
if
(
lf
)
if
(
lf
)
{
text
=
lf
(
slice
.
label
,
slice
);
text
=
lf
(
slice
.
label
,
slice
);
else
}
else
{
text
=
slice
.
label
;
text
=
slice
.
label
;
if
(
plf
)
}
if
(
plf
)
{
text
=
plf
(
text
,
slice
);
text
=
plf
(
text
,
slice
);
}
var
halfAngle
=
((
startAngle
+
slice
.
angle
)
+
startAngle
)
/
2
;
var
halfAngle
=
((
startAngle
+
slice
.
angle
)
+
startAngle
)
/
2
;
var
x
=
centerLeft
+
Math
.
round
(
Math
.
cos
(
halfAngle
)
*
radius
);
var
x
=
centerLeft
+
Math
.
round
(
Math
.
cos
(
halfAngle
)
*
radius
);
var
y
=
centerTop
+
Math
.
round
(
Math
.
sin
(
halfAngle
)
*
radius
)
*
options
.
series
.
pie
.
tilt
;
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>"
;
var
html
=
"<span class='pieLabel' id='pieLabel"
+
index
+
"' style='position:absolute;top:"
+
y
+
"px;left:"
+
x
+
"px;'>"
+
text
+
"</span>"
;
target
.
append
(
html
);
target
.
append
(
html
);
var
label
=
target
.
children
(
'#pieLabel'
+
index
);
var
labelTop
=
(
y
-
label
.
height
()
/
2
);
var
label
=
target
.
children
(
"#pieLabel"
+
index
);
var
labelLeft
=
(
x
-
label
.
width
()
/
2
);
var
labelTop
=
(
y
-
label
.
height
()
/
2
);
label
.
css
(
'top'
,
labelTop
);
var
labelLeft
=
(
x
-
label
.
width
()
/
2
);
label
.
css
(
'left'
,
labelLeft
);
label
.
css
(
"top"
,
labelTop
);
label
.
css
(
"left"
,
labelLeft
);
// check to make sure that the label is not outside the canvas
// check to make sure that the label is not outside the canvas
if
(
0
-
labelTop
>
0
||
0
-
labelLeft
>
0
||
canvasHeight
-
(
labelTop
+
label
.
height
())
<
0
||
canvasWidth
-
(
labelLeft
+
label
.
width
())
<
0
)
if
(
0
-
labelTop
>
0
||
0
-
labelLeft
>
0
||
canvasHeight
-
(
labelTop
+
label
.
height
())
<
0
||
canvasWidth
-
(
labelLeft
+
label
.
width
())
<
0
)
{
redraw
=
true
;
redraw
=
true
;
}
if
(
options
.
series
.
pie
.
label
.
background
.
opacity
!=
0
)
{
if
(
options
.
series
.
pie
.
label
.
background
.
opacity
!=
0
)
{
// put in the transparent background separately to avoid blended labels and label boxes
// put in the transparent background separately to avoid blended labels and label boxes
var
c
=
options
.
series
.
pie
.
label
.
background
.
color
;
var
c
=
options
.
series
.
pie
.
label
.
background
.
color
;
if
(
c
==
null
)
{
if
(
c
==
null
)
{
c
=
slice
.
color
;
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
);
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>"
)
.
css
(
"opacity"
,
options
.
series
.
pie
.
label
.
background
.
opacity
)
.
insertBefore
(
label
);
}
}
}
// end individual label function
}
// end individual label function
}
// end drawLabels function
}
// end drawLabels function
}
// end drawPie function
}
// end drawPie function
}
// end draw function
}
// end draw function
// Placed here because it needs to be accessed from multiple locations
// Placed here because it needs to be accessed from multiple locations
function
drawDonutHole
(
layer
)
{
function
drawDonutHole
(
layer
)
{
// draw donut hole
if
(
options
.
series
.
pie
.
innerRadius
>
0
)
{
if
(
options
.
series
.
pie
.
innerRadius
>
0
)
{
// subtract the center
// subtract the center
layer
.
save
();
layer
.
save
();
innerRadius
=
options
.
series
.
pie
.
innerRadius
>
1
?
options
.
series
.
pie
.
innerRadius
:
maxRadius
*
options
.
series
.
pie
.
innerRadius
;
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
.
globalCompositeOperation
=
"destination-out"
;
// this does not work with excanvas, but it will fall back to using the stroke color
layer
.
beginPath
();
layer
.
beginPath
();
layer
.
fillStyle
=
options
.
series
.
pie
.
stroke
.
color
;
layer
.
fillStyle
=
options
.
series
.
pie
.
stroke
.
color
;
layer
.
arc
(
0
,
0
,
innerRadius
,
0
,
Math
.
PI
*
2
,
false
);
layer
.
arc
(
0
,
0
,
innerRadius
,
0
,
Math
.
PI
*
2
,
false
);
layer
.
fill
();
layer
.
fill
();
layer
.
closePath
();
layer
.
closePath
();
layer
.
restore
();
layer
.
restore
();
// add inner stroke
// add inner stroke
layer
.
save
();
layer
.
save
();
layer
.
beginPath
();
layer
.
beginPath
();
layer
.
strokeStyle
=
options
.
series
.
pie
.
stroke
.
color
;
layer
.
strokeStyle
=
options
.
series
.
pie
.
stroke
.
color
;
layer
.
arc
(
0
,
0
,
innerRadius
,
0
,
Math
.
PI
*
2
,
false
);
layer
.
arc
(
0
,
0
,
innerRadius
,
0
,
Math
.
PI
*
2
,
false
);
layer
.
stroke
();
layer
.
stroke
();
layer
.
closePath
();
layer
.
closePath
();
layer
.
restore
();
layer
.
restore
();
// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
}
}
}
}
//-- Additional Interactive related functions --
//-- Additional Interactive related functions --
function
isPointInPoly
(
poly
,
pt
)
function
isPointInPoly
(
poly
,
pt
)
{
{
for
(
var
c
=
false
,
i
=
-
1
,
l
=
poly
.
length
,
j
=
l
-
1
;
++
i
<
l
;
j
=
i
)
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
]))
((
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
])
&&
(
pt
[
0
]
<
(
poly
[
j
][
0
]
-
poly
[
i
][
0
])
*
(
pt
[
1
]
-
poly
[
i
][
1
])
/
(
poly
[
j
][
1
]
-
poly
[
i
][
1
])
+
poly
[
i
][
0
])
&&
(
c
=
!
c
);
&&
(
c
=
!
c
);
return
c
;
return
c
;
}
}
function
findNearbySlice
(
mouseX
,
mouseY
)
function
findNearbySlice
(
mouseX
,
mouseY
)
{
{
var
slices
=
plot
.
getData
()
,
var
slices
=
plot
.
getData
()
;
options
=
plot
.
getOptions
(),
var
options
=
plot
.
getOptions
();
radius
=
options
.
series
.
pie
.
radius
>
1
?
options
.
series
.
pie
.
radius
:
maxRadius
*
options
.
series
.
pie
.
radius
;
var
radius
=
options
.
series
.
pie
.
radius
>
1
?
options
.
series
.
pie
.
radius
:
maxRadius
*
options
.
series
.
pie
.
radius
;
for
(
var
i
=
0
;
i
<
slices
.
length
;
++
i
)
for
(
var
i
=
0
;
i
<
slices
.
length
;
++
i
)
{
{
var
s
=
slices
[
i
];
var
s
=
slices
[
i
];
if
(
s
.
pie
.
show
)
if
(
s
.
pie
.
show
)
{
{
ctx
.
save
();
ctx
.
save
();
ctx
.
beginPath
();
ctx
.
beginPath
();
ctx
.
moveTo
(
0
,
0
);
// Center of the pie
ctx
.
moveTo
(
0
,
0
);
// Center of the pie
//ctx.scale(1, options.series.pie.tilt); // this actually seems to break everything when here.
//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
.
arc
(
0
,
0
,
radius
,
s
.
startAngle
,
s
.
startAngle
+
s
.
angle
,
false
);
ctx
.
closePath
();
ctx
.
closePath
();
x
=
mouseX
-
centerLeft
;
x
=
mouseX
-
centerLeft
;
y
=
mouseY
-
centerTop
;
y
=
mouseY
-
centerTop
;
if
(
ctx
.
isPointInPath
)
{
if
(
ctx
.
isPointInPath
)
{
if
(
ctx
.
isPointInPath
(
mouseX
-
centerLeft
,
mouseY
-
centerTop
))
if
(
ctx
.
isPointInPath
(
mouseX
-
centerLeft
,
mouseY
-
centerTop
))
{
{
//alert('found slice!');
ctx
.
restore
();
ctx
.
restore
();
return
{
datapoint
:
[
s
.
percent
,
s
.
data
],
dataIndex
:
0
,
series
:
s
,
seriesIndex
:
i
};
return
{
datapoint
:
[
s
.
percent
,
s
.
data
],
dataIndex
:
0
,
series
:
s
,
seriesIndex
:
i
};
}
}
}
}
else
{
else
{
// excanvas for IE doesn;t support isPointInPath, this is a workaround.
// excanvas for IE doesn;t support isPointInPath, this is a workaround.
p1X
=
(
radius
*
Math
.
cos
(
s
.
startAngle
));
p1X
=
radius
*
Math
.
cos
(
s
.
startAngle
);
p1Y
=
(
radius
*
Math
.
sin
(
s
.
startAngle
));
p1Y
=
radius
*
Math
.
sin
(
s
.
startAngle
);
p2X
=
(
radius
*
Math
.
cos
(
s
.
startAngle
+
(
s
.
angle
/
4
)));
p2X
=
radius
*
Math
.
cos
(
s
.
startAngle
+
s
.
angle
/
4
);
p2Y
=
(
radius
*
Math
.
sin
(
s
.
startAngle
+
(
s
.
angle
/
4
)));
p2Y
=
radius
*
Math
.
sin
(
s
.
startAngle
+
s
.
angle
/
4
);
p3X
=
(
radius
*
Math
.
cos
(
s
.
startAngle
+
(
s
.
angle
/
2
)));
p3X
=
radius
*
Math
.
cos
(
s
.
startAngle
+
s
.
angle
/
2
);
p3Y
=
(
radius
*
Math
.
sin
(
s
.
startAngle
+
(
s
.
angle
/
2
)));
p3Y
=
radius
*
Math
.
sin
(
s
.
startAngle
+
s
.
angle
/
2
);
p4X
=
(
radius
*
Math
.
cos
(
s
.
startAngle
+
(
s
.
angle
/
1.5
)));
p4X
=
radius
*
Math
.
cos
(
s
.
startAngle
+
s
.
angle
/
1.5
);
p4Y
=
(
radius
*
Math
.
sin
(
s
.
startAngle
+
(
s
.
angle
/
1.5
)));
p4Y
=
radius
*
Math
.
sin
(
s
.
startAngle
+
s
.
angle
/
1.5
);
p5X
=
(
radius
*
Math
.
cos
(
s
.
startAngle
+
s
.
angle
));
p5X
=
radius
*
Math
.
cos
(
s
.
startAngle
+
s
.
angle
);
p5Y
=
(
radius
*
Math
.
sin
(
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
]];
arrPoly
=
[[
0
,
0
],
[
p1X
,
p1Y
],
[
p2X
,
p2Y
],
[
p3X
,
p3Y
],
[
p4X
,
p4Y
],
[
p5X
,
p5Y
]];
arrPoint
=
[
x
,
y
];
arrPoint
=
[
x
,
y
];
// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
if
(
isPointInPoly
(
arrPoly
,
arrPoint
))
{
if
(
isPointInPoly
(
arrPoly
,
arrPoint
))
{
ctx
.
restore
();
ctx
.
restore
();
return
{
datapoint
:
[
s
.
percent
,
s
.
data
],
dataIndex
:
0
,
series
:
s
,
seriesIndex
:
i
};
return
{
}
datapoint
:
[
s
.
percent
,
s
.
data
],
dataIndex
:
0
,
series
:
s
,
seriesIndex
:
i
};
}
}
}
ctx
.
restore
();
ctx
.
restore
();
}
}
}
}
return
null
;
return
null
;
}
}
function
onMouseMove
(
e
)
function
onMouseMove
(
e
)
{
{
triggerClickHoverEvent
(
"plothover"
,
e
);
triggerClickHoverEvent
(
'plothover'
,
e
);
}
}
function
onClick
(
e
)
function
onClick
(
e
)
{
{
triggerClickHoverEvent
(
"plotclick"
,
e
);
triggerClickHoverEvent
(
'plotclick'
,
e
);
}
}
// trigger click or hover event (they send the same parameters so we share their code)
// trigger click or hover event (they send the same parameters so we share their code)
function
triggerClickHoverEvent
(
eventname
,
e
)
{
function
triggerClickHoverEvent
(
eventname
,
e
)
{
var
offset
=
plot
.
offset
()
,
var
offset
=
plot
.
offset
()
;
canvasX
=
parseInt
(
e
.
pageX
-
offset
.
left
),
var
canvasX
=
parseInt
(
e
.
pageX
-
offset
.
left
);
canvasY
=
parseInt
(
e
.
pageY
-
offset
.
top
),
var
canvasY
=
parseInt
(
e
.
pageY
-
offset
.
top
);
item
=
findNearbySlice
(
canvasX
,
canvasY
);
var
item
=
findNearbySlice
(
canvasX
,
canvasY
);
if
(
options
.
grid
.
autoHighlight
)
if
(
options
.
grid
.
autoHighlight
)
{
{
// clear auto-highlights
// clear auto-highlights
for
(
var
i
=
0
;
i
<
highlights
.
length
;
++
i
)
{
for
(
var
i
=
0
;
i
<
highlights
.
length
;
++
i
)
{
var
h
=
highlights
[
i
];
var
h
=
highlights
[
i
];
if
(
h
.
auto
==
eventname
&&
!
(
item
&&
h
.
series
==
item
.
series
))
if
(
h
.
auto
==
eventname
&&
!
(
item
&&
h
.
series
==
item
.
series
))
{
unhighlight
(
h
.
series
);
unhighlight
(
h
.
series
);
}
}
}
}
}
// highlight the slice
// highlight the slice
if
(
item
)
if
(
item
)
{
highlight
(
item
.
series
,
eventname
);
highlight
(
item
.
series
,
eventname
);
}
// trigger any hover bind events
// trigger any hover bind events
var
pos
=
{
pageX
:
e
.
pageX
,
pageY
:
e
.
pageY
};
var
pos
=
{
pageX
:
e
.
pageX
,
pageY
:
e
.
pageY
};
target
.
trigger
(
eventname
,
[
pos
,
item
]);
target
.
trigger
(
eventname
,
[
pos
,
item
]);
}
}
function
highlight
(
s
,
auto
)
function
highlight
(
s
,
auto
)
{
{
if
(
typeof
s
==
"number"
)
{
if
(
typeof
s
==
"number"
)
s
=
series
[
s
];
s
=
series
[
s
];
}
var
i
=
indexOfHighlight
(
s
);
var
i
=
indexOfHighlight
(
s
);
if
(
i
==
-
1
)
{
if
(
i
==
-
1
)
{
highlights
.
push
({
series
:
s
,
auto
:
auto
});
highlights
.
push
({
series
:
s
,
auto
:
auto
});
plot
.
triggerRedrawOverlay
();
plot
.
triggerRedrawOverlay
();
}
}
else
if
(
!
auto
)
{
else
if
(
!
auto
)
highlights
[
i
].
auto
=
false
;
highlights
[
i
].
auto
=
false
;
}
}
}
function
unhighlight
(
s
)
function
unhighlight
(
s
)
{
{
if
(
s
==
null
)
{
if
(
s
==
null
)
{
highlights
=
[];
highlights
=
[];
plot
.
triggerRedrawOverlay
();
plot
.
triggerRedrawOverlay
();
}
}
if
(
typeof
s
==
"number"
)
if
(
typeof
s
==
"number"
)
{
s
=
series
[
s
];
s
=
series
[
s
];
}
var
i
=
indexOfHighlight
(
s
);
var
i
=
indexOfHighlight
(
s
);
if
(
i
!=
-
1
)
{
if
(
i
!=
-
1
)
{
highlights
.
splice
(
i
,
1
);
highlights
.
splice
(
i
,
1
);
plot
.
triggerRedrawOverlay
();
plot
.
triggerRedrawOverlay
();
}
}
}
}
function
indexOfHighlight
(
s
)
function
indexOfHighlight
(
s
)
{
{
for
(
var
i
=
0
;
i
<
highlights
.
length
;
++
i
)
{
for
(
var
i
=
0
;
i
<
highlights
.
length
;
++
i
)
{
var
h
=
highlights
[
i
];
var
h
=
highlights
[
i
];
if
(
h
.
series
==
s
)
if
(
h
.
series
==
s
)
return
i
;
return
i
;
...
@@ -669,52 +711,50 @@ More detail and specific examples can be found in the included HTML file.
...
@@ -669,52 +711,50 @@ More detail and specific examples can be found in the included HTML file.
return
-
1
;
return
-
1
;
}
}
function
drawOverlay
(
plot
,
octx
)
function
drawOverlay
(
plot
,
octx
)
{
{
//alert(options.series.pie.radius);
var
options
=
plot
.
getOptions
();
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
;
var
radius
=
options
.
series
.
pie
.
radius
>
1
?
options
.
series
.
pie
.
radius
:
maxRadius
*
options
.
series
.
pie
.
radius
;
octx
.
save
();
octx
.
save
();
octx
.
translate
(
centerLeft
,
centerTop
);
octx
.
translate
(
centerLeft
,
centerTop
);
octx
.
scale
(
1
,
options
.
series
.
pie
.
tilt
);
octx
.
scale
(
1
,
options
.
series
.
pie
.
tilt
);
for
(
i
=
0
;
i
<
highlights
.
length
;
++
i
)
for
(
i
=
0
;
i
<
highlights
.
length
;
++
i
)
{
drawHighlight
(
highlights
[
i
].
series
);
drawHighlight
(
highlights
[
i
].
series
);
}
drawDonutHole
(
octx
);
drawDonutHole
(
octx
);
octx
.
restore
();
octx
.
restore
();
function
drawHighlight
(
series
)
function
drawHighlight
(
series
)
{
{
if
(
series
.
angle
<=
0
||
isNaN
(
series
.
angle
))
if
(
series
.
angle
<=
0
||
isNaN
(
series
.
angle
))
{
return
;
return
;
}
//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
//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
.
fillStyle
=
"rgba(255, 255, 255, "
+
options
.
series
.
pie
.
highlight
.
opacity
+
")"
;
// this is temporary until we have access to parseColor
octx
.
beginPath
();
octx
.
beginPath
();
if
(
Math
.
abs
(
series
.
angle
-
Math
.
PI
*
2
)
>
0.000000001
)
if
(
Math
.
abs
(
series
.
angle
-
Math
.
PI
*
2
)
>
0.000000001
)
{
octx
.
moveTo
(
0
,
0
);
// Center of the pie
octx
.
moveTo
(
0
,
0
);
// Center of the pie
octx
.
arc
(
0
,
0
,
radius
,
series
.
startAngle
,
series
.
startAngle
+
series
.
angle
,
false
);
}
octx
.
arc
(
0
,
0
,
radius
,
series
.
startAngle
,
series
.
startAngle
+
series
.
angle
,
false
);
octx
.
closePath
();
octx
.
closePath
();
octx
.
fill
();
octx
.
fill
();
}
}
}
}
}
// end init (plugin body)
}
// end init (plugin body)
// define pie specific options and their default values
// define pie specific options and their default values
var
options
=
{
var
options
=
{
series
:
{
series
:
{
pie
:
{
pie
:
{
show
:
false
,
show
:
false
,
radius
:
'auto'
,
// actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
radius
:
"auto"
,
// actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
innerRadius
:
0
,
/* for donut */
innerRadius
:
0
,
/* for donut */
startAngle
:
3
/
2
,
startAngle
:
3
/
2
,
tilt
:
1
,
tilt
:
1
,
shadow
:
{
shadow
:
{
...
@@ -724,16 +764,16 @@ More detail and specific examples can be found in the included HTML file.
...
@@ -724,16 +764,16 @@ More detail and specific examples can be found in the included HTML file.
},
},
offset
:
{
offset
:
{
top
:
0
,
top
:
0
,
left
:
'auto'
left
:
"auto"
},
},
stroke
:
{
stroke
:
{
color
:
'#FFF'
,
color
:
"#fff"
,
width
:
1
width
:
1
},
},
label
:
{
label
:
{
show
:
'auto'
,
show
:
"auto"
,
formatter
:
function
(
label
,
slice
){
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>'
;
return
"<div style='font-size:x-small;text-align:center;padding:2px;color:"
+
slice
.
color
+
";'>"
+
label
+
"<br/>"
+
Math
.
round
(
slice
.
percent
)
+
"%</div>"
;
},
// formatter function
},
// formatter function
radius
:
1
,
// radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
radius
:
1
,
// radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
background
:
{
background
:
{
...
@@ -745,20 +785,21 @@ More detail and specific examples can be found in the included HTML file.
...
@@ -745,20 +785,21 @@ More detail and specific examples can be found in the included HTML file.
combine
:
{
combine
:
{
threshold
:
-
1
,
// percentage at which to combine little slices into one larger slice
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)
color
:
null
,
// color to give the new slice (auto-generated if null)
label
:
'Other'
// label to give the new slice
label
:
"Other"
// label to give the new slice
},
},
highlight
:
{
highlight
:
{
//color:
'#FFF'
, // will add this functionality once parseColor is available
//color:
"#fff"
, // will add this functionality once parseColor is available
opacity
:
0.5
opacity
:
0.5
}
}
}
}
}
}
};
};
$
.
plot
.
plugins
.
push
({
$
.
plot
.
plugins
.
push
({
init
:
init
,
init
:
init
,
options
:
options
,
options
:
options
,
name
:
"pie"
,
name
:
"pie"
,
version
:
"1.
0
"
version
:
"1.
1
"
});
});
})(
jQuery
);
})(
jQuery
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment