Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
sdkjs
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boris Kocherov
sdkjs
Commits
addf2669
Commit
addf2669
authored
Dec 15, 2016
by
GoshaZotov
Committed by
GitHub
Dec 15, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #90 from ONLYOFFICE/Feature/3d_perspective_pie
Feature/3d perspective pie
parents
3328c59d
d621e895
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
1394 additions
and
826 deletions
+1394
-826
common/Charts/3DTransformation.js
common/Charts/3DTransformation.js
+90
-12
common/Charts/ChartsDrawer.js
common/Charts/ChartsDrawer.js
+1304
-814
No files found.
common/Charts/3DTransformation.js
View file @
addf2669
...
...
@@ -90,11 +90,10 @@ function Processor3D(width, height, left, right, bottom, top, chartSpace, charts
this
.
angleOy
=
this
.
view3D
&&
this
.
view3D
.
rotY
?
(
-
this
.
view3D
.
rotY
/
360
)
*
(
Math
.
PI
*
2
)
:
0
;
this
.
angleOz
=
this
.
view3D
&&
this
.
view3D
.
rotZ
?
(
-
this
.
view3D
.
rotZ
/
360
)
*
(
Math
.
PI
*
2
)
:
0
;
/*if(this.view3D.rAngAx && this.view3D.rotX < 0
)
if
(
!
this
.
view3D
.
rAngAx
&&
AscFormat
.
c_oChartTypes
.
Pie
===
this
.
chartsDrawer
.
calcProp
.
type
)
{
this.angleOx = - this.angleOx;
this.angleOy = - this.angleOy;
}*/
this
.
angleOy
=
0
;
}
this
.
orientationCatAx
=
null
;
this
.
orientationValAx
=
null
;
...
...
@@ -139,6 +138,55 @@ Processor3D.prototype.calaculate3DProperties = function(baseDepth, gapDepth, bIs
this
.
_recalculateScaleWithMaxWidth
();
}
}
if
(
AscFormat
.
c_oChartTypes
.
Pie
===
this
.
chartsDrawer
.
calcProp
.
type
&&
!
this
.
view3D
.
rAngAx
)
{
//TODO пересмотреть функцию
this
.
tempChangeAspectRatioForPie
();
}
};
Processor3D
.
prototype
.
tempChangeAspectRatioForPie
=
function
()
{
var
perspectiveDepth
=
this
.
depthPerspective
;
var
widthCanvas
=
this
.
widthCanvas
;
var
originalWidthChart
=
widthCanvas
-
this
.
left
-
this
.
right
;
var
heightCanvas
=
this
.
heightCanvas
;
var
heightChart
=
heightCanvas
-
this
.
top
-
this
.
bottom
;
var
points
=
[],
faces
=
[];
points
.
push
(
new
Point3D
(
this
.
left
+
originalWidthChart
/
2
,
this
.
top
,
perspectiveDepth
,
this
));
points
.
push
(
new
Point3D
(
this
.
left
,
this
.
top
,
perspectiveDepth
/
2
,
this
));
points
.
push
(
new
Point3D
(
this
.
left
+
originalWidthChart
,
this
.
top
,
perspectiveDepth
/
2
,
this
));
points
.
push
(
new
Point3D
(
this
.
left
+
originalWidthChart
/
2
,
this
.
top
,
0
,
this
));
points
.
push
(
new
Point3D
(
this
.
left
+
originalWidthChart
/
2
,
this
.
top
+
heightChart
,
perspectiveDepth
,
this
));
points
.
push
(
new
Point3D
(
this
.
left
,
this
.
top
+
heightChart
,
perspectiveDepth
/
2
,
this
));
points
.
push
(
new
Point3D
(
this
.
left
+
originalWidthChart
,
this
.
top
+
heightChart
,
perspectiveDepth
/
2
,
this
));
points
.
push
(
new
Point3D
(
this
.
left
+
originalWidthChart
/
2
,
this
.
top
+
heightChart
,
0
,
this
));
faces
.
push
([
0
,
1
,
2
,
3
]);
faces
.
push
([
2
,
5
,
4
,
3
]);
faces
.
push
([
1
,
6
,
7
,
0
]);
faces
.
push
([
6
,
5
,
4
,
7
]);
faces
.
push
([
7
,
4
,
3
,
0
]);
faces
.
push
([
1
,
6
,
2
,
5
]);
var
minMaxOx
=
this
.
_getMinMaxOx
(
points
,
faces
);
var
minMaxOy
=
this
.
_getMinMaxOy
(
points
,
faces
);
var
kF
=
((
minMaxOx
.
right
-
minMaxOx
.
left
)
/
originalWidthChart
);
if
((
minMaxOy
.
bottom
-
minMaxOy
.
top
)
/
kF
>
heightChart
)
{
kF
=
((
minMaxOy
.
bottom
-
minMaxOy
.
top
)
/
heightChart
);
}
this
.
aspectRatioX
=
this
.
aspectRatioX
*
kF
;
this
.
aspectRatioY
=
this
.
aspectRatioY
*
kF
;
this
.
aspectRatioZ
=
this
.
aspectRatioZ
*
kF
;
};
Processor3D
.
prototype
.
calculateCommonOptions
=
function
()
...
...
@@ -157,6 +205,13 @@ Processor3D.prototype._calculateAutoHPercent = function()
this
.
hPercent
=
this
.
view3D
.
hPercent
===
null
?
(
heightLine
/
widthLine
)
:
this
.
view3D
.
hPercent
/
100
;
if
(
this
.
chartsDrawer
.
calcProp
.
type
===
AscFormat
.
c_oChartTypes
.
HBar
&&
((
this
.
view3D
.
hPercent
===
null
&&
this
.
view3D
.
rAngAx
)
||
(
this
.
view3D
.
hPercent
!==
null
&&
!
this
.
view3D
.
rAngAx
)))
this
.
hPercent
=
1
/
this
.
hPercent
;
if
(
AscFormat
.
c_oChartTypes
.
Pie
===
this
.
chartsDrawer
.
calcProp
.
type
)
{
this
.
hPercent
=
0.12
;
//this.view3D.depthPercent = 180;
}
}
};
...
...
@@ -1107,6 +1162,12 @@ Processor3D.prototype._calculateDepthPerspective = function()
var
gapWidth
=
this
.
chartSpace
.
chart
.
plotArea
.
chart
.
gapWidth
!=
null
?
(
this
.
chartSpace
.
chart
.
plotArea
.
chart
.
gapWidth
/
100
)
:
(
150
/
100
);
var
gapDepth
=
this
.
chartSpace
.
chart
.
plotArea
.
chart
.
gapDepth
!=
null
?
(
this
.
chartSpace
.
chart
.
plotArea
.
chart
.
gapDepth
/
100
)
:
(
150
/
100
);
if
(
AscFormat
.
c_oChartTypes
.
Area
===
this
.
chartsDrawer
.
calcProp
.
type
)
{
gapWidth
=
0
;
gapDepth
=
0
;
}
var
baseDepth
=
width
/
(
seriesCount
-
(
seriesCount
-
1
)
*
overlap
+
gapWidth
);
if
(
this
.
chartsDrawer
.
calcProp
.
subType
==
"
standard
"
||
this
.
chartsDrawer
.
calcProp
.
type
==
AscFormat
.
c_oChartTypes
.
Line
||
isNormalArea
)
baseDepth
=
(
width
/
(
seriesCount
-
(
seriesCount
-
1
)
*
overlap
+
gapWidth
))
*
seriesCount
;
...
...
@@ -1187,6 +1248,21 @@ Processor3D.prototype._calculateCameraDiff = function (/*isSkip*/)
//add test points for parallelepiped rect
var
points
=
[];
var
faces
=
[];
/*if(AscFormat.c_oChartTypes.Pie === this.chartsDrawer.calcProp.type)
{
points.push(new Point3D(this.left + originalWidthChart / 2, this.top, perspectiveDepth, this));
points.push(new Point3D(this.left, this.top, perspectiveDepth / 2, this));
points.push(new Point3D(this.left + originalWidthChart, this.top, perspectiveDepth / 2, this));
points.push(new Point3D(this.left + originalWidthChart / 2, this.top, 0, this));
points.push(new Point3D(this.left + originalWidthChart / 2, this.top + heightChart, perspectiveDepth, this));
points.push(new Point3D(this.left, this.top + heightChart, perspectiveDepth / 2, this));
points.push(new Point3D(this.left + originalWidthChart, this.top + heightChart, perspectiveDepth / 2, this));
points.push(new Point3D(this.left + originalWidthChart / 2, this.top + heightChart, 0, this));
}
else
{*/
points
.
push
(
new
Point3D
(
this
.
left
,
this
.
top
,
perspectiveDepth
,
this
));
points
.
push
(
new
Point3D
(
this
.
left
,
heightChart
+
this
.
top
,
perspectiveDepth
,
this
));
points
.
push
(
new
Point3D
(
originalWidthChart
+
this
.
left
,
heightChart
+
this
.
top
,
perspectiveDepth
,
this
));
...
...
@@ -1195,6 +1271,7 @@ Processor3D.prototype._calculateCameraDiff = function (/*isSkip*/)
points
.
push
(
new
Point3D
(
originalWidthChart
+
this
.
left
,
heightChart
+
this
.
top
,
0
,
this
));
points
.
push
(
new
Point3D
(
this
.
left
,
heightChart
+
this
.
top
,
0
,
this
));
points
.
push
(
new
Point3D
(
this
.
left
,
this
.
top
,
0
,
this
));
//}
faces
.
push
([
0
,
1
,
2
,
3
]);
faces
.
push
([
2
,
5
,
4
,
3
]);
...
...
@@ -1449,6 +1526,7 @@ Processor3D.prototype.checkOutSideArea = function(newPoints)
}
};
calculateZ
(
100
);
calculateZ
(
10
);
calculateZ
(
1
);
...
...
common/Charts/ChartsDrawer.js
View file @
addf2669
...
...
@@ -2532,7 +2532,16 @@ CChartsDrawer.prototype =
if
(
numCache
!=
null
&&
numCache
.
pts
&&
numCache
.
pts
.
length
)
{
if
(
!
this
.
calcProp
.
ptCount
)
{
if
(
AscFormat
.
c_oChartTypes
.
Pie
===
this
.
calcProp
.
type
)
{
this
.
calcProp
.
ptCount
=
1
;
}
else
{
this
.
calcProp
.
ptCount
=
numCache
.
ptCount
;
}
}
//TODO возможно нужно будет проверку добавить на isHidden
counter
++
;
...
...
@@ -2543,6 +2552,11 @@ CChartsDrawer.prototype =
}
}
if
(
AscFormat
.
c_oChartTypes
.
Pie
===
this
.
calcProp
.
type
)
{
counter
=
1
;
}
return
counter
;
},
...
...
@@ -3111,7 +3125,7 @@ CChartsDrawer.prototype =
{
res
=
true
;
}
else
if
(
isPerspective
&&
(
isBar
||
isLine
||
isHBar
||
isArea
))
else
if
(
isPerspective
&&
(
isBar
||
isLine
||
isHBar
||
isArea
||
isPie
))
{
res
=
true
;
}
...
...
@@ -5923,7 +5937,6 @@ drawAreaChart.prototype =
{
//ширина линии
var
brush
;
var
FillUniColor
;
var
pen
;
var
seria
,
dataSeries
;
...
...
@@ -7067,7 +7080,6 @@ drawHBarChart.prototype =
_DrawBars3D
:
function
()
{
var
t
=
this
;
var
processor3D
=
this
.
cChartDrawer
.
processor3D
;
var
drawVerges
=
function
(
i
,
j
,
paths
,
onlyLessNull
,
k
,
isNotPen
,
isNotBrush
)
{
...
...
@@ -7431,6 +7443,8 @@ function drawPieChart()
this
.
angleFor3D
=
null
;
this
.
properties3d
=
null
;
this
.
usually3dPropsCalc
=
[];
this
.
tempDrawOrder
=
null
;
}
drawPieChart
.
prototype
=
...
...
@@ -7463,13 +7477,20 @@ drawPieChart.prototype =
this
.
paths
=
{};
if
(
this
.
cChartDrawer
.
nDimensionCount
===
3
)
{
if
(
this
.
cChartDrawer
.
processor3D
.
view3D
.
rAngAx
)
{
this
.
properties3d
=
this
.
cChartDrawer
.
processor3D
.
calculatePropertiesForPieCharts
();
this
.
_re
с
alculatePie3D
();
this
.
_recalculatePie3D
();
}
else
{
this
.
_recalculatePie3DPerspective
();
}
}
else
{
this
.
_re
с
alculatePie
();
this
.
_re
c
alculatePie
();
}
},
...
...
@@ -7489,92 +7510,7 @@ drawPieChart.prototype =
}
},
_drawPie3D_Slow
:
function
()
{
var
numCache
=
this
.
_getFirstRealNumCache
();
var
props
=
this
.
cChartSpace
.
getParentObjects
();
var
brush
,
pen
,
val
;
var
path
;
for
(
var
n
=
0
;
n
<
this
.
paths
.
series
.
length
;
n
++
)
{
for
(
var
i
=
0
,
len
=
numCache
.
length
;
i
<
len
;
i
++
)
{
val
=
numCache
[
i
];
brush
=
val
.
brush
;
if
(
n
===
0
||
n
===
this
.
paths
.
series
.
length
-
1
)
{
pen
=
val
.
pen
;
}
else
{
pen
=
null
;
}
path
=
this
.
paths
.
series
[
n
][
i
];
var
duplicateBrush
=
brush
;
if
(
n
!==
this
.
paths
.
series
.
length
-
1
)
{
var
duplicateBrush
=
brush
.
createDuplicate
();
var
cColorMod
=
new
AscFormat
.
CColorMod
;
cColorMod
.
val
=
35000
;
cColorMod
.
name
=
"
shade
"
;
duplicateBrush
.
addColorMod
(
cColorMod
);
duplicateBrush
.
calculate
(
props
.
theme
,
props
.
slide
,
props
.
layout
,
props
.
master
,
new
AscFormat
.
CUniColor
().
RGBA
);
}
this
.
cChartDrawer
.
drawPath
(
path
,
pen
,
duplicateBrush
);
}
}
},
_re
с
alculatePie3D_Slow
:
function
()
{
var
trueWidth
=
this
.
chartProp
.
trueWidth
;
var
trueHeight
=
this
.
chartProp
.
trueHeight
;
var
numCache
=
this
.
_getFirstRealNumCache
();
var
sumData
=
this
.
cChartDrawer
.
_getSumArray
(
numCache
,
true
);
var
radius
=
Math
.
min
(
trueHeight
,
trueWidth
)
/
2
;
if
(
radius
<
0
)
radius
=
0
;
var
xCenter
=
this
.
chartProp
.
chartGutter
.
_left
+
trueWidth
/
2
;
var
yCenter
=
this
.
chartProp
.
chartGutter
.
_top
+
trueHeight
/
2
;
var
startAngle
=
this
.
cChartDrawer
.
processor3D
.
angleOy
?
this
.
cChartDrawer
.
processor3D
.
angleOy
:
0
;
var
startAngle3D
=
startAngle
!==
0
&&
startAngle
!==
undefined
?
this
.
_changeAngle
(
radius
,
Math
.
PI
/
2
,
startAngle
,
xCenter
,
yCenter
,
this
.
properties3d
)
:
0
;
this
.
tempAngle
=
Math
.
PI
/
2
+
startAngle
;
this
.
angleFor3D
=
Math
.
PI
/
2
-
startAngle3D
;
//рисуем против часовой стрелки, поэтому цикл с конца
var
depth
=
this
.
properties3d
.
depth
;
for
(
var
n
=
0
;
n
<
depth
;
n
++
)
{
if
(
!
this
.
paths
.
series
)
this
.
paths
.
series
=
[];
for
(
var
i
=
numCache
.
length
-
1
;
i
>=
0
;
i
--
)
{
var
angle
=
Math
.
abs
((
parseFloat
(
numCache
[
i
].
val
/
sumData
))
*
(
Math
.
PI
*
2
));
if
(
!
this
.
paths
.
series
[
n
])
this
.
paths
.
series
[
n
]
=
[];
if
(
sumData
===
0
)
//TODO стоит пересмотреть
this
.
paths
.
series
[
n
][
i
]
=
this
.
_calculateEmptySegment
(
radius
,
xCenter
,
yCenter
);
else
this
.
paths
.
series
[
n
][
i
]
=
this
.
_calculateSegment3D
(
angle
,
radius
,
xCenter
,
yCenter
,
n
,
i
);
}
}
},
_re
с
alculatePie
:
function
()
_recalculatePie
:
function
()
{
var
trueWidth
=
this
.
chartProp
.
trueWidth
;
var
trueHeight
=
this
.
chartProp
.
trueHeight
;
...
...
@@ -7599,7 +7535,7 @@ drawPieChart.prototype =
this
.
paths
.
series
[
i
]
=
this
.
_calculateEmptySegment
(
radius
,
xCenter
,
yCenter
);
else
this
.
paths
.
series
[
i
]
=
this
.
_calculateSegment
(
angle
,
radius
,
xCenter
,
yCenter
);
}
;
}
},
_getFirstRealNumCache
:
function
()
...
...
@@ -7633,22 +7569,6 @@ drawPieChart.prototype =
return
path
;
},
_calculateSegment3D_Slow
:
function
(
angle
,
radius
,
xCenter
,
yCenter
,
depth
,
i
)
{
if
(
isNaN
(
angle
))
return
null
;
var
startAngle
=
(
this
.
tempAngle
);
var
swapAngle
=
angle
;
var
endAngle
=
startAngle
+
angle
;
var
path
=
this
.
_calculateArc3D
(
radius
,
startAngle
,
swapAngle
,
xCenter
,
yCenter
,
depth
,
i
);
this
.
tempAngle
+=
angle
;
return
path
;
},
_calculateEmptySegment
:
function
(
radius
,
xCenter
,
yCenter
)
{
var
path
=
new
Path
();
...
...
@@ -7703,74 +7623,8 @@ drawPieChart.prototype =
return
path
;
},
_calculateArc3D_Slow
:
function
(
radius
,
stAng
,
swAng
,
xCenter
,
yCenter
,
depth
,
seriaNum
)
{
var
radius1
=
this
.
properties3d
.
radius1
;
var
radius2
=
this
.
properties3d
.
radius2
;
var
pxToMm
=
this
.
chartProp
.
pxToMM
;
var
t
=
this
;
var
x0
,
y0
,
radiusSpec
;
var
calculateProps
=
function
()
{
if
(
t
.
usually3dPropsCalc
&&
t
.
usually3dPropsCalc
[
seriaNum
])
{
swAng
=
t
.
usually3dPropsCalc
[
seriaNum
].
swAng
;
stAng
=
t
.
usually3dPropsCalc
[
seriaNum
].
stAng
;
radiusSpec
=
t
.
usually3dPropsCalc
[
seriaNum
].
radiusSpec
;
x0
=
t
.
usually3dPropsCalc
[
seriaNum
].
x0
;
yCenter
=
yCenter
+
t
.
properties3d
.
depth
/
2
-
depth
;
y0
=
(
yCenter
-
radiusSpec
*
Math
.
sin
(
stAng
));
}
else
{
swAng
=
t
.
_changeAngle
(
radius
,
stAng
,
swAng
,
xCenter
,
yCenter
,
t
.
properties3d
);
stAng
=
t
.
angleFor3D
;
//корректируем центр
yCenter
=
yCenter
+
t
.
properties3d
.
depth
/
2
-
depth
;
radiusSpec
=
(
radius1
*
radius2
)
/
Math
.
sqrt
(
Math
.
pow
(
radius2
,
2
)
*
Math
.
pow
((
Math
.
cos
(
stAng
)),
2
)
+
Math
.
pow
(
radius1
,
2
)
*
Math
.
pow
(
Math
.
sin
(
stAng
),
2
));
x0
=
(
xCenter
+
radiusSpec
*
Math
.
cos
(
stAng
));
y0
=
(
yCenter
-
radiusSpec
*
Math
.
sin
(
stAng
));
}
};
var
path
=
new
Path
();
var
pathH
=
this
.
chartProp
.
pathH
;
var
pathW
=
this
.
chartProp
.
pathW
;
var
gdLst
=
[];
path
.
pathH
=
pathH
;
path
.
pathW
=
pathW
;
gdLst
[
"
w
"
]
=
1
;
gdLst
[
"
h
"
]
=
1
;
calculateProps
();
path
.
moveTo
(
xCenter
/
pxToMm
*
pathW
,
yCenter
/
pxToMm
*
pathH
);
path
.
lnTo
(
x0
/
pxToMm
*
pathW
,
y0
/
pxToMm
*
pathH
);
path
.
arcTo
(
radius1
/
pxToMm
*
pathW
,
radius2
/
pxToMm
*
pathH
,
-
1
*
stAng
*
cToDeg
,
-
1
*
swAng
*
cToDeg
);
path
.
lnTo
(
xCenter
/
pxToMm
*
pathW
,
yCenter
/
pxToMm
*
pathH
);
path
.
recalculate
(
gdLst
);
this
.
angleFor3D
+=
swAng
;
if
(
!
this
.
usually3dPropsCalc
[
seriaNum
])
this
.
usually3dPropsCalc
[
seriaNum
]
=
{
swAng
:
swAng
,
stAng
:
stAng
,
xCenter
:
xCenter
,
x0
:
x0
,
radiusSpec
:
radiusSpec
};
return
path
;
},
_changeAngle
:
function
(
radius
,
stAng
,
swAng
,
xCenter
,
yCenter
,
properties
)
_changeAngle
:
function
(
radius
,
stAng
,
swAng
,
xCenter
,
yCenter
,
depth
,
radius1
,
radius2
)
{
var
depth
=
properties
.
depth
;
var
radius1
=
properties
.
radius1
;
var
radius2
=
properties
.
radius2
;
//корректируем центр
yCenter
=
yCenter
-
depth
/
2
;
...
...
@@ -7780,9 +7634,9 @@ drawPieChart.prototype =
var
kFY
=
radius
/
radius2
;
var
cX
;
if
(
this
.
cX
!==
null
)
cX
=
this
.
cX
;
else
if
(
x0
<
xCenter
)
//
if(this.cX !== null)
//
cX = this.cX;
if
(
x0
<
xCenter
)
cX
=
xCenter
-
(
xCenter
-
x0
)
/
kFX
;
else
if
(
x0
>
xCenter
)
cX
=
xCenter
+
(
x0
-
xCenter
)
/
kFX
;
...
...
@@ -7790,9 +7644,9 @@ drawPieChart.prototype =
cX
=
xCenter
;
var
cY
;
if
(
this
.
cY
!==
null
)
cY
=
this
.
cY
;
else
if
(
y0
<
yCenter
)
//
if(this.cY !== null)
//
cY = this.cY;
if
(
y0
<
yCenter
)
cY
=
yCenter
-
(
yCenter
-
y0
)
/
kFY
;
else
if
(
y0
>
yCenter
)
cY
=
yCenter
+
(
y0
-
yCenter
)
/
kFY
;
...
...
@@ -7843,572 +7697,472 @@ drawPieChart.prototype =
return
res
;
},
_calculateBestFitPosition
:
function
(
fStartAngle
,
fSweepAngle
,
fRadius
,
fWidth
,
fHeight
,
fCenterX
,
fCenterY
,
bLayout
){
var
fStartAngle_
=
fStartAngle
;
var
fEndAngle
=
fStartAngle
+
fSweepAngle
;
if
(
bLayout
){
return
this
.
_calculateBestFitPositionOuter
(
fStartAngle_
,
fEndAngle
,
fRadius
,
fWidth
,
fHeight
,
fCenterX
,
fCenterY
);
_calculateDLbl
:
function
(
chartSpace
,
ser
,
val
,
bLayout
)
{
var
pxToMm
=
this
.
chartProp
.
pxToMM
;
//TODO сделать через idx как у drawDoughnutChart!!!
if
(
!
this
.
paths
.
series
[
val
])
return
;
var
path
;
if
(
this
.
cChartDrawer
.
nDimensionCount
===
3
)
{
if
(
this
.
paths
.
series
[
val
][
ser
]
&&
this
.
paths
.
series
[
val
][
ser
].
upPath
)
{
path
=
this
.
paths
.
series
[
val
][
ser
].
upPath
.
ArrPathCommand
;
}
var
oRet
=
this
.
_calculateBestFitPositionInner
(
fStartAngle_
,
fEndAngle
,
fRadius
,
fWidth
,
fHeight
,
fCenterX
,
fCenterY
);
if
(
!
oRet
.
bError
){
if
(
AscFormat
.
fCheckBoxIntersectionSegment
(
oRet
.
fX
,
oRet
.
fY
,
fWidth
,
fHeight
,
fCenterX
,
fCenterY
,
fCenterX
+
fRadius
*
Math
.
cos
(
fStartAngle_
),
fCenterY
+
fRadius
*
Math
.
sin
(
fStartAngle_
))
||
AscFormat
.
fCheckBoxIntersectionSegment
(
oRet
.
fX
,
oRet
.
fY
,
fWidth
,
fHeight
,
fCenterX
,
fCenterY
,
fCenterX
+
fRadius
*
Math
.
cos
(
fEndAngle
),
fCenterY
+
fRadius
*
Math
.
sin
(
fEndAngle
))){
oRet
.
bError
=
true
;
}
else
{
path
=
this
.
paths
.
series
[
val
].
ArrPathCommand
;
}
if
(
oRet
.
bError
){
return
this
.
_calculateBestFitPositionOuter
(
fStartAngle_
,
fEndAngle
,
fRadius
,
fWidth
,
fHeight
,
fCenterX
,
fCenterY
);
if
(
!
path
)
{
return
;
}
return
oRet
;
},
_calculateBestFitPositionInner
:
function
(
fStartAngle
,
fEndAngle
,
fPieRadius
,
fLabelWidth
,
fLabelHeight
,
fCenterX
,
fCenterY
){
var
oResult
=
{
bError
:
true
};
var
fBisectAngle
=
AscFormat
.
normalizeRotate
((
fStartAngle
+
fEndAngle
)
/
2.0
);
var
getEllipseRadius
=
function
(
radius1
,
radius2
,
alpha
)
{
var
a
=
radius1
*
radius2
;
var
b
=
Math
.
sqrt
(
Math
.
pow
(
radius2
,
2
)
*
Math
.
pow
(
Math
.
cos
(
alpha
),
2
)
+
Math
.
pow
(
radius1
,
2
)
*
Math
.
pow
(
Math
.
sin
(
alpha
),
2
));
var
res
=
a
/
b
;
if
(
AscFormat
.
fApproxEqual
(
fBisectAngle
,
0
)
||
AscFormat
.
fApproxEqual
(
fBisectAngle
,
Math
.
PI
/
2
)
||
AscFormat
.
fApproxEqual
(
fBisectAngle
,
Math
.
PI
)
||
AscFormat
.
fApproxEqual
(
fBisectAngle
,
3
*
Math
.
PI
/
2
)){
return
this
.
_calculateInEndDLblPosition
(
fStartAngle
,
fStartAngle
+
fEndAngle
,
fPieRadius
,
fLabelWidth
,
fLabelHeight
,
fCenterX
,
fCenterY
);
return
res
;
};
var
centerX
=
path
[
0
].
X
;
var
centerY
=
path
[
0
].
Y
;
var
radius
=
path
[
2
].
hR
;
var
stAng
=
path
[
2
].
stAng
;
var
swAng
=
path
[
2
].
swAng
;
if
(
this
.
cChartDrawer
.
nDimensionCount
===
3
&&
path
[
2
].
wR
)
{
radius
=
getEllipseRadius
(
path
[
2
].
hR
,
path
[
2
].
wR
,
-
1
*
stAng
-
swAng
/
2
-
Math
.
PI
/
2
);
}
var
fBisectAngle2
=
AscFormat
.
normalizeRotate
(
fBisectAngle
+
Math
.
PI
/
4
)
-
Math
.
PI
/
4
;
var
nIndexArea
=
((
fBisectAngle2
+
Math
.
PI
/
4
)
/
(
Math
.
PI
/
2
))
>>
0
;
var
point
=
this
.
chartProp
.
series
[
0
].
val
.
numRef
?
this
.
chartProp
.
series
[
0
].
val
.
numRef
.
numCache
.
pts
[
val
]
:
this
.
chartProp
.
series
[
0
].
val
.
numLit
.
pts
[
val
];
var
fLengthCoeff
=
((
fBisectAngle2
+
Math
.
PI
/
4
)
-
(
Math
.
PI
/
2
)
*
nIndexArea
)
/
(
Math
.
PI
/
2
);
if
(
!
point
)
return
;
var
fXs
=
fCenterX
+
fPieRadius
*
Math
.
cos
(
fBisectAngle
);
var
fYs
=
fCenterY
+
fPieRadius
*
Math
.
sin
(
fBisectAngle
);
var
fDeltaX
,
fDeltaY
,
oSolvation
;
var
width
=
point
.
compiledDlb
.
extX
;
var
height
=
point
.
compiledDlb
.
extY
;
switch
(
nIndexArea
){
case
0
:{
if
(
fBisectAngle2
<
0
){
fDeltaX
=
fLabelWidth
;
fDeltaY
=
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
var
tempCenterX
,
tempCenterY
;
//TODO высчитать позиции, как в екселе + ограничения
switch
(
point
.
compiledDlb
.
dLblPos
)
{
case
c_oAscChartDataLabelsPos
.
bestFit
:
{
var
oPos
=
this
.
_calculateBestFitPosition
(
stAng
,
swAng
,
radius
,
width
,
height
,
centerX
,
centerY
,
bLayout
);
if
(
!
oPos
.
bError
){
centerX
=
oPos
.
fX
;
centerY
=
oPos
.
fY
;
}
else
{
fDeltaX
=
fLabelWidth
;
fDeltaY
=
fLabelHeight
*
fLengthCoeff
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>
0
&&
oSolvation
.
x1
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
);
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
centerX
=
centerX
+
(
radius
/
2
)
*
Math
.
cos
(
-
1
*
stAng
-
swAng
/
2
)
-
width
/
2
;
centerY
=
centerY
-
(
radius
/
2
)
*
Math
.
sin
(
-
1
*
stAng
-
swAng
/
2
)
-
height
/
2
;
}
else
if
(
oSolvation
.
x2
>
0
&&
oSolvation
.
x2
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
);
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
break
;
}
case
c_oAscChartDataLabelsPos
.
ctr
:
{
centerX
=
centerX
+
(
radius
/
2
)
*
Math
.
cos
(
-
1
*
stAng
-
swAng
/
2
)
-
width
/
2
;
centerY
=
centerY
-
(
radius
/
2
)
*
Math
.
sin
(
-
1
*
stAng
-
swAng
/
2
)
-
height
/
2
;
break
;
}
case
c_oAscChartDataLabelsPos
.
inBase
:
{
centerX
=
centerX
+
(
radius
/
2
)
*
Math
.
cos
(
-
1
*
stAng
-
swAng
/
2
)
-
width
/
2
;
centerY
=
centerY
-
(
radius
/
2
)
*
Math
.
sin
(
-
1
*
stAng
-
swAng
/
2
)
-
height
/
2
;
break
;
}
case
1
:{
if
(
fBisectAngle
<
Math
.
PI
/
2
){
fDeltaX
=
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
fDeltaY
=
fLabelHeight
;
case
c_oAscChartDataLabelsPos
.
inEnd
:
{
var
oPos
=
this
.
_calculateInEndDLblPosition
(
stAng
,
swAng
,
radius
,
width
,
height
,
centerX
,
centerY
);
if
(
!
oPos
.
bError
){
centerX
=
oPos
.
fX
;
centerY
=
oPos
.
fY
;
break
;
}
else
{
fDeltaX
=
-
fLengthCoeff
*
fLabelWidth
;
fDeltaY
=
fLabelHeight
;
tempCenterX
=
centerX
+
(
radius
)
*
Math
.
cos
(
-
1
*
stAng
-
swAng
/
2
);
tempCenterY
=
centerY
-
(
radius
)
*
Math
.
sin
(
-
1
*
stAng
-
swAng
/
2
);
if
(
tempCenterX
<
centerX
&&
tempCenterY
<
centerY
)
{
centerX
=
tempCenterX
;
centerY
=
tempCenterY
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>
0
&&
oSolvation
.
x1
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
);
else
if
(
tempCenterX
>
centerX
&&
tempCenterY
<
centerY
)
{
centerX
=
tempCenterX
-
width
;
centerY
=
tempCenterY
;
}
else
if
(
oSolvation
.
x2
>
0
&&
oSolvation
.
x2
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
;
else
if
(
tempCenterX
<
centerX
&&
tempCenterY
>
centerY
)
{
centerX
=
tempCenterX
;
centerY
=
tempCenterY
-
height
;
}
else
{
centerX
=
tempCenterX
-
width
;
centerY
=
tempCenterY
-
height
;
}
break
;
}
case
2
:{
if
(
fBisectAngle
<
Math
.
PI
){
fDeltaX
=
-
fLabelWidth
;
fDeltaY
=
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
else
{
fDeltaX
=
-
fLabelWidth
;
fDeltaY
=
-
fLengthCoeff
*
fLabelHeight
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>
0
&&
oSolvation
.
x1
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
fLabelHeight
*
fLengthCoeff
;
case
c_oAscChartDataLabelsPos
.
outEnd
:
{
tempCenterX
=
centerX
+
(
radius
)
*
Math
.
cos
(
-
1
*
stAng
-
swAng
/
2
);
tempCenterY
=
centerY
-
(
radius
)
*
Math
.
sin
(
-
1
*
stAng
-
swAng
/
2
);
if
(
tempCenterX
<
centerX
&&
tempCenterY
<
centerY
)
{
centerX
=
tempCenterX
-
width
;
centerY
=
tempCenterY
-
height
;
}
else
if
(
oSolvation
.
x2
>
0
&&
oSolvation
.
x2
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
fLabelHeight
*
fLengthCoeff
;
}
}
break
;
else
if
(
tempCenterX
>
centerX
&&
tempCenterY
<
centerY
)
{
centerX
=
tempCenterX
;
centerY
=
tempCenterY
-
height
;
}
case
3
:{
fLengthCoeff
=
1
-
fLengthCoeff
;
if
(
fBisectAngle
<
3
*
Math
.
PI
/
2
){
fDeltaX
=
-
fLabelWidth
*
fLengthCoeff
;
fDeltaY
=
-
fLabelHeight
;
else
if
(
tempCenterX
<
centerX
&&
tempCenterY
>
centerY
)
{
centerX
=
tempCenterX
-
width
;
centerY
=
tempCenterY
;
}
else
{
fDeltaX
=
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
fDeltaY
=
-
fLabelHeight
;
else
{
centerX
=
tempCenterX
;
centerY
=
tempCenterY
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>
0
&&
oSolvation
.
x1
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
fLabelHeight
;
break
;
}
else
if
(
oSolvation
.
x2
>
0
&&
oSolvation
.
x2
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
fLabelHeight
;
}
if
(
centerX
<
0
)
centerX
=
0
;
if
(
centerX
+
width
>
this
.
chartProp
.
widthCanvas
/
pxToMm
)
centerX
=
this
.
chartProp
.
widthCanvas
/
pxToMm
-
width
;
if
(
centerY
<
0
)
centerY
=
0
;
if
(
centerY
+
height
>
this
.
chartProp
.
heightCanvas
/
pxToMm
)
centerY
=
this
.
chartProp
.
heightCanvas
/
pxToMm
-
height
;
return
{
x
:
centerX
,
y
:
centerY
};
},
//****fast calulate and drawing(for switch on slow drawing: change name function _Slow)
_recalculatePie3D
:
function
()
{
var
trueWidth
=
this
.
chartProp
.
trueWidth
;
var
trueHeight
=
this
.
chartProp
.
trueHeight
;
var
numCache
=
this
.
_getFirstRealNumCache
();
var
sumData
=
this
.
cChartDrawer
.
_getSumArray
(
numCache
,
true
);
var
radius
=
Math
.
min
(
trueHeight
,
trueWidth
)
/
2
;
if
(
radius
<
0
)
{
radius
=
0
;
}
break
;
var
xCenter
=
this
.
chartProp
.
chartGutter
.
_left
+
trueWidth
/
2
;
var
yCenter
=
this
.
chartProp
.
chartGutter
.
_top
+
trueHeight
/
2
;
var
startAngle
=
this
.
cChartDrawer
.
processor3D
.
angleOy
?
this
.
cChartDrawer
.
processor3D
.
angleOy
:
0
;
var
startAngle3D
=
startAngle
!==
0
&&
startAngle
!==
undefined
?
this
.
_changeAngle
(
radius
,
Math
.
PI
/
2
,
startAngle
,
xCenter
,
yCenter
,
this
.
properties3d
.
depth
,
this
.
properties3d
.
radius1
,
this
.
properties3d
.
radius2
)
:
0
;
this
.
angleFor3D
=
Math
.
PI
/
2
-
startAngle3D
;
startAngle
=
startAngle
+
Math
.
PI
/
2
;
for
(
var
i
=
numCache
.
length
-
1
;
i
>=
0
;
i
--
)
{
var
partOfSum
=
numCache
[
i
].
val
/
sumData
;
var
swapAngle
=
Math
.
abs
((
parseFloat
(
partOfSum
))
*
(
Math
.
PI
*
2
));
if
(
!
this
.
paths
.
series
)
{
this
.
paths
.
series
=
[];
}
this
.
paths
.
series
[
i
]
=
this
.
_calculateSegment3D
(
startAngle
,
swapAngle
,
radius
,
xCenter
,
yCenter
);
startAngle
+=
swapAngle
;
}
return
oResult
;
},
_calculateBestFitPositionOuter
:
function
(
fStartAngle
,
fEndAngle
,
fPieRadius
,
fLabelWidth
,
fLabelHeight
,
fCenterX
,
fCenterY
){
var
oResult
=
{
bError
:
true
};
var
fBisectAngle
=
AscFormat
.
normalizeRotate
((
fStartAngle
+
fEndAngle
)
/
2.0
);
var
fBisectAngle2
=
AscFormat
.
normalizeRotate
(
fBisectAngle
+
Math
.
PI
/
4
)
-
Math
.
PI
/
4
;
var
nIndexArea
=
((
fBisectAngle2
+
Math
.
PI
/
4
)
/
(
Math
.
PI
/
2
))
>>
0
;
_recalculatePie3DPerspective
:
function
()
{
var
left
=
this
.
chartProp
.
chartGutter
.
_left
;
var
right
=
this
.
chartProp
.
chartGutter
.
_right
;
var
top
=
this
.
chartProp
.
chartGutter
.
_top
;
var
bottom
=
this
.
chartProp
.
chartGutter
.
_bottom
;
var
trueWidth
=
this
.
chartProp
.
trueWidth
;
var
fLengthCoeff
=
((
fBisectAngle2
+
Math
.
PI
/
4
)
-
(
Math
.
PI
/
2
)
*
nIndexArea
)
/
(
Math
.
PI
/
2
);
var
widthCanvas
=
this
.
chartProp
.
widthCanvas
;
var
heightCanvas
=
this
.
chartProp
.
heightCanvas
;
var
fXs
=
fCenterX
+
fPieRadius
*
Math
.
cos
(
fBisectAngle
);
var
fYs
=
fCenterY
+
fPieRadius
*
Math
.
sin
(
fBisectAngle
);
var
fDeltaX
,
fDeltaY
,
oSolvation
;
var
height
=
heightCanvas
-
(
top
+
bottom
);
var
width
=
widthCanvas
-
(
left
+
right
);
var
fAngleApproxDelta
=
1
e
-
4
;
switch
(
nIndexArea
){
case
0
:{
if
(
AscFormat
.
fApproxEqual
(
fBisectAngle2
,
0
,
fAngleApproxDelta
)){
fDeltaX
=
0
;
fDeltaY
=
0
;
var
tempDepth
=
this
.
cChartDrawer
.
processor3D
.
depthPerspective
;
var
x1
=
left
,
y1
=
top
+
height
,
z1
=
0
;
var
x2
=
left
,
y2
=
top
,
z2
=
0
;
var
x3
=
left
+
width
,
y3
=
top
,
z3
=
0
;
var
x4
=
left
+
width
,
y4
=
top
+
height
,
z4
=
0
;
var
x5
=
left
,
y5
=
top
+
height
,
z5
=
tempDepth
;
var
x6
=
left
,
y6
=
top
,
z6
=
tempDepth
;
var
x7
=
left
+
width
,
y7
=
top
,
z7
=
tempDepth
;
var
x8
=
left
+
width
,
y8
=
top
+
height
,
z8
=
tempDepth
;
var
point1
=
this
.
cChartDrawer
.
_convertAndTurnPoint
(
x1
,
y1
,
z1
);
var
point2
=
this
.
cChartDrawer
.
_convertAndTurnPoint
(
x2
,
y2
,
z2
);
//var point3 = this.cChartDrawer._convertAndTurnPoint(x3, y3, z3);
//var point4 = this.cChartDrawer._convertAndTurnPoint(x4, y4, z4);
var
point5
=
this
.
cChartDrawer
.
_convertAndTurnPoint
(
x5
,
y5
,
z5
);
var
point6
=
this
.
cChartDrawer
.
_convertAndTurnPoint
(
x6
,
y6
,
z6
);
//var point7 = this.cChartDrawer._convertAndTurnPoint(x7, y7, z7);
//var point8 = this.cChartDrawer._convertAndTurnPoint(x8, y8, z8);
var
radius3D1
=
(
z6
-
z2
)
/
2
;
var
radius3D2
=
(
z5
-
z1
)
/
2
;
var
center3D1
=
new
Point3D
(
x2
+
((
x3
-
x2
)
/
2
),
y2
,
z2
+
(
radius3D1
));
var
center3D2
=
new
Point3D
(
x1
+
((
x4
-
x1
)
/
2
),
y1
,
z1
+
(
radius3D2
));
var
pointCenter1
=
this
.
cChartDrawer
.
_convertAndTurnPoint
(
center3D1
.
x
,
center3D1
.
y
,
center3D1
.
z
);
var
pointCenter2
=
this
.
cChartDrawer
.
_convertAndTurnPoint
(
center3D2
.
x
,
center3D2
.
y
,
center3D2
.
z
);
//TEST DRAW FRAME
//this._calculateTestFrame(point1, point2, point3, point4, point5, point6, point7, point8);
var
test1
=
this
.
cChartDrawer
.
_convertAndTurnPoint
(
x2
,
y2
,
center3D1
.
z
);
var
test2
=
this
.
cChartDrawer
.
_convertAndTurnPoint
(
x3
,
y3
,
center3D1
.
z
);
var
test11
=
this
.
cChartDrawer
.
_convertAndTurnPoint
(
x4
,
y4
,
center3D2
.
z
);
var
test22
=
this
.
cChartDrawer
.
_convertAndTurnPoint
(
x1
,
y1
,
center3D2
.
z
);
var
radius11
=
Math
.
abs
((
test2
.
x
-
test1
.
x
)
/
2
);
var
radius12
=
Math
.
abs
((
point6
.
y
-
point2
.
y
)
/
2
);
var
radius21
=
Math
.
abs
((
test22
.
x
-
test11
.
x
)
/
2
);
var
radius22
=
Math
.
abs
((
point5
.
y
-
point1
.
y
)
/
2
);
var
center1
=
{
x
:
this
.
chartProp
.
chartGutter
.
_left
+
trueWidth
/
2
,
y
:
(
point2
.
y
-
point6
.
y
)
/
2
+
point6
.
y
};
var
center2
=
{
x
:
this
.
chartProp
.
chartGutter
.
_left
+
trueWidth
/
2
,
y
:
(
point1
.
y
-
point5
.
y
)
/
2
+
point5
.
y
};
var
angles1
=
this
.
_calculateAngles3DPerspective
(
center1
.
x
,
center1
.
y
,
radius11
,
radius12
,
radius3D1
,
center3D1
);
var
angles2
=
this
.
_calculateAngles3DPerspective
(
center2
.
x
,
center2
.
y
,
radius21
,
radius22
,
radius3D2
,
center3D2
);
if
(
!
this
.
paths
.
series
)
{
this
.
paths
.
series
=
[];
}
else
if
(
fBisectAngle2
<
0
){
fDeltaX
=
0
;
fDeltaY
=
fLengthCoeff
*
fLabelHeight
;
for
(
var
i
=
0
;
i
<
angles1
.
length
;
i
++
)
{
var
start
=
angles1
[
i
].
start
;
var
start1
=
angles2
[
i
].
start
;
if
(
i
===
angles1
.
length
-
1
)
{
var
end
=
angles1
[
0
].
start
+
2
*
Math
.
PI
;
angles1
[
i
].
swap
=
end
-
start
;
var
end1
=
angles2
[
0
].
start
+
2
*
Math
.
PI
;
angles2
[
i
].
swap
=
end1
-
start1
;
}
else
{
fDeltaX
=
0
;
fDeltaY
=
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
var
paths
=
this
.
_calculateSegment3DPerspective
(
radius11
,
radius12
,
radius21
,
radius22
,
angles1
[
i
],
angles2
[
i
],
center1
,
center2
,
pointCenter1
,
pointCenter2
,
Math
.
sign
(
point2
.
y
-
point6
.
y
));
if
(
null
===
this
.
tempDrawOrder
)
{
this
.
tempDrawOrder
=
Math
.
sign
(
point2
.
y
-
point6
.
y
)
<
0
?
true
:
null
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
);
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
if
(
!
this
.
paths
.
series
[
angles1
.
length
-
i
-
1
])
{
this
.
paths
.
series
[
angles1
.
length
-
i
-
1
]
=
[];
}
else
if
(
oSolvation
.
x2
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
);
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
else
if
(
oSolvation
.
x1
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
);
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
else
if
(
oSolvation
.
x2
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
);
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
}
break
;
}
case
1
:{
if
(
AscFormat
.
fApproxEqual
(
fBisectAngle
,
Math
.
PI
/
2
,
fAngleApproxDelta
)){
fDeltaX
=
0
;
fDeltaY
=
0
;
}
else
if
(
fBisectAngle
<
Math
.
PI
/
2
){
fDeltaX
=
-
fLengthCoeff
*
fLabelWidth
;
fDeltaY
=
0
;
this
.
paths
.
series
[
angles1
.
length
-
i
-
1
].
push
(
paths
);
}
else
{
fDeltaX
=
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
fDeltaY
=
0
;
},
_calculateAngles3DPerspective
:
function
(
xCenter
,
yCenter
,
radius1
,
radius2
,
radius3D1
,
center3D1
)
{
var
t
=
this
;
var
widthCanvas
=
this
.
chartProp
.
widthCanvas
;
var
numCache
=
this
.
_getFirstRealNumCache
();
var
sumData
=
this
.
cChartDrawer
.
_getSumArray
(
numCache
,
true
);
var
startAngle
=
Math
.
PI
/
2
;
var
newStartAngle
=
startAngle
;
var
firstAngle
=
this
.
cChartSpace
.
chart
.
view3D
&&
this
.
cChartSpace
.
chart
.
view3D
.
rotY
?
(
-
this
.
cChartSpace
.
chart
.
view3D
.
rotY
/
360
)
*
(
Math
.
PI
*
2
)
:
0
;
var
getAngleByCoordsSidesTriangle
=
function
(
aC
,
bC
,
cC
)
{
var
res
;
var
a
=
Math
.
sqrt
(
Math
.
pow
(
aC
.
x
,
2
)
+
Math
.
pow
(
aC
.
y
,
2
));
var
b
=
Math
.
sqrt
(
Math
.
pow
(
bC
.
x
,
2
)
+
Math
.
pow
(
bC
.
y
,
2
));
var
c
=
Math
.
sqrt
(
Math
.
pow
(
cC
.
x
,
2
)
+
Math
.
pow
(
cC
.
y
,
2
));
res
=
Math
.
acos
((
Math
.
pow
(
b
,
2
)
+
Math
.
pow
(
c
,
2
)
-
Math
.
pow
(
a
,
2
))
/
(
2
*
b
*
c
));
return
res
;
};
var
getPointsByAngle
=
function
(
angle
)
{
var
point1
=
t
.
cChartDrawer
.
_convertAndTurnPoint
(
center3D1
.
x
+
radius3D1
*
Math
.
cos
(
angle
),
center3D1
.
y
,
center3D1
.
z
+
radius3D1
*
Math
.
sin
(
angle
));
var
y11
=
point1
.
y
;
var
x11
=
Math
.
sqrt
(
Math
.
abs
(
Math
.
pow
(
radius1
,
2
)
*
(
1
-
(
Math
.
pow
(
y11
-
(
yCenter
),
2
)
/
Math
.
pow
(
radius2
,
2
)))));
var
x111
;
if
((
angle
<=
3
*
Math
.
PI
/
2
&&
angle
>=
Math
.
PI
/
2
)
||
(
angle
>=
-
3
*
Math
.
PI
/
2
&&
angle
<=
-
Math
.
PI
/
2
))
{
x111
=
xCenter
-
x11
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
);
else
{
x111
=
widthCanvas
-
(
xCenter
-
x11
)
}
else
if
(
oSolvation
.
x2
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
);
return
{
x
:
x111
,
y
:
y11
};
};
var
angles
=
[];
for
(
var
i
=
numCache
.
length
;
i
>=
0
;
i
--
)
{
//рассчитываем угол
if
(
i
===
numCache
.
length
)
{
var
swapAngle
=
firstAngle
}
else
if
(
oSolvation
.
x1
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
);
else
{
var
partOfSum
=
numCache
[
i
].
val
/
sumData
;
var
swapAngle
=
Math
.
abs
((
parseFloat
(
partOfSum
))
*
(
Math
.
PI
*
2
)
);
}
else
if
(
oSolvation
.
x2
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
);
var
tempSwapAngle
=
0
,
newSwapAngle
=
0
,
tempStartAngle
=
startAngle
;
while
(
true
)
{
if
(
i
===
numCache
.
length
&&
swapAngle
<
0
)
{
if
(
tempStartAngle
-
Math
.
PI
/
2
>
startAngle
+
swapAngle
)
{
tempSwapAngle
=
-
Math
.
PI
/
2
;
}
else
{
tempSwapAngle
=
(
startAngle
+
swapAngle
)
-
tempStartAngle
;
}
break
;
}
case
2
:{
if
(
AscFormat
.
fApproxEqual
(
fBisectAngle
,
Math
.
PI
,
fAngleApproxDelta
)){
fDeltaX
=
0
;
fDeltaY
=
0
;
else
{
if
(
tempStartAngle
+
Math
.
PI
/
2
<
startAngle
+
swapAngle
)
{
tempSwapAngle
=
Math
.
PI
/
2
;
}
else
if
(
fBisectAngle
<
Math
.
PI
){
fDeltaX
=
0
;
fDeltaY
=
-
fLengthCoeff
*
fLabelHeight
;
else
{
tempSwapAngle
=
(
startAngle
+
swapAngle
)
-
tempStartAngle
;
}
else
{
fDeltaX
=
0
;
fDeltaY
=
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
fLabelHeight
*
fLengthCoeff
;
}
else
if
(
oSolvation
.
x2
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
fLabelHeight
*
fLengthCoeff
;
}
else
if
(
oSolvation
.
x1
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
fLabelHeight
*
fLengthCoeff
;
var
p1
=
getPointsByAngle
(
tempStartAngle
);
var
p2
=
getPointsByAngle
(
tempStartAngle
+
tempSwapAngle
);
newSwapAngle
+=
getAngleByCoordsSidesTriangle
({
x
:
p2
.
x
-
p1
.
x
,
y
:
p2
.
y
-
p1
.
y
},
{
x
:
xCenter
-
p1
.
x
,
y
:
yCenter
-
p1
.
y
},
{
x
:
xCenter
-
p2
.
x
,
y
:
yCenter
-
p2
.
y
});
if
(
i
===
numCache
.
length
&&
swapAngle
<
0
)
{
if
(
tempStartAngle
-
Math
.
PI
/
2
>
startAngle
+
swapAngle
)
{
tempStartAngle
-=
Math
.
PI
/
2
;
}
else
if
(
oSolvation
.
x2
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
fLabelHeight
*
fLengthCoeff
;
}
}
else
{
if
(
i
!==
numCache
.
length
)
angles
.
push
({
start
:
newStartAngle
,
swap
:
newSwapAngle
,
end
:
newStartAngle
+
newSwapAngle
});
break
;
}
case
3
:{
if
(
fBisectAngle
<
3
*
Math
.
PI
/
2
){
fDeltaX
=
fLabelWidth
*
fLengthCoeff
;
fDeltaY
=
0
;
}
else
{
fDeltaX
=
-
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
fDeltaY
=
0
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
fLabelHeight
;
}
else
if
(
oSolvation
.
x2
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
fLabelHeight
;
}
else
if
(
oSolvation
.
x1
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
fLabelHeight
;
}
else
if
(
oSolvation
.
x2
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
fLabelHeight
;
}
}
break
;
}
else
{
if
(
tempStartAngle
+
Math
.
PI
/
2
<
startAngle
+
swapAngle
)
{
tempStartAngle
+=
Math
.
PI
/
2
;
}
return
oResult
;
},
else
{
if
(
i
!==
numCache
.
length
)
angles
.
push
({
start
:
newStartAngle
,
swap
:
newSwapAngle
,
end
:
newStartAngle
+
newSwapAngle
});
_calculateInEndDLblPosition
:
function
(
fStartAngle
,
fSweepAngle
,
fPieRadius
,
fLabelWidth
,
fLabelHeight
,
fCenterX
,
fCenterY
){
var
fEndAngle
=
fStartAngle
+
fSweepAngle
;
var
oResult
=
{
bError
:
true
,
fX
:
0.0
,
fY
:
0.0
};
var
fBisectAngle
=
AscFormat
.
normalizeRotate
((
fStartAngle
+
fEndAngle
)
/
2
);
var
nQuadrantIndex
=
(
2.0
*
fBisectAngle
/
Math
.
PI
)
>>
0
;
var
fHalfRectWidthVector
=
fLabelWidth
/
2
,
fHalfRectHeightVector
=
fLabelHeight
/
2
;
if
(
nQuadrantIndex
===
1
||
nQuadrantIndex
==
2
){
fHalfRectWidthVector
=
-
fHalfRectWidthVector
;
break
;
}
if
(
nQuadrantIndex
===
2
||
nQuadrantIndex
==
3
){
fHalfRectHeightVector
=
-
fHalfRectHeightVector
;
}
var
fXs
=
fCenterX
+
fPieRadius
*
Math
.
cos
(
fBisectAngle
),
fYs
=
fCenterY
+
fPieRadius
*
Math
.
sin
(
fBisectAngle
);
var
a
=
fPieRadius
*
fPieRadius
,
b
=
2
*
(
(
fXs
-
fCenterX
)
*
fHalfRectWidthVector
+
(
fYs
-
fCenterY
)
*
fHalfRectHeightVector
),
c
=
fHalfRectWidthVector
*
fHalfRectWidthVector
+
fHalfRectHeightVector
*
fHalfRectHeightVector
-
fPieRadius
*
fPieRadius
;
var
oSolution
=
AscFormat
.
fSolveQuadraticEquation
(
a
,
b
,
c
);
if
(
oSolution
.
bError
){
return
oResult
;
}
var
D
=
b
*
b
-
4
*
a
*
c
;
if
(
D
<
0
){
return
oResult
;
}
var
t1
=
oSolution
.
x1
,
t2
=
oSolution
.
x2
;
if
(
t1
>
0
&&
t1
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
t1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
/
2
;
oResult
.
fY
=
fCenterY
+
t1
*
(
fYs
-
fCenterY
)
-
fLabelHeight
/
2
;
return
oResult
}
if
(
t2
>
0
&&
t2
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
t2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
/
2
;
oResult
.
fY
=
fCenterY
+
t2
*
(
fYs
-
fCenterY
)
-
fLabelHeight
/
2
;
return
oResult
}
return
oResult
;
},
_calculateDLbl
:
function
(
chartSpace
,
ser
,
val
,
bLayout
)
{
var
pxToMm
=
this
.
chartProp
.
pxToMM
;
//TODO сделать через idx как у drawDoughnutChart!!!
if
(
!
this
.
paths
.
series
[
val
])
return
;
var
path
;
if
(
this
.
cChartDrawer
.
nDimensionCount
===
3
)
startAngle
+=
swapAngle
;
if
(
i
===
numCache
.
length
)
{
if
(
this
.
paths
.
series
[
val
][
ser
]
&&
this
.
paths
.
series
[
val
][
ser
].
upPath
)
if
(
swapAngle
<
0
)
{
path
=
this
.
paths
.
series
[
val
][
ser
].
upPath
.
ArrPathCommand
;
}
newStartAngle
-=
newSwapAngle
;
}
else
{
path
=
this
.
paths
.
series
[
val
].
ArrPathCommand
;
newStartAngle
+=
newSwapAngle
;
}
if
(
!
path
)
}
else
{
return
;
newStartAngle
+=
newSwapAngle
;
}
}
var
getEllipseRadius
=
function
(
radius1
,
radius2
,
alpha
)
return
angles
;
},
_calculateArc3D
:
function
(
radius
,
stAng
,
swAng
,
xCenter
,
yCenter
,
bIsNotDrawFrontFace
,
depth
,
radius1
,
radius2
)
{
var
a
=
radius1
*
radius2
;
var
b
=
Math
.
sqrt
(
Math
.
pow
(
radius2
,
2
)
*
Math
.
pow
(
Math
.
cos
(
alpha
),
2
)
+
Math
.
pow
(
radius1
,
2
)
*
Math
.
pow
(
Math
.
sin
(
alpha
),
2
));
var
res
=
a
/
b
;
var
properties
=
this
.
cChartDrawer
.
processor3D
.
calculatePropertiesForPieCharts
();
return
res
;
};
depth
=
!
depth
?
properties
.
depth
:
depth
;
radius1
=
!
radius1
?
properties
.
radius1
:
radius1
;
radius2
=
!
radius2
?
properties
.
radius2
:
radius2
;
var
centerX
=
path
[
0
].
X
;
var
centerY
=
path
[
0
].
Y
;
var
radius
=
path
[
2
].
hR
;
var
stAng
=
path
[
2
].
stAng
;
var
swAng
=
path
[
2
].
swAng
;
if
(
this
.
cChartDrawer
.
nDimensionCount
===
3
&&
path
[
2
].
wR
)
{
radius
=
getEllipseRadius
(
path
[
2
].
hR
,
path
[
2
].
wR
,
-
1
*
stAng
-
swAng
/
2
-
Math
.
PI
/
2
);
}
var
pxToMm
=
this
.
chartProp
.
pxToMM
;
var
pathH
=
this
.
chartProp
.
pathH
;
var
pathW
=
this
.
chartProp
.
pathW
;
var
point
=
this
.
chartProp
.
series
[
0
].
val
.
numRef
?
this
.
chartProp
.
series
[
0
].
val
.
numRef
.
numCache
.
pts
[
val
]
:
this
.
chartProp
.
series
[
0
].
val
.
numLit
.
pts
[
val
];
var
gdLst
=
[];
gdLst
[
"
w
"
]
=
1
;
gdLst
[
"
h
"
]
=
1
;
if
(
!
point
)
return
;
var
constMargin
=
5
/
pxToMm
;
var
width
=
point
.
compiledDlb
.
extX
;
var
height
=
point
.
compiledDlb
.
extY
;
var
tempCenterX
,
tempCenterY
;
//TODO высчитать позиции, как в екселе + ограничения
switch
(
point
.
compiledDlb
.
dLblPos
)
{
case
c_oAscChartDataLabelsPos
.
bestFit
:
{
var
oPos
=
this
.
_calculateBestFitPosition
(
stAng
,
swAng
,
radius
,
width
,
height
,
centerX
,
centerY
,
bLayout
);
if
(
!
oPos
.
bError
){
centerX
=
oPos
.
fX
;
centerY
=
oPos
.
fY
;
}
else
{
centerX
=
centerX
+
(
radius
/
2
)
*
Math
.
cos
(
-
1
*
stAng
-
swAng
/
2
)
-
width
/
2
;
centerY
=
centerY
-
(
radius
/
2
)
*
Math
.
sin
(
-
1
*
stAng
-
swAng
/
2
)
-
height
/
2
;
}
break
;
}
case
c_oAscChartDataLabelsPos
.
ctr
:
{
centerX
=
centerX
+
(
radius
/
2
)
*
Math
.
cos
(
-
1
*
stAng
-
swAng
/
2
)
-
width
/
2
;
centerY
=
centerY
-
(
radius
/
2
)
*
Math
.
sin
(
-
1
*
stAng
-
swAng
/
2
)
-
height
/
2
;
break
;
}
case
c_oAscChartDataLabelsPos
.
inBase
:
{
centerX
=
centerX
+
(
radius
/
2
)
*
Math
.
cos
(
-
1
*
stAng
-
swAng
/
2
)
-
width
/
2
;
centerY
=
centerY
-
(
radius
/
2
)
*
Math
.
sin
(
-
1
*
stAng
-
swAng
/
2
)
-
height
/
2
;
break
;
}
case
c_oAscChartDataLabelsPos
.
inEnd
:
{
var
oPos
=
this
.
_calculateInEndDLblPosition
(
stAng
,
swAng
,
radius
,
width
,
height
,
centerX
,
centerY
);
if
(
!
oPos
.
bError
){
centerX
=
oPos
.
fX
;
centerY
=
oPos
.
fY
;
break
;
}
tempCenterX
=
centerX
+
(
radius
)
*
Math
.
cos
(
-
1
*
stAng
-
swAng
/
2
);
tempCenterY
=
centerY
-
(
radius
)
*
Math
.
sin
(
-
1
*
stAng
-
swAng
/
2
);
if
(
tempCenterX
<
centerX
&&
tempCenterY
<
centerY
)
{
centerX
=
tempCenterX
;
centerY
=
tempCenterY
;
}
else
if
(
tempCenterX
>
centerX
&&
tempCenterY
<
centerY
)
{
centerX
=
tempCenterX
-
width
;
centerY
=
tempCenterY
;
}
else
if
(
tempCenterX
<
centerX
&&
tempCenterY
>
centerY
)
{
centerX
=
tempCenterX
;
centerY
=
tempCenterY
-
height
;
}
else
{
centerX
=
tempCenterX
-
width
;
centerY
=
tempCenterY
-
height
;
}
break
;
}
case
c_oAscChartDataLabelsPos
.
outEnd
:
{
tempCenterX
=
centerX
+
(
radius
)
*
Math
.
cos
(
-
1
*
stAng
-
swAng
/
2
);
tempCenterY
=
centerY
-
(
radius
)
*
Math
.
sin
(
-
1
*
stAng
-
swAng
/
2
);
if
(
tempCenterX
<
centerX
&&
tempCenterY
<
centerY
)
{
centerX
=
tempCenterX
-
width
;
centerY
=
tempCenterY
-
height
;
}
else
if
(
tempCenterX
>
centerX
&&
tempCenterY
<
centerY
)
{
centerX
=
tempCenterX
;
centerY
=
tempCenterY
-
height
;
}
else
if
(
tempCenterX
<
centerX
&&
tempCenterY
>
centerY
)
{
centerX
=
tempCenterX
-
width
;
centerY
=
tempCenterY
;
}
else
{
centerX
=
tempCenterX
;
centerY
=
tempCenterY
;
}
break
;
}
}
if
(
centerX
<
0
)
centerX
=
0
;
if
(
centerX
+
width
>
this
.
chartProp
.
widthCanvas
/
pxToMm
)
centerX
=
this
.
chartProp
.
widthCanvas
/
pxToMm
-
width
;
if
(
centerY
<
0
)
centerY
=
0
;
if
(
centerY
+
height
>
this
.
chartProp
.
heightCanvas
/
pxToMm
)
centerY
=
this
.
chartProp
.
heightCanvas
/
pxToMm
-
height
;
return
{
x
:
centerX
,
y
:
centerY
};
},
//****fast calulate and drawing(for switch on slow drawing: change name function _Slow)
_re
с
alculatePie3D
:
function
()
{
var
trueWidth
=
this
.
chartProp
.
trueWidth
;
var
trueHeight
=
this
.
chartProp
.
trueHeight
;
var
numCache
=
this
.
_getFirstRealNumCache
();
var
sumData
=
this
.
cChartDrawer
.
_getSumArray
(
numCache
,
true
);
var
radius
=
Math
.
min
(
trueHeight
,
trueWidth
)
/
2
;
var
radius
=
Math
.
min
(
trueHeight
,
trueWidth
)
/
2
;
if
(
radius
<
0
)
{
radius
=
0
;
}
var
xCenter
=
this
.
chartProp
.
chartGutter
.
_left
+
trueWidth
/
2
;
var
yCenter
=
this
.
chartProp
.
chartGutter
.
_top
+
trueHeight
/
2
;
var
startAngle
=
this
.
cChartDrawer
.
processor3D
.
angleOy
?
this
.
cChartDrawer
.
processor3D
.
angleOy
:
0
;
var
startAngle3D
=
startAngle
!==
0
&&
startAngle
!==
undefined
?
this
.
_changeAngle
(
radius
,
Math
.
PI
/
2
,
startAngle
,
xCenter
,
yCenter
,
this
.
properties3d
)
:
0
;
this
.
angleFor3D
=
Math
.
PI
/
2
-
startAngle3D
;
startAngle
=
startAngle
+
Math
.
PI
/
2
;
for
(
var
i
=
numCache
.
length
-
1
;
i
>=
0
;
i
--
)
{
var
val
=
numCache
[
i
].
val
;
var
partOfSum
=
numCache
[
i
].
val
/
sumData
;
var
swapAngle
=
Math
.
abs
((
parseFloat
(
partOfSum
))
*
(
Math
.
PI
*
2
));
if
(
!
this
.
paths
.
series
)
{
this
.
paths
.
series
=
[];
}
this
.
paths
.
series
[
i
]
=
this
.
_calculateSegment3D
(
startAngle
,
swapAngle
,
radius
,
xCenter
,
yCenter
);
startAngle
+=
swapAngle
;
}
},
_calculateArc3D
:
function
(
radius
,
stAng
,
swAng
,
xCenter
,
yCenter
,
bIsNotDrawFrontFace
)
{
var
properties
=
this
.
cChartDrawer
.
processor3D
.
calculatePropertiesForPieCharts
();
var
depth
=
properties
.
depth
;
var
radius1
=
properties
.
radius1
;
var
radius2
=
properties
.
radius2
;
var
pxToMm
=
this
.
chartProp
.
pxToMM
;
var
pathH
=
this
.
chartProp
.
pathH
;
var
pathW
=
this
.
chartProp
.
pathW
;
var
t
=
this
;
var
gdLst
=
[];
gdLst
[
"
w
"
]
=
1
;
gdLst
[
"
h
"
]
=
1
;
swAng
=
this
.
_changeAngle
(
radius
,
stAng
,
swAng
,
xCenter
,
yCenter
,
properties
);
swAng
=
this
.
_changeAngle
(
radius
,
stAng
,
swAng
,
xCenter
,
yCenter
,
depth
,
radius1
,
radius2
);
stAng
=
this
.
angleFor3D
;
//корректируем центр
yCenter
=
yCenter
-
depth
/
2
;
...
...
@@ -8518,209 +8272,952 @@ drawPieChart.prototype =
var
endAng
=
startAng
+
swapAng
;
var
p
=
getSegmentPoints
(
startAng
,
endAng
);
path
.
moveTo
(
p
.
x0
/
pxToMm
*
pathW
,
p
.
y0
/
pxToMm
*
pathH
);
path
.
arcTo
(
radius1
/
pxToMm
*
pathW
,
radius2
/
pxToMm
*
pathH
,
-
1
*
startAng
*
cToDeg
,
-
1
*
swapAng
*
cToDeg
);
path
.
lnTo
(
p
.
x3
/
pxToMm
*
pathW
,
p
.
y3
/
pxToMm
*
pathH
);
path
.
arcTo
(
radius1
/
pxToMm
*
pathW
,
radius2
/
pxToMm
*
pathH
,
-
1
*
startAng
*
cToDeg
-
1
*
swapAng
*
cToDeg
,
1
*
swapAng
*
cToDeg
);
path
.
lnTo
(
p
.
x0
/
pxToMm
*
pathW
,
p
.
y0
/
pxToMm
*
pathH
);
path
.
recalculate
(
gdLst
);
path
.
moveTo
(
p
.
x0
/
pxToMm
*
pathW
,
p
.
y0
/
pxToMm
*
pathH
);
path
.
arcTo
(
radius1
/
pxToMm
*
pathW
,
radius2
/
pxToMm
*
pathH
,
-
1
*
startAng
*
cToDeg
,
-
1
*
swapAng
*
cToDeg
);
path
.
lnTo
(
p
.
x3
/
pxToMm
*
pathW
,
p
.
y3
/
pxToMm
*
pathH
);
path
.
arcTo
(
radius1
/
pxToMm
*
pathW
,
radius2
/
pxToMm
*
pathH
,
-
1
*
startAng
*
cToDeg
-
1
*
swapAng
*
cToDeg
,
1
*
swapAng
*
cToDeg
);
path
.
lnTo
(
p
.
x0
/
pxToMm
*
pathW
,
p
.
y0
/
pxToMm
*
pathH
);
path
.
recalculate
(
gdLst
);
return
path
;
};
var
calculateUpFace
=
function
(
startAng
,
swapAng
)
{
var
path
=
getNewPath
();
var
endAng
=
startAng
+
swapAng
;
var
p
=
getSegmentPoints
(
startAng
,
endAng
);
path
.
moveTo
(
xCenter
/
pxToMm
*
pathW
,
yCenter
/
pxToMm
*
pathH
);
path
.
lnTo
(
p
.
x0
/
pxToMm
*
pathW
,
p
.
y0
/
pxToMm
*
pathH
);
path
.
arcTo
(
radius1
/
pxToMm
*
pathW
,
radius2
/
pxToMm
*
pathH
,
-
1
*
stAng
*
cToDeg
,
-
1
*
swapAng
*
cToDeg
);
path
.
lnTo
(
xCenter
/
pxToMm
*
pathW
,
yCenter
/
pxToMm
*
pathH
);
path
.
recalculate
(
gdLst
);
return
path
;
};
var
calculateDownFace
=
function
(
startAng
,
swapAng
)
{
var
path
=
getNewPath
();
var
endAng
=
startAng
+
swapAng
;
var
p
=
getSegmentPoints
(
startAng
,
endAng
);
path
.
moveTo
(
xCenter
/
pxToMm
*
pathW
,
(
yCenter
+
depth
)
/
pxToMm
*
pathH
);
path
.
lnTo
(
p
.
x0
/
pxToMm
*
pathW
,
(
p
.
y0
+
depth
)
/
pxToMm
*
pathH
);
path
.
arcTo
(
radius1
/
pxToMm
*
pathW
,
radius2
/
pxToMm
*
pathH
,
-
1
*
stAng
*
cToDeg
,
-
1
*
swapAng
*
cToDeg
);
path
.
lnTo
(
xCenter
/
pxToMm
*
pathW
,
(
yCenter
+
depth
)
/
pxToMm
*
pathH
);
path
.
recalculate
(
gdLst
);
return
path
;
};
//FRONT FACES
//break front faces
var
arrAngles
=
breakAng
(
stAng
,
swAng
);
var
frontPath
=
[];
for
(
var
i
=
1
;
i
<
arrAngles
.
length
;
i
++
)
{
var
start
=
arrAngles
[
i
-
1
].
angle
;
var
end
=
arrAngles
[
i
].
angle
;
var
swap
=
end
-
start
;
if
((
start
>=
0
&&
start
>=
Math
.
PI
&&
start
<=
2
*
Math
.
PI
)
||
(
start
<
0
&&
start
>=
-
Math
.
PI
&&
start
<=
0
))
{
frontPath
.
push
(
calculateFrontFace
(
start
,
swap
));
}
}
//INSIDE FACES
var
insidePath
=
calculateInsideFaces
(
stAng
,
swAng
);
//UP FACE
var
upPath
=
calculateUpFace
(
stAng
,
swAng
);
//DOWN FACE
var
downPath
=
calculateDownFace
(
stAng
,
swAng
);
this
.
angleFor3D
+=
swAng
;
return
{
frontPath
:
frontPath
,
upPath
:
upPath
,
insidePath
:
insidePath
,
downPath
:
downPath
};
},
_calculateSegment3D
:
function
(
startAngle
,
swapAngle
,
radius
,
xCenter
,
yCenter
)
{
if
(
isNaN
(
swapAngle
))
{
return
null
;
}
if
(
radius
<
0
)
{
radius
=
0
;
}
var
path
=
[];
path
.
push
(
this
.
_calculateArc3D
(
radius
,
startAngle
,
swapAngle
,
xCenter
,
yCenter
));
return
path
;
},
_calculateSegment3DPerspective
:
function
(
radiusUp1
,
radiusUp2
,
radiusDown1
,
radiusDown2
,
angles1
,
angles2
,
center1
,
center2
,
pointCenter1
,
pointCenter2
,
upFaceSign
)
{
var
xCenter
=
center1
.
x
,
yCenter
=
center1
.
y
,
xCenter1
=
center2
.
x
,
yCenter1
=
center2
.
y
;
var
startAngle1
=
angles1
.
start
,
swapAngle1
=
angles1
.
swap
,
startAngle2
=
angles2
.
start
,
swapAngle2
=
angles2
.
swap
;
var
pxToMm
=
this
.
chartProp
.
pxToMM
;
var
pathH
=
this
.
chartProp
.
pathH
;
var
pathW
=
this
.
chartProp
.
pathW
;
var
gdLst
=
[];
gdLst
[
"
w
"
]
=
1
;
gdLst
[
"
h
"
]
=
1
;
var
getNewPath
=
function
()
{
var
path
=
new
Path
();
path
.
pathH
=
pathH
;
path
.
pathW
=
pathW
;
return
path
;
};
var
getSegmentPoints
=
function
(
startAng
,
endAng
,
startAng2
,
endAng2
)
{
var
radiusSpec
=
(
radiusUp1
*
radiusUp2
)
/
Math
.
sqrt
(
Math
.
pow
(
radiusUp2
,
2
)
*
Math
.
pow
((
Math
.
cos
(
startAng
)),
2
)
+
Math
.
pow
(
radiusUp1
,
2
)
*
Math
.
pow
(
Math
.
sin
(
startAng
),
2
));
var
radiusSpec2
=
(
radiusUp1
*
radiusUp2
)
/
Math
.
sqrt
(
Math
.
pow
(
radiusUp2
,
2
)
*
Math
.
pow
((
Math
.
cos
(
endAng
)),
2
)
+
Math
.
pow
(
radiusUp1
,
2
)
*
Math
.
pow
(
Math
.
sin
(
endAng
),
2
));
var
radiusSpec11
=
(
radiusDown1
*
radiusDown2
)
/
Math
.
sqrt
(
Math
.
pow
(
radiusDown2
,
2
)
*
Math
.
pow
((
Math
.
cos
(
startAng2
)),
2
)
+
Math
.
pow
(
radiusDown1
,
2
)
*
Math
.
pow
(
Math
.
sin
(
startAng2
),
2
));
var
radiusSpec12
=
(
radiusDown1
*
radiusDown2
)
/
Math
.
sqrt
(
Math
.
pow
(
radiusDown2
,
2
)
*
Math
.
pow
((
Math
.
cos
(
endAng2
)),
2
)
+
Math
.
pow
(
radiusDown1
,
2
)
*
Math
.
pow
(
Math
.
sin
(
endAng2
),
2
));
var
x0
=
(
xCenter
+
radiusSpec
*
Math
.
cos
(
startAng
));
var
y0
=
(
yCenter
-
radiusSpec
*
Math
.
sin
(
startAng
));
var
x1
=
(
xCenter1
+
radiusSpec11
*
Math
.
cos
(
startAng2
));
var
y1
=
((
yCenter1
)
-
radiusSpec11
*
Math
.
sin
(
startAng2
));
var
x2
=
(
xCenter
+
radiusSpec2
*
Math
.
cos
(
endAng
));
var
y2
=
(
yCenter
-
radiusSpec2
*
Math
.
sin
(
endAng
));
var
x3
=
(
xCenter1
+
radiusSpec12
*
Math
.
cos
(
endAng2
));
var
y3
=
((
yCenter1
)
-
radiusSpec12
*
Math
.
sin
(
endAng2
));
return
{
x0
:
x0
,
y0
:
y0
,
x1
:
x1
,
y1
:
y1
,
x2
:
x2
,
y2
:
y2
,
x3
:
x3
,
y3
:
y3
};
};
var
breakAng
=
function
(
startAng
,
swapAng
)
{
var
res
=
[];
var
endAng
=
startAng
+
swapAng
;
res
.
push
({
angle
:
startAng
});
var
tempStartAng
=
startAng
;
var
tempEndAng
=
endAng
;
var
tempPI
=
Math
.
PI
;
if
(
tempStartAng
<=
-
2
*
tempPI
&&
tempEndAng
>
-
2
*
tempPI
)
{
res
.
push
({
angle
:
-
2
*
Math
.
PI
});
}
if
(
tempStartAng
<=
-
tempPI
&&
tempEndAng
>
-
tempPI
)
{
res
.
push
({
angle
:
-
Math
.
PI
});
}
if
(
tempStartAng
<=
0
&&
tempEndAng
>
0
)
{
res
.
push
({
angle
:
0
});
}
if
(
tempStartAng
<=
tempPI
&&
tempEndAng
>
tempPI
)
{
res
.
push
({
angle
:
Math
.
PI
});
}
if
(
tempStartAng
<=
2
*
tempPI
&&
tempEndAng
>
2
*
tempPI
)
{
res
.
push
({
angle
:
2
*
Math
.
PI
});
}
res
.
push
({
angle
:
endAng
});
return
res
;
};
var
calculateInsideFaces
=
function
(
startAng1
,
swapAng1
,
startAng2
,
swapAng2
)
{
var
path
=
getNewPath
();
var
endAng1
=
startAng1
+
swapAng1
;
var
endAng2
=
startAng2
+
swapAng2
;
var
p
=
getSegmentPoints
(
startAng1
,
endAng1
,
startAng2
,
endAng2
);
path
.
moveTo
(
pointCenter1
.
x
/
pxToMm
*
pathW
,
pointCenter1
.
y
/
pxToMm
*
pathH
);
path
.
lnTo
(
p
.
x0
/
pxToMm
*
pathW
,
p
.
y0
/
pxToMm
*
pathH
);
path
.
lnTo
(
p
.
x1
/
pxToMm
*
pathW
,
p
.
y1
/
pxToMm
*
pathH
);
path
.
lnTo
(
pointCenter2
.
x
/
pxToMm
*
pathW
,
(
pointCenter2
.
y
)
/
pxToMm
*
pathH
);
path
.
moveTo
(
pointCenter1
.
x
/
pxToMm
*
pathW
,
pointCenter1
.
y
/
pxToMm
*
pathH
);
path
.
lnTo
(
p
.
x2
/
pxToMm
*
pathW
,
p
.
y2
/
pxToMm
*
pathH
);
path
.
lnTo
(
p
.
x3
/
pxToMm
*
pathW
,
p
.
y3
/
pxToMm
*
pathH
);
path
.
lnTo
(
pointCenter2
.
x
/
pxToMm
*
pathW
,
(
pointCenter2
.
y
)
/
pxToMm
*
pathH
);
path
.
recalculate
(
gdLst
);
return
path
;
};
var
calculateFrontFace
=
function
(
startAng
,
swapAng
,
startAng2
,
swapAng2
)
{
var
path
=
getNewPath
();
var
endAng
=
startAng
+
swapAng
;
var
endAng2
=
startAng2
+
swapAng2
;
var
p
=
getSegmentPoints
(
startAng
,
endAng
,
startAng2
,
endAng2
);
//var p2 = getSegmentPoints(startAng2, endAng2);
path
.
moveTo
(
p
.
x0
/
pxToMm
*
pathW
,
p
.
y0
/
pxToMm
*
pathH
);
path
.
arcTo
(
radiusUp1
/
pxToMm
*
pathW
,
radiusUp2
/
pxToMm
*
pathH
,
-
1
*
startAng
*
cToDeg
,
-
1
*
swapAng
*
cToDeg
);
path
.
lnTo
(
p
.
x3
/
pxToMm
*
pathW
,
p
.
y3
/
pxToMm
*
pathH
);
path
.
arcTo
(
radiusDown1
/
pxToMm
*
pathW
,
radiusDown2
/
pxToMm
*
pathH
,
-
1
*
startAng2
*
cToDeg
-
1
*
swapAng2
*
cToDeg
,
1
*
swapAng2
*
cToDeg
);
path
.
lnTo
(
p
.
x0
/
pxToMm
*
pathW
,
p
.
y0
/
pxToMm
*
pathH
);
path
.
recalculate
(
gdLst
);
return
path
;
};
var
calculateUpFace
=
function
(
startAng
,
swapAng
)
{
var
path
=
getNewPath
();
var
radiusSpec
=
(
radiusUp1
*
radiusUp2
)
/
Math
.
sqrt
(
Math
.
pow
(
radiusUp2
,
2
)
*
Math
.
pow
((
Math
.
cos
(
startAng
)),
2
)
+
Math
.
pow
(
radiusUp1
,
2
)
*
Math
.
pow
(
Math
.
sin
(
startAng
),
2
));
var
x0
=
(
xCenter
+
radiusSpec
*
Math
.
cos
(
startAng
));
var
y0
=
(
yCenter
-
radiusSpec
*
Math
.
sin
(
startAng
));
path
.
moveTo
(
pointCenter1
.
x
/
pxToMm
*
pathW
,
pointCenter1
.
y
/
pxToMm
*
pathH
);
path
.
lnTo
(
x0
/
pxToMm
*
pathW
,
y0
/
pxToMm
*
pathH
);
path
.
arcTo
(
radiusUp1
/
pxToMm
*
pathW
,
radiusUp2
/
pxToMm
*
pathH
,
-
1
*
startAng
*
cToDeg
,
-
1
*
swapAng
*
cToDeg
);
path
.
lnTo
(
pointCenter1
.
x
/
pxToMm
*
pathW
,
pointCenter1
.
y
/
pxToMm
*
pathH
);
path
.
recalculate
(
gdLst
);
return
path
;
};
var
calculateDownFace
=
function
(
startAng
,
swapAng
)
{
var
path
=
getNewPath
();
var
radiusSpec
=
(
radiusDown1
*
radiusDown2
)
/
Math
.
sqrt
(
Math
.
pow
(
radiusDown2
,
2
)
*
Math
.
pow
((
Math
.
cos
(
startAng
)),
2
)
+
Math
.
pow
(
radiusDown1
,
2
)
*
Math
.
pow
(
Math
.
sin
(
startAng
),
2
));
//var radiusSpec2 = (radius11 * radius2) / Math.sqrt(Math.pow(radius2, 2) * Math.pow((Math.cos(endAng)), 2) + Math.pow(radius11, 2) * Math.pow(Math.sin(endAng),2))
var
x
=
(
xCenter1
+
radiusSpec
*
Math
.
cos
(
startAng
));
var
y
=
(
yCenter1
-
radiusSpec
*
Math
.
sin
(
startAng
));
path
.
moveTo
(
pointCenter2
.
x
/
pxToMm
*
pathW
,
(
pointCenter2
.
y
)
/
pxToMm
*
pathH
);
path
.
lnTo
(
x
/
pxToMm
*
pathW
,
y
/
pxToMm
*
pathH
);
path
.
arcTo
(
radiusDown1
/
pxToMm
*
pathW
,
radiusDown2
/
pxToMm
*
pathH
,
-
1
*
startAng
*
cToDeg
,
-
1
*
swapAng
*
cToDeg
);
path
.
lnTo
(
pointCenter2
.
x
/
pxToMm
*
pathW
,
(
pointCenter2
.
y
)
/
pxToMm
*
pathH
);
path
.
recalculate
(
gdLst
);
return
path
;
};
//FRONT FACES
//break front faces
var
arrAngles
=
breakAng
(
startAngle1
,
swapAngle1
);
var
arrAngles2
=
breakAng
(
startAngle2
,
swapAngle2
);
var
frontPath
=
[];
for
(
var
i
=
1
;
i
<
arrAngles
.
length
;
i
++
)
{
var
start
=
arrAngles
[
i
-
1
].
angle
;
var
end
=
arrAngles
[
i
].
angle
;
var
swap
=
end
-
start
;
var
start2
=
arrAngles2
[
i
-
1
].
angle
;
var
end2
;
if
(
!
arrAngles2
[
i
])
{
end2
=
arrAngles2
[
i
-
1
].
angle
;
}
else
{
end2
=
arrAngles2
[
i
].
angle
;
}
var
swap2
=
end2
-
start2
;
if
((
start
>=
0
&&
start
>=
Math
.
PI
&&
start
<=
2
*
Math
.
PI
)
||
(
start
<
0
&&
start
>=
-
Math
.
PI
&&
start
<=
0
))
{
frontPath
.
push
(
calculateFrontFace
(
upFaceSign
*
start
,
upFaceSign
*
swap
,
start2
,
swap2
));
}
}
//INSIDE FACES
var
insidePath
=
calculateInsideFaces
(
upFaceSign
*
startAngle1
,
upFaceSign
*
swapAngle1
,
startAngle2
,
swapAngle2
);
//UP FACE
var
upPath
=
calculateUpFace
(
upFaceSign
*
startAngle1
,
upFaceSign
*
swapAngle1
);
//DOWN FACE
var
downPath
=
calculateDownFace
(
startAngle2
,
swapAngle2
);
return
{
frontPath
:
frontPath
,
upPath
:
upPath
,
insidePath
:
insidePath
,
downPath
:
downPath
};
},
_drawPie3D
:
function
()
{
var
numCache
=
this
.
_getFirstRealNumCache
();
var
t
=
this
;
var
shade
=
"
shade
"
;
var
shadeValue
=
35000
;
var
drawPath
=
function
(
path
,
pen
,
brush
,
isShadePen
,
isShadeBrush
)
{
if
(
path
)
{
if
(
brush
)
{
var
props
=
t
.
cChartSpace
.
getParentObjects
();
var
duplicateBrush
=
brush
.
createDuplicate
();
var
cColorMod
=
new
AscFormat
.
CColorMod
;
cColorMod
.
val
=
shadeValue
;
cColorMod
.
name
=
shade
;
if
(
duplicateBrush
)
{
duplicateBrush
.
addColorMod
(
cColorMod
);
duplicateBrush
.
calculate
(
props
.
theme
,
props
.
slide
,
props
.
layout
,
props
.
master
,
new
AscFormat
.
CUniColor
().
RGBA
);
}
if
(
isShadePen
)
{
pen
=
AscFormat
.
CreatePenFromParams
(
duplicateBrush
,
undefined
,
undefined
,
undefined
,
undefined
,
0
);
}
if
(
isShadeBrush
)
{
brush
=
duplicateBrush
;
}
}
t
.
cChartDrawer
.
drawPath
(
path
,
pen
,
brush
);
}
};
var
pen
=
numCache
[
0
].
pen
;
drawPath
(
this
.
paths
.
test
,
pen
,
null
);
var
sides
=
{
down
:
0
,
inside
:
1
,
up
:
2
,
front
:
3
};
var
drawPaths
=
function
(
side
)
{
for
(
var
i
=
0
,
len
=
numCache
.
length
;
i
<
len
;
i
++
)
{
var
val
=
numCache
[
i
];
var
brush
=
val
.
brush
;
var
pen
=
val
.
pen
;
var
path
=
t
.
paths
.
series
[
i
];
if
(
path
)
{
for
(
var
j
=
path
.
length
-
1
;
j
>=
0
;
j
--
)
{
if
(
side
===
sides
.
down
)
{
drawPath
(
path
[
j
].
downPath
,
pen
,
null
);
}
else
if
(
side
===
sides
.
inside
)
{
drawPath
(
path
[
j
].
insidePath
,
pen
,
brush
,
null
,
true
);
}
else
if
(
side
===
sides
.
up
)
{
drawPath
(
path
[
j
].
upPath
,
pen
,
brush
);
}
else
if
(
side
===
sides
.
frontPath
)
{
for
(
var
k
=
0
;
k
<
path
[
j
].
frontPath
.
length
;
k
++
)
{
drawPath
(
path
[
j
].
frontPath
[
k
],
pen
,
brush
,
true
,
true
);
}
}
}
}
}
};
drawPaths
(
sides
.
down
);
drawPaths
(
sides
.
inside
);
if
(
this
.
tempDrawOrder
!==
null
)
{
drawPaths
(
sides
.
up
);
drawPaths
(
sides
.
frontPath
);
}
else
{
drawPaths
(
sides
.
frontPath
);
drawPaths
(
sides
.
up
);
}
},
//best fit DLbl
_calculateBestFitPosition
:
function
(
fStartAngle
,
fSweepAngle
,
fRadius
,
fWidth
,
fHeight
,
fCenterX
,
fCenterY
,
bLayout
){
var
fStartAngle_
=
fStartAngle
;
var
fEndAngle
=
fStartAngle
+
fSweepAngle
;
if
(
bLayout
){
return
this
.
_calculateBestFitPositionOuter
(
fStartAngle_
,
fEndAngle
,
fRadius
,
fWidth
,
fHeight
,
fCenterX
,
fCenterY
);
}
var
oRet
=
this
.
_calculateBestFitPositionInner
(
fStartAngle_
,
fEndAngle
,
fRadius
,
fWidth
,
fHeight
,
fCenterX
,
fCenterY
);
if
(
!
oRet
.
bError
){
if
(
AscFormat
.
fCheckBoxIntersectionSegment
(
oRet
.
fX
,
oRet
.
fY
,
fWidth
,
fHeight
,
fCenterX
,
fCenterY
,
fCenterX
+
fRadius
*
Math
.
cos
(
fStartAngle_
),
fCenterY
+
fRadius
*
Math
.
sin
(
fStartAngle_
))
||
AscFormat
.
fCheckBoxIntersectionSegment
(
oRet
.
fX
,
oRet
.
fY
,
fWidth
,
fHeight
,
fCenterX
,
fCenterY
,
fCenterX
+
fRadius
*
Math
.
cos
(
fEndAngle
),
fCenterY
+
fRadius
*
Math
.
sin
(
fEndAngle
))){
oRet
.
bError
=
true
;
}
}
if
(
oRet
.
bError
){
return
this
.
_calculateBestFitPositionOuter
(
fStartAngle_
,
fEndAngle
,
fRadius
,
fWidth
,
fHeight
,
fCenterX
,
fCenterY
);
}
return
oRet
;
},
_calculateBestFitPositionInner
:
function
(
fStartAngle
,
fEndAngle
,
fPieRadius
,
fLabelWidth
,
fLabelHeight
,
fCenterX
,
fCenterY
){
var
oResult
=
{
bError
:
true
};
var
fBisectAngle
=
AscFormat
.
normalizeRotate
((
fStartAngle
+
fEndAngle
)
/
2.0
);
if
(
AscFormat
.
fApproxEqual
(
fBisectAngle
,
0
)
||
AscFormat
.
fApproxEqual
(
fBisectAngle
,
Math
.
PI
/
2
)
||
AscFormat
.
fApproxEqual
(
fBisectAngle
,
Math
.
PI
)
||
AscFormat
.
fApproxEqual
(
fBisectAngle
,
3
*
Math
.
PI
/
2
)){
return
this
.
_calculateInEndDLblPosition
(
fStartAngle
,
fStartAngle
+
fEndAngle
,
fPieRadius
,
fLabelWidth
,
fLabelHeight
,
fCenterX
,
fCenterY
);
}
var
fBisectAngle2
=
AscFormat
.
normalizeRotate
(
fBisectAngle
+
Math
.
PI
/
4
)
-
Math
.
PI
/
4
;
var
nIndexArea
=
((
fBisectAngle2
+
Math
.
PI
/
4
)
/
(
Math
.
PI
/
2
))
>>
0
;
var
fLengthCoeff
=
((
fBisectAngle2
+
Math
.
PI
/
4
)
-
(
Math
.
PI
/
2
)
*
nIndexArea
)
/
(
Math
.
PI
/
2
);
var
fXs
=
fCenterX
+
fPieRadius
*
Math
.
cos
(
fBisectAngle
);
var
fYs
=
fCenterY
+
fPieRadius
*
Math
.
sin
(
fBisectAngle
);
var
fDeltaX
,
fDeltaY
,
oSolvation
;
switch
(
nIndexArea
){
case
0
:{
if
(
fBisectAngle2
<
0
){
fDeltaX
=
fLabelWidth
;
fDeltaY
=
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
else
{
fDeltaX
=
fLabelWidth
;
fDeltaY
=
fLabelHeight
*
fLengthCoeff
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>
0
&&
oSolvation
.
x1
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
);
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
else
if
(
oSolvation
.
x2
>
0
&&
oSolvation
.
x2
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
);
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
}
break
;
}
case
1
:{
if
(
fBisectAngle
<
Math
.
PI
/
2
){
fDeltaX
=
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
fDeltaY
=
fLabelHeight
;
}
else
{
fDeltaX
=
-
fLengthCoeff
*
fLabelWidth
;
fDeltaY
=
fLabelHeight
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>
0
&&
oSolvation
.
x1
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
);
}
else
if
(
oSolvation
.
x2
>
0
&&
oSolvation
.
x2
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
);
}
}
break
;
}
case
2
:{
if
(
fBisectAngle
<
Math
.
PI
){
fDeltaX
=
-
fLabelWidth
;
fDeltaY
=
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
else
{
fDeltaX
=
-
fLabelWidth
;
fDeltaY
=
-
fLengthCoeff
*
fLabelHeight
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>
0
&&
oSolvation
.
x1
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
fLabelHeight
*
fLengthCoeff
;
}
else
if
(
oSolvation
.
x2
>
0
&&
oSolvation
.
x2
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
fLabelHeight
*
fLengthCoeff
;
}
}
break
;
}
case
3
:{
fLengthCoeff
=
1
-
fLengthCoeff
;
if
(
fBisectAngle
<
3
*
Math
.
PI
/
2
){
fDeltaX
=
-
fLabelWidth
*
fLengthCoeff
;
fDeltaY
=
-
fLabelHeight
;
}
else
{
fDeltaX
=
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
fDeltaY
=
-
fLabelHeight
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>
0
&&
oSolvation
.
x1
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
fLabelHeight
;
}
else
if
(
oSolvation
.
x2
>
0
&&
oSolvation
.
x2
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
fLabelHeight
;
}
}
break
;
}
}
return
oResult
;
},
_calculateBestFitPositionOuter
:
function
(
fStartAngle
,
fEndAngle
,
fPieRadius
,
fLabelWidth
,
fLabelHeight
,
fCenterX
,
fCenterY
){
var
oResult
=
{
bError
:
true
};
var
fBisectAngle
=
AscFormat
.
normalizeRotate
((
fStartAngle
+
fEndAngle
)
/
2.0
);
var
fBisectAngle2
=
AscFormat
.
normalizeRotate
(
fBisectAngle
+
Math
.
PI
/
4
)
-
Math
.
PI
/
4
;
var
nIndexArea
=
((
fBisectAngle2
+
Math
.
PI
/
4
)
/
(
Math
.
PI
/
2
))
>>
0
;
var
fLengthCoeff
=
((
fBisectAngle2
+
Math
.
PI
/
4
)
-
(
Math
.
PI
/
2
)
*
nIndexArea
)
/
(
Math
.
PI
/
2
);
var
fXs
=
fCenterX
+
fPieRadius
*
Math
.
cos
(
fBisectAngle
);
var
fYs
=
fCenterY
+
fPieRadius
*
Math
.
sin
(
fBisectAngle
);
var
fDeltaX
,
fDeltaY
,
oSolvation
;
var
fAngleApproxDelta
=
1
e
-
4
;
switch
(
nIndexArea
){
case
0
:{
if
(
AscFormat
.
fApproxEqual
(
fBisectAngle2
,
0
,
fAngleApproxDelta
)){
fDeltaX
=
0
;
fDeltaY
=
0
;
}
else
if
(
fBisectAngle2
<
0
){
fDeltaX
=
0
;
fDeltaY
=
fLengthCoeff
*
fLabelHeight
;
}
else
{
fDeltaX
=
0
;
fDeltaY
=
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
);
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
else
if
(
oSolvation
.
x2
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
);
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
else
if
(
oSolvation
.
x1
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
);
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
else
if
(
oSolvation
.
x2
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
);
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
}
break
;
}
case
1
:{
if
(
AscFormat
.
fApproxEqual
(
fBisectAngle
,
Math
.
PI
/
2
,
fAngleApproxDelta
)){
fDeltaX
=
0
;
fDeltaY
=
0
;
}
else
if
(
fBisectAngle
<
Math
.
PI
/
2
){
fDeltaX
=
-
fLengthCoeff
*
fLabelWidth
;
fDeltaY
=
0
;
}
else
{
fDeltaX
=
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
fDeltaY
=
0
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
);
}
else
if
(
oSolvation
.
x2
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
);
}
else
if
(
oSolvation
.
x1
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
);
}
else
if
(
oSolvation
.
x2
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
*
fLengthCoeff
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
);
}
}
break
;
}
case
2
:{
if
(
AscFormat
.
fApproxEqual
(
fBisectAngle
,
Math
.
PI
,
fAngleApproxDelta
)){
fDeltaX
=
0
;
fDeltaY
=
0
;
}
else
if
(
fBisectAngle
<
Math
.
PI
){
fDeltaX
=
0
;
fDeltaY
=
-
fLengthCoeff
*
fLabelHeight
;
}
else
{
fDeltaX
=
0
;
fDeltaY
=
(
1
-
fLengthCoeff
)
*
fLabelHeight
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
fLabelHeight
*
fLengthCoeff
;
}
else
if
(
oSolvation
.
x2
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
fLabelHeight
*
fLengthCoeff
;
}
else
if
(
oSolvation
.
x1
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
fLabelHeight
*
fLengthCoeff
;
}
else
if
(
oSolvation
.
x2
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
fLabelHeight
*
fLengthCoeff
;
}
}
break
;
}
case
3
:{
if
(
fBisectAngle
<
3
*
Math
.
PI
/
2
){
fDeltaX
=
fLabelWidth
*
fLengthCoeff
;
fDeltaY
=
0
;
}
else
{
fDeltaX
=
-
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
fDeltaY
=
0
;
}
oSolvation
=
AscFormat
.
fSolveQuadraticEquation
(
fPieRadius
*
fPieRadius
,
2
*
(
fDeltaX
*
(
fXs
-
fCenterX
)
+
fDeltaY
*
(
fYs
-
fCenterY
)),
fDeltaX
*
fDeltaX
+
fDeltaY
*
fDeltaY
-
fPieRadius
*
fPieRadius
);
if
(
!
oSolvation
.
bError
){
if
(
oSolvation
.
x1
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
fLabelHeight
;
}
else
if
(
oSolvation
.
x2
>=
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
fLabelHeight
;
}
else
if
(
oSolvation
.
x1
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x1
*
(
fXs
-
fCenterX
)
-
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x1
*
(
fYs
-
fCenterY
)
-
fLabelHeight
;
}
else
if
(
oSolvation
.
x2
>=
0
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
oSolvation
.
x2
*
(
fXs
-
fCenterX
)
-
(
1
-
fLengthCoeff
)
*
fLabelWidth
;
oResult
.
fY
=
fCenterY
+
oSolvation
.
x2
*
(
fYs
-
fCenterY
)
-
fLabelHeight
;
}
}
break
;
}
}
return
oResult
;
},
_calculateInEndDLblPosition
:
function
(
fStartAngle
,
fSweepAngle
,
fPieRadius
,
fLabelWidth
,
fLabelHeight
,
fCenterX
,
fCenterY
){
var
fEndAngle
=
fStartAngle
+
fSweepAngle
;
var
oResult
=
{
bError
:
true
,
fX
:
0.0
,
fY
:
0.0
};
var
fBisectAngle
=
AscFormat
.
normalizeRotate
((
fStartAngle
+
fEndAngle
)
/
2
);
var
nQuadrantIndex
=
(
2.0
*
fBisectAngle
/
Math
.
PI
)
>>
0
;
var
fHalfRectWidthVector
=
fLabelWidth
/
2
,
fHalfRectHeightVector
=
fLabelHeight
/
2
;
if
(
nQuadrantIndex
===
1
||
nQuadrantIndex
==
2
){
fHalfRectWidthVector
=
-
fHalfRectWidthVector
;
}
if
(
nQuadrantIndex
===
2
||
nQuadrantIndex
==
3
){
fHalfRectHeightVector
=
-
fHalfRectHeightVector
;
}
var
fXs
=
fCenterX
+
fPieRadius
*
Math
.
cos
(
fBisectAngle
),
fYs
=
fCenterY
+
fPieRadius
*
Math
.
sin
(
fBisectAngle
);
var
a
=
fPieRadius
*
fPieRadius
,
b
=
2
*
(
(
fXs
-
fCenterX
)
*
fHalfRectWidthVector
+
(
fYs
-
fCenterY
)
*
fHalfRectHeightVector
),
c
=
fHalfRectWidthVector
*
fHalfRectWidthVector
+
fHalfRectHeightVector
*
fHalfRectHeightVector
-
fPieRadius
*
fPieRadius
;
var
oSolution
=
AscFormat
.
fSolveQuadraticEquation
(
a
,
b
,
c
);
if
(
oSolution
.
bError
){
return
oResult
;
}
var
D
=
b
*
b
-
4
*
a
*
c
;
if
(
D
<
0
){
return
oResult
;
}
var
t1
=
oSolution
.
x1
,
t2
=
oSolution
.
x2
;
if
(
t1
>
0
&&
t1
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
t1
*
(
fXs
-
fCenterX
)
-
fLabelWidth
/
2
;
oResult
.
fY
=
fCenterY
+
t1
*
(
fYs
-
fCenterY
)
-
fLabelHeight
/
2
;
return
oResult
}
if
(
t2
>
0
&&
t2
<
1
){
oResult
.
bError
=
false
;
oResult
.
fX
=
fCenterX
+
t2
*
(
fXs
-
fCenterX
)
-
fLabelWidth
/
2
;
oResult
.
fY
=
fCenterY
+
t2
*
(
fYs
-
fCenterY
)
-
fLabelHeight
/
2
;
return
oResult
}
return
oResult
;
},
//For test
_calculateTestFrame
:
function
(
point1
,
point2
,
point3
,
point4
,
point5
,
point6
,
point7
,
point8
)
{
var
pxToMm
=
this
.
chartProp
.
pxToMM
;
var
pathH
=
this
.
chartProp
.
pathH
;
var
pathW
=
this
.
chartProp
.
pathW
;
var
path
=
new
Path
();
path
.
pathH
=
pathH
;
path
.
pathW
=
pathW
;
var
gdLst
=
[];
gdLst
[
"
w
"
]
=
1
;
gdLst
[
"
h
"
]
=
1
;
path
.
moveTo
(
point1
.
x
/
pxToMm
*
pathW
,
point1
.
y
/
pxToMm
*
pathH
);
path
.
lnTo
(
point2
.
x
/
pxToMm
*
pathW
,
point2
.
y
/
pxToMm
*
pathH
);
path
.
lnTo
(
point3
.
x
/
pxToMm
*
pathW
,
point3
.
y
/
pxToMm
*
pathH
);
path
.
lnTo
(
point4
.
x
/
pxToMm
*
pathW
,
point4
.
y
/
pxToMm
*
pathH
);
path
.
lnTo
(
point1
.
x
/
pxToMm
*
pathW
,
point1
.
y
/
pxToMm
*
pathH
);
path
.
moveTo
(
point5
.
x
/
pxToMm
*
pathW
,
point5
.
y
/
pxToMm
*
pathH
);
path
.
lnTo
(
point6
.
x
/
pxToMm
*
pathW
,
point6
.
y
/
pxToMm
*
pathH
);
path
.
lnTo
(
point7
.
x
/
pxToMm
*
pathW
,
point7
.
y
/
pxToMm
*
pathH
);
path
.
lnTo
(
point8
.
x
/
pxToMm
*
pathW
,
point8
.
y
/
pxToMm
*
pathH
);
path
.
lnTo
(
point5
.
x
/
pxToMm
*
pathW
,
point5
.
y
/
pxToMm
*
pathH
);
return
path
;
}
;
path
.
moveTo
(
point1
.
x
/
pxToMm
*
pathW
,
point1
.
y
/
pxToMm
*
pathH
)
;
path
.
lnTo
(
point5
.
x
/
pxToMm
*
pathW
,
point5
.
y
/
pxToMm
*
pathH
)
;
var
calculateUpFace
=
function
(
startAng
,
swapAng
)
{
var
path
=
getNewPath
();
path
.
moveTo
(
point2
.
x
/
pxToMm
*
pathW
,
point2
.
y
/
pxToMm
*
pathH
);
path
.
lnTo
(
point6
.
x
/
pxToMm
*
pathW
,
point6
.
y
/
pxToMm
*
pathH
);
var
endAng
=
startAng
+
swapAng
;
var
p
=
getSegmentPoints
(
startAng
,
endAng
);
path
.
moveTo
(
point3
.
x
/
pxToMm
*
pathW
,
point3
.
y
/
pxToMm
*
pathH
)
;
path
.
lnTo
(
point7
.
x
/
pxToMm
*
pathW
,
point7
.
y
/
pxToMm
*
pathH
);
path
.
moveTo
(
xCenter
/
pxToMm
*
pathW
,
yCenter
/
pxToMm
*
pathH
);
path
.
lnTo
(
p
.
x0
/
pxToMm
*
pathW
,
p
.
y0
/
pxToMm
*
pathH
);
path
.
arcTo
(
radius1
/
pxToMm
*
pathW
,
radius2
/
pxToMm
*
pathH
,
-
1
*
stAng
*
cToDeg
,
-
1
*
swapAng
*
cToDeg
);
path
.
lnTo
(
xCenter
/
pxToMm
*
pathW
,
yCenter
/
pxToMm
*
pathH
);
path
.
moveTo
(
point4
.
x
/
pxToMm
*
pathW
,
point4
.
y
/
pxToMm
*
pathH
);
path
.
lnTo
(
point8
.
x
/
pxToMm
*
pathW
,
point8
.
y
/
pxToMm
*
pathH
);
path
.
recalculate
(
gdLst
);
return
path
;
};
this
.
paths
.
test
=
path
;
},
var
calculateDownFace
=
function
(
startAng
,
swapAng
)
//TODO delete after test
_recalculatePie3D_Slow
:
function
()
{
var
path
=
getNewPath
();
var
trueWidth
=
this
.
chartProp
.
trueWidth
;
var
trueHeight
=
this
.
chartProp
.
trueHeight
;
var
endAng
=
startAng
+
swapAng
;
var
p
=
getSegmentPoints
(
startAng
,
endAng
);
var
numCache
=
this
.
_getFirstRealNumCache
()
;
var
sumData
=
this
.
cChartDrawer
.
_getSumArray
(
numCache
,
true
);
path
.
moveTo
(
xCenter
/
pxToMm
*
pathW
,
(
yCenter
+
depth
)
/
pxToMm
*
pathH
);
path
.
lnTo
(
p
.
x0
/
pxToMm
*
pathW
,
(
p
.
y0
+
depth
)
/
pxToMm
*
pathH
);
path
.
arcTo
(
radius1
/
pxToMm
*
pathW
,
radius2
/
pxToMm
*
pathH
,
-
1
*
stAng
*
cToDeg
,
-
1
*
swapAng
*
cToDeg
);
path
.
lnTo
(
xCenter
/
pxToMm
*
pathW
,
(
yCenter
+
depth
)
/
pxToMm
*
pathH
);
var
radius
=
Math
.
min
(
trueHeight
,
trueWidth
)
/
2
;
if
(
radius
<
0
)
radius
=
0
;
path
.
recalculate
(
gdLst
);
var
xCenter
=
this
.
chartProp
.
chartGutter
.
_left
+
trueWidth
/
2
;
var
yCenter
=
this
.
chartProp
.
chartGutter
.
_top
+
trueHeight
/
2
;
return
path
;
}
var
startAngle
=
this
.
cChartDrawer
.
processor3D
.
angleOy
?
this
.
cChartDrawer
.
processor3D
.
angleOy
:
0
;
var
startAngle3D
=
startAngle
!==
0
&&
startAngle
!==
undefined
?
this
.
_changeAngle
(
radius
,
Math
.
PI
/
2
,
startAngle
,
xCenter
,
yCenter
,
this
.
properties3d
)
:
0
;
//FRONT FACES
//break front faces
var
arrAngles
=
breakAng
(
stAng
,
swAng
);
var
frontPath
=
[];
for
(
var
i
=
1
;
i
<
arrAngles
.
length
;
i
++
)
this
.
tempAngle
=
Math
.
PI
/
2
+
startAngle
;
this
.
angleFor3D
=
Math
.
PI
/
2
-
startAngle3D
;
//рисуем против часовой стрелки, поэтому цикл с конца
var
depth
=
this
.
properties3d
.
depth
;
for
(
var
n
=
0
;
n
<
depth
;
n
++
)
{
var
start
=
arrAngles
[
i
-
1
].
angle
;
var
end
=
arrAngles
[
i
].
angle
;
var
swap
=
end
-
start
;
if
(
!
this
.
paths
.
series
)
this
.
paths
.
series
=
[];
if
((
start
>=
0
&&
start
>=
Math
.
PI
&&
start
<=
2
*
Math
.
PI
)
||
(
start
<
0
&&
start
>=
-
Math
.
PI
&&
start
<=
0
))
for
(
var
i
=
numCache
.
length
-
1
;
i
>=
0
;
i
--
)
{
frontPath
.
push
(
calculateFrontFace
(
start
,
swap
));
var
angle
=
Math
.
abs
((
parseFloat
(
numCache
[
i
].
val
/
sumData
))
*
(
Math
.
PI
*
2
));
if
(
!
this
.
paths
.
series
[
n
])
this
.
paths
.
series
[
n
]
=
[];
if
(
sumData
===
0
)
//TODO стоит пересмотреть
this
.
paths
.
series
[
n
][
i
]
=
this
.
_calculateEmptySegment
(
radius
,
xCenter
,
yCenter
);
else
this
.
paths
.
series
[
n
][
i
]
=
this
.
_calculateSegment3D
(
angle
,
radius
,
xCenter
,
yCenter
,
n
,
i
);
}
}
//INSIDE FACES
var
insidePath
=
calculateInsideFaces
(
stAng
,
swAng
);
//UP FACE
var
upPath
=
calculateUpFace
(
stAng
,
swAng
);
//DOWN FACE
var
downPath
=
calculateDownFace
(
stAng
,
swAng
);
this
.
angleFor3D
+=
swAng
;
return
{
frontPath
:
frontPath
,
upPath
:
upPath
,
insidePath
:
insidePath
,
downPath
:
downPath
};
},
_calculateSegment3D
:
function
(
startAngle
,
swapAngle
,
radius
,
xCenter
,
yCenter
)
{
if
(
isNaN
(
swapAngle
))
_calculateSegment3D_Slow
:
function
(
angle
,
radius
,
xCenter
,
yCenter
,
depth
,
i
)
{
if
(
isNaN
(
angle
))
return
null
;
}
if
(
radius
<
0
)
{
radius
=
0
;
}
var
startAngle
=
(
this
.
tempAngle
);
var
swapAngle
=
angle
;
var
path
=
[];
path
.
push
(
this
.
_calculateArc3D
(
radius
,
startAngle
,
swapAngle
,
xCenter
,
yCenter
));
var
path
=
this
.
_calculateArc3D
(
radius
,
startAngle
,
swapAngle
,
xCenter
,
yCenter
,
depth
,
i
);
this
.
tempAngle
+=
angle
;
return
path
;
},
_drawPie3D
:
function
()
_calculateArc3D_Slow
:
function
(
radius
,
stAng
,
swAng
,
xCenter
,
yCenter
,
depth
,
seriaNum
)
{
var
numCache
=
this
.
_getFirstRealNumCache
();
var
radius1
=
this
.
properties3d
.
radius1
;
var
radius2
=
this
.
properties3d
.
radius2
;
var
pxToMm
=
this
.
chartProp
.
pxToMM
;
var
t
=
this
;
var
shade
=
"
shade
"
;
var
shadeValue
=
35000
;
var
drawPath
=
function
(
path
,
pen
,
brush
,
isShadePen
,
isShadeBrush
)
{
if
(
path
)
var
x0
,
y0
,
radiusSpec
;
var
calculateProps
=
function
()
{
if
(
brush
)
if
(
t
.
usually3dPropsCalc
&&
t
.
usually3dPropsCalc
[
seriaNum
]
)
{
var
props
=
t
.
cChartSpace
.
getParentObjects
();
var
duplicateBrush
=
brush
.
createDuplicate
();
var
cColorMod
=
new
AscFormat
.
CColorMod
;
cColorMod
.
val
=
shadeValue
;
cColorMod
.
name
=
shade
;
swAng
=
t
.
usually3dPropsCalc
[
seriaNum
].
swAng
;
stAng
=
t
.
usually3dPropsCalc
[
seriaNum
].
stAng
;
radiusSpec
=
t
.
usually3dPropsCalc
[
seriaNum
].
radiusSpec
;
x0
=
t
.
usually3dPropsCalc
[
seriaNum
].
x0
;
if
(
duplicateBrush
)
{
duplicateBrush
.
addColorMod
(
cColorMod
);
duplicateBrush
.
calculate
(
props
.
theme
,
props
.
slide
,
props
.
layout
,
props
.
master
,
new
AscFormat
.
CUniColor
().
RGBA
);
}
if
(
isShadePen
)
{
pen
=
AscFormat
.
CreatePenFromParams
(
duplicateBrush
,
undefined
,
undefined
,
undefined
,
undefined
,
0
);
yCenter
=
yCenter
+
t
.
properties3d
.
depth
/
2
-
depth
;
y0
=
(
yCenter
-
radiusSpec
*
Math
.
sin
(
stAng
));
}
if
(
isShadeBrush
)
else
{
brush
=
duplicateBrush
;
}
}
swAng
=
t
.
_changeAngle
(
radius
,
stAng
,
swAng
,
xCenter
,
yCenter
,
t
.
properties3d
);
stAng
=
t
.
angleFor3D
;
t
.
cChartDrawer
.
drawPath
(
path
,
pen
,
brush
);
}
//корректируем центр
yCenter
=
yCenter
+
t
.
properties3d
.
depth
/
2
-
depth
;
radiusSpec
=
(
radius1
*
radius2
)
/
Math
.
sqrt
(
Math
.
pow
(
radius2
,
2
)
*
Math
.
pow
((
Math
.
cos
(
stAng
)),
2
)
+
Math
.
pow
(
radius1
,
2
)
*
Math
.
pow
(
Math
.
sin
(
stAng
),
2
));
x0
=
(
xCenter
+
radiusSpec
*
Math
.
cos
(
stAng
));
y0
=
(
yCenter
-
radiusSpec
*
Math
.
sin
(
stAng
));
}
};
//DOWN
for
(
var
i
=
0
,
len
=
numCache
.
length
;
i
<
len
;
i
++
)
{
var
val
=
numCache
[
i
];
var
brush
=
val
.
brush
;
var
pen
=
val
.
pen
;
var
path
=
this
.
paths
.
series
[
i
];
var
path
=
new
Path
();
if
(
path
)
{
for
(
var
j
=
path
.
length
-
1
;
j
>=
0
;
j
--
)
{
drawPath
(
path
[
j
].
downPath
,
pen
,
null
);
}
}
}
var
pathH
=
this
.
chartProp
.
pathH
;
var
pathW
=
this
.
chartProp
.
pathW
;
var
gdLst
=
[];
//INSIDE
for
(
var
i
=
0
,
len
=
numCache
.
length
;
i
<
len
;
i
++
)
{
var
val
=
numCache
[
i
];
var
brush
=
val
.
brush
;
var
pen
=
val
.
pen
;
var
path
=
this
.
paths
.
series
[
i
];
path
.
pathH
=
pathH
;
path
.
pathW
=
pathW
;
gdLst
[
"
w
"
]
=
1
;
gdLst
[
"
h
"
]
=
1
;
if
(
path
)
{
for
(
var
j
=
path
.
length
-
1
;
j
>=
0
;
j
--
)
{
drawPath
(
path
[
j
].
insidePath
,
pen
,
brush
,
null
,
true
);
}
}
}
calculateProps
();
//FRONT
for
(
var
i
=
0
,
len
=
numCache
.
length
;
i
<
len
;
i
++
)
{
var
val
=
numCache
[
i
];
var
brush
=
val
.
brush
;
var
pen
=
val
.
pen
;
var
path
=
this
.
paths
.
series
[
i
];
path
.
moveTo
(
xCenter
/
pxToMm
*
pathW
,
yCenter
/
pxToMm
*
pathH
);
path
.
lnTo
(
x0
/
pxToMm
*
pathW
,
y0
/
pxToMm
*
pathH
);
path
.
arcTo
(
radius1
/
pxToMm
*
pathW
,
radius2
/
pxToMm
*
pathH
,
-
1
*
stAng
*
cToDeg
,
-
1
*
swAng
*
cToDeg
);
path
.
lnTo
(
xCenter
/
pxToMm
*
pathW
,
yCenter
/
pxToMm
*
pathH
);
if
(
path
)
path
.
recalculate
(
gdLst
);
this
.
angleFor3D
+=
swAng
;
if
(
!
this
.
usually3dPropsCalc
[
seriaNum
])
this
.
usually3dPropsCalc
[
seriaNum
]
=
{
swAng
:
swAng
,
stAng
:
stAng
,
xCenter
:
xCenter
,
x0
:
x0
,
radiusSpec
:
radiusSpec
};
return
path
;
},
_drawPie3D_Slow
:
function
()
{
for
(
var
j
=
path
.
length
-
1
;
j
>=
0
;
j
--
)
var
numCache
=
this
.
_getFirstRealNumCache
();
var
props
=
this
.
cChartSpace
.
getParentObjects
();
var
brush
,
pen
,
val
;
var
path
;
for
(
var
n
=
0
;
n
<
this
.
paths
.
series
.
length
;
n
++
)
{
for
(
var
k
=
0
;
k
<
path
[
j
].
frontPath
.
length
;
k
++
)
for
(
var
i
=
0
,
len
=
numCache
.
length
;
i
<
len
;
i
++
)
{
val
=
numCache
[
i
];
brush
=
val
.
brush
;
if
(
n
===
0
||
n
===
this
.
paths
.
series
.
length
-
1
)
{
drawPath
(
path
[
j
].
frontPath
[
k
],
pen
,
brush
,
true
,
true
);
}
}
pen
=
val
.
pen
;
}
else
{
pen
=
null
;
}
//UP
for
(
var
i
=
0
,
len
=
numCache
.
length
;
i
<
len
;
i
++
)
{
var
val
=
numCache
[
i
];
var
brush
=
val
.
brush
;
var
pen
=
val
.
pen
;
var
path
=
this
.
paths
.
series
[
i
];
path
=
this
.
paths
.
series
[
n
][
i
];
if
(
path
)
{
for
(
var
j
=
path
.
length
-
1
;
j
>=
0
;
j
--
)
var
duplicateBrush
=
brush
;
if
(
n
!==
this
.
paths
.
series
.
length
-
1
)
{
drawPath
(
path
[
j
].
upPath
,
pen
,
brush
);
duplicateBrush
=
brush
.
createDuplicate
();
var
cColorMod
=
new
AscFormat
.
CColorMod
;
cColorMod
.
val
=
35000
;
cColorMod
.
name
=
"
shade
"
;
duplicateBrush
.
addColorMod
(
cColorMod
);
duplicateBrush
.
calculate
(
props
.
theme
,
props
.
slide
,
props
.
layout
,
props
.
master
,
new
AscFormat
.
CUniColor
().
RGBA
);
}
this
.
cChartDrawer
.
drawPath
(
path
,
pen
,
duplicateBrush
);
}
}
}
};
...
...
@@ -8758,7 +9255,7 @@ drawDoughnutChart.prototype =
_drawPie
:
function
()
{
var
brush
,
pen
,
val
;
var
brush
,
pen
;
var
path
;
var
idxPoint
,
numCache
;
...
...
@@ -8874,8 +9371,8 @@ drawDoughnutChart.prototype =
var
x1
=
xCenter
+
radius2
*
Math
.
cos
(
stAng
);
var
y1
=
yCenter
-
radius2
*
Math
.
sin
(
stAng
);
var
x3
=
xCenter
+
radius1
*
Math
.
cos
(
stAng
+
swAng
);
var
y3
=
yCenter
-
radius1
*
Math
.
sin
(
stAng
+
swAng
);
//
var x3 = xCenter + radius1*Math.cos(stAng + swAng);
//
var y3 = yCenter - radius1*Math.sin(stAng + swAng);
var
x4
=
xCenter
+
radius2
*
Math
.
cos
(
stAng
+
swAng
);
var
y4
=
yCenter
-
radius2
*
Math
.
sin
(
stAng
+
swAng
);
...
...
@@ -8893,17 +9390,10 @@ drawDoughnutChart.prototype =
_calculateDLbl
:
function
(
chartSpace
,
ser
,
val
)
{
var
pxToMm
=
this
.
chartProp
.
pxToMM
;
if
(
!
this
.
paths
.
series
[
ser
][
val
])
return
;
var
path
=
this
.
paths
.
series
[
ser
][
val
].
ArrPathCommand
;
var
x1
=
path
[
0
].
X
;
var
y1
=
path
[
0
].
Y
;
var
x2
=
path
[
1
].
X
;
var
y2
=
path
[
1
].
Y
;
var
radius1
=
path
[
2
].
hR
;
var
stAng
=
path
[
2
].
stAng
;
...
...
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