Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
c3-closed
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Evgeny
c3-closed
Commits
0516616d
Commit
0516616d
authored
Aug 17, 2014
by
Masayuki Tanaka
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Modularize event rect
parent
f2f75452
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
840 additions
and
836 deletions
+840
-836
Gruntfile.coffee
Gruntfile.coffee
+1
-0
c3.js
c3.js
+526
-524
c3.min.js
c3.min.js
+0
-0
core.js
src/core.js
+6
-310
data.js
src/data.js
+6
-2
interaction.js
src/interaction.js
+301
-0
No files found.
Gruntfile.coffee
View file @
0516616d
...
...
@@ -27,6 +27,7 @@ module.exports = (grunt) ->
'src/data.convert.js'
,
'src/data.load.js'
,
'src/category.js'
,
'src/interaction.js'
,
'src/size.js'
,
'src/shape.js'
,
'src/shape.line.js'
,
...
...
c3.js
View file @
0516616d
...
...
@@ -132,7 +132,7 @@
c3_chart_internal_fn
.
initWithData
=
function
(
data
)
{
var
$$
=
this
,
d3
=
$$
.
d3
,
config
=
$$
.
config
;
var
main
,
eventRect
,
binding
=
true
;
var
main
,
binding
=
true
;
if
(
$$
.
initPie
)
{
$$
.
initPie
();
}
if
(
$$
.
initBrush
)
{
$$
.
initBrush
();
}
...
...
@@ -225,9 +225,7 @@
.
attr
(
'class'
,
CLASS
[
_chart
]);
// Cover whole with rects for events
eventRect
=
main
.
select
(
'.'
+
CLASS
[
_chart
]).
append
(
"g"
)
.
attr
(
"class"
,
CLASS
[
_eventRects
])
.
style
(
'fill-opacity'
,
0
);
$$
.
initEventRect
();
// Define g for bar chart area
if
(
$$
.
initBar
)
{
$$
.
initBar
();
}
...
...
@@ -405,9 +403,7 @@
c3_chart_internal_fn
.
redraw
=
function
(
options
,
transitions
)
{
var
$$
=
this
,
main
=
$$
.
main
,
d3
=
$$
.
d3
,
config
=
$$
.
config
;
var
eventRect
,
eventRectUpdate
;
var
areaIndices
=
$$
.
getShapeIndices
(
$$
.
isAreaType
),
barIndices
=
$$
.
getShapeIndices
(
$$
.
isBarType
),
lineIndices
=
$$
.
getShapeIndices
(
$$
.
isLineType
),
maxDataCountTarget
;
var
rectX
,
rectW
;
var
areaIndices
=
$$
.
getShapeIndices
(
$$
.
isAreaType
),
barIndices
=
$$
.
getShapeIndices
(
$$
.
isBarType
),
lineIndices
=
$$
.
getShapeIndices
(
$$
.
isLineType
);
var
withY
,
withSubchart
,
withTransition
,
withTransitionForExit
,
withTransitionForAxis
,
withTransform
,
withUpdateXDomain
,
withUpdateOrgXDomain
,
withLegend
;
var
hideAxis
=
$$
.
hasArcType
();
var
drawArea
,
drawBar
,
drawLine
,
xForText
,
yForText
;
...
...
@@ -549,70 +545,9 @@
.
selectAll
(
'circle'
)
.
remove
();
// event rect
if
(
config
[
__interaction_enabled
])
{
// rect for mouseover
eventRect
=
main
.
select
(
'.'
+
CLASS
[
_eventRects
])
.
style
(
'cursor'
,
config
[
__zoom_enabled
]
?
config
[
__axis_rotated
]
?
'ns-resize'
:
'ew-resize'
:
null
);
if
(
notEmpty
(
config
[
__data_xs
])
&&
!
$$
.
isSingleX
(
config
[
__data_xs
]))
{
if
(
!
eventRect
.
classed
(
CLASS
[
_eventRectsMultiple
]))
{
eventRect
.
classed
(
CLASS
[
_eventRectsMultiple
],
true
).
classed
(
CLASS
[
_eventRectsSingle
],
false
)
.
selectAll
(
'.'
+
CLASS
[
_eventRect
]).
remove
();
}
eventRectUpdate
=
main
.
select
(
'.'
+
CLASS
[
_eventRects
]).
selectAll
(
'.'
+
CLASS
[
_eventRect
])
.
data
([
0
]);
// enter : only one rect will be added
$$
.
generateEventRectsForMultipleXs
(
eventRectUpdate
.
enter
());
// update
eventRectUpdate
.
attr
(
'x'
,
0
)
.
attr
(
'y'
,
0
)
.
attr
(
'width'
,
$$
.
width
)
.
attr
(
'height'
,
$$
.
height
);
// exit : not needed because always only one rect exists
}
else
{
if
(
!
eventRect
.
classed
(
CLASS
[
_eventRectsSingle
]))
{
eventRect
.
classed
(
CLASS
[
_eventRectsMultiple
],
false
).
classed
(
CLASS
[
_eventRectsSingle
],
true
)
.
selectAll
(
'.'
+
CLASS
[
_eventRect
]).
remove
();
}
if
((
$$
.
isCustomX
()
||
$$
.
isTimeSeries
())
&&
!
$$
.
isCategorized
())
{
rectW
=
function
(
d
)
{
var
prevX
=
$$
.
getPrevX
(
d
.
index
),
nextX
=
$$
.
getNextX
(
d
.
index
),
dx
=
$$
.
data
.
xs
[
d
.
id
][
d
.
index
],
w
=
(
$$
.
x
(
nextX
?
nextX
:
dx
)
-
$$
.
x
(
prevX
?
prevX
:
dx
))
/
2
;
return
w
<
0
?
0
:
w
;
};
rectX
=
function
(
d
)
{
var
prevX
=
$$
.
getPrevX
(
d
.
index
),
dx
=
$$
.
data
.
xs
[
d
.
id
][
d
.
index
];
return
(
$$
.
x
(
dx
)
+
$$
.
x
(
prevX
?
prevX
:
dx
))
/
2
;
};
}
else
{
rectW
=
$$
.
getEventRectWidth
();
rectX
=
function
(
d
)
{
return
$$
.
x
(
d
.
x
)
-
(
rectW
/
2
);
};
}
// Set data
maxDataCountTarget
=
$$
.
getMaxDataCountTarget
(
$$
.
data
.
targets
);
main
.
select
(
'.'
+
CLASS
[
_eventRects
])
.
datum
(
maxDataCountTarget
?
maxDataCountTarget
.
values
:
[]);
// Update rects
eventRectUpdate
=
main
.
select
(
'.'
+
CLASS
[
_eventRects
]).
selectAll
(
'.'
+
CLASS
[
_eventRect
])
.
data
(
function
(
d
)
{
return
d
;
});
// enter
$$
.
generateEventRectsForSingleX
(
eventRectUpdate
.
enter
());
// update
eventRectUpdate
.
attr
(
'class'
,
generateCall
(
$$
.
classEvent
,
$$
))
.
attr
(
"x"
,
config
[
__axis_rotated
]
?
0
:
rectX
)
.
attr
(
"y"
,
config
[
__axis_rotated
]
?
rectX
:
0
)
.
attr
(
"width"
,
config
[
__axis_rotated
]
?
$$
.
width
:
rectW
)
.
attr
(
"height"
,
config
[
__axis_rotated
]
?
rectW
:
$$
.
height
);
// exit
eventRectUpdate
.
exit
().
remove
();
}
$$
.
redrawEventRect
();
}
// transition should be derived from one transition
...
...
@@ -621,30 +556,8 @@
$$
.
addTransitionForBar
(
transitions
,
drawBar
);
$$
.
addTransitionForLine
(
transitions
,
drawLine
);
/*
transitions.push(mainLine.transition()
.attr("d", drawLine)
.style("stroke", $$.color)
.style("opacity", 1));
*/
$$
.
addTransitionForArea
(
transitions
,
drawArea
);
/*
transitions.push(mainArea.transition()
.attr("d", drawArea)
.style("fill", $$.color)
.style("opacity", $$.orgAreaOpacity));
*/
$$
.
addTransitionForCircle
(
transitions
,
cx
,
cy
);
/*
transitions.push(mainCircle.transition()
.style('opacity', generateCall($$.opacityForCircle, $$))
.style("fill", $$.color)
.attr("cx", cx)
.attr("cy", cy));
transitions.push(main.selectAll('.' + CLASS[_selectedCircle]).transition()
.attr("cx", cx)
.attr("cy", cy));
*/
$$
.
addTransitionForText
(
transitions
,
xForText
,
yForText
,
options
.
flow
);
$$
.
addTransitionForRegion
(
transitions
);
$$
.
addTransitionForGrid
(
transitions
);
...
...
@@ -774,11 +687,7 @@
mainRegion
.
select
(
'rect'
).
filter
(
$$
.
isRegionOnX
)
.
attr
(
"x"
,
generateCall
(
$$
.
regionX
,
$$
))
.
attr
(
"width"
,
generateCall
(
$$
.
regionWidth
,
$$
));
eventRectUpdate
.
attr
(
"x"
,
config
[
__axis_rotated
]
?
0
:
rectX
)
.
attr
(
"y"
,
config
[
__axis_rotated
]
?
rectX
:
0
)
.
attr
(
"width"
,
config
[
__axis_rotated
]
?
$$
.
width
:
rectW
)
.
attr
(
"height"
,
config
[
__axis_rotated
]
?
rectW
:
$$
.
height
);
$$
.
updateEventRect
();
// callback for end of flow
done
();
...
...
@@ -820,357 +729,144 @@
$$
.
redraw
(
options
,
transitions
);
};
c3_chart_internal_fn
.
generateEventRectsForSingleX
=
function
(
eventRectEnter
)
{
var
$$
=
this
,
d3
=
$$
.
d3
,
config
=
$$
.
config
;
eventRectEnter
.
append
(
"rect"
)
.
attr
(
"class"
,
generateCall
(
$$
.
classEvent
,
$$
))
.
style
(
"cursor"
,
config
[
__data_selection_enabled
]
&&
config
[
__data_selection_grouped
]
?
"pointer"
:
null
)
.
on
(
'mouseover'
,
function
(
d
)
{
var
index
=
d
.
index
,
selectedData
,
newData
;
if
(
$$
.
dragging
)
{
return
;
}
// do nothing if dragging
if
(
$$
.
hasArcType
())
{
return
;
}
c3_chart_internal_fn
.
isTimeSeries
=
function
(
)
{
return
this
.
config
[
__axis_x_type
]
===
'timeseries'
;
};
c3_chart_internal_fn
.
isCategorized
=
function
()
{
return
this
.
config
[
__axis_x_type
].
indexOf
(
'categor'
)
>=
0
;
};
c3_chart_internal_fn
.
isCustomX
=
function
()
{
var
$$
=
this
,
config
=
$$
.
config
;
return
!
$$
.
isTimeSeries
()
&&
(
config
[
__data_x
]
||
notEmpty
(
config
[
__data_xs
]));
};
selectedData
=
$$
.
data
.
targets
.
map
(
function
(
t
)
{
return
$$
.
addName
(
$$
.
getValueOnIndex
(
t
.
values
,
index
));
});
c3_chart_internal_fn
.
getTranslate
=
function
(
target
)
{
var
$$
=
this
,
config
=
$$
.
config
,
x
,
y
;
if
(
target
===
'main'
)
{
x
=
asHalfPixel
(
$$
.
margin
.
left
);
y
=
asHalfPixel
(
$$
.
margin
.
top
);
}
else
if
(
target
===
'context'
)
{
x
=
asHalfPixel
(
$$
.
margin2
.
left
);
y
=
asHalfPixel
(
$$
.
margin2
.
top
);
}
else
if
(
target
===
'legend'
)
{
x
=
$$
.
margin3
.
left
;
y
=
$$
.
margin3
.
top
;
}
else
if
(
target
===
'x'
)
{
x
=
0
;
y
=
config
[
__axis_rotated
]
?
0
:
$$
.
height
;
}
else
if
(
target
===
'y'
)
{
x
=
0
;
y
=
config
[
__axis_rotated
]
?
$$
.
height
:
0
;
}
else
if
(
target
===
'y2'
)
{
x
=
config
[
__axis_rotated
]
?
0
:
$$
.
width
;
y
=
config
[
__axis_rotated
]
?
1
:
0
;
}
else
if
(
target
===
'subx'
)
{
x
=
0
;
y
=
config
[
__axis_rotated
]
?
0
:
$$
.
height2
;
}
else
if
(
target
===
'arc'
)
{
x
=
$$
.
arcWidth
/
2
;
y
=
$$
.
arcHeight
/
2
;
}
return
"translate("
+
x
+
","
+
y
+
")"
;
};
c3_chart_internal_fn
.
initialOpacity
=
function
(
d
)
{
return
d
.
value
!==
null
&&
this
.
withoutFadeIn
[
d
.
id
]
?
1
:
0
;
};
c3_chart_internal_fn
.
opacityForCircle
=
function
(
d
)
{
var
$$
=
this
;
return
isValue
(
d
.
value
)
?
$$
.
isScatterType
(
d
)
?
0.5
:
1
:
0
;
};
c3_chart_internal_fn
.
opacityForText
=
function
()
{
return
this
.
hasDataLabel
()
?
1
:
0
;
};
c3_chart_internal_fn
.
xx
=
function
(
d
)
{
return
d
?
this
.
x
(
d
.
x
)
:
null
;
};
c3_chart_internal_fn
.
xv
=
function
(
d
)
{
var
$$
=
this
;
return
Math
.
ceil
(
$$
.
x
(
$$
.
isTimeSeries
()
?
$$
.
parseDate
(
d
.
value
)
:
d
.
value
));
};
c3_chart_internal_fn
.
yv
=
function
(
d
)
{
var
$$
=
this
,
yScale
=
d
.
axis
&&
d
.
axis
===
'y2'
?
$$
.
y2
:
$$
.
y
;
return
Math
.
ceil
(
yScale
(
d
.
value
));
};
c3_chart_internal_fn
.
subxx
=
function
(
d
)
{
return
d
?
this
.
subX
(
d
.
x
)
:
null
;
};
// Sort selectedData as names order
newData
=
[];
Object
.
keys
(
config
[
__data_names
]).
forEach
(
function
(
id
)
{
for
(
var
j
=
0
;
j
<
selectedData
.
length
;
j
++
)
{
if
(
selectedData
[
j
]
&&
selectedData
[
j
].
id
===
id
)
{
newData
.
push
(
selectedData
[
j
]);
selectedData
.
shift
(
j
);
break
;
c3_chart_internal_fn
.
transformMain
=
function
(
withTransition
,
transitions
)
{
var
$$
=
this
,
xAxis
,
yAxis
,
y2Axis
;
if
(
transitions
&&
transitions
.
axisX
)
{
xAxis
=
transitions
.
axisX
;
}
else
{
xAxis
=
$$
.
main
.
select
(
'.'
+
CLASS
[
_axisX
]
);
if
(
withTransition
)
{
xAxis
=
xAxis
.
transition
();
}
}
if
(
transitions
&&
transitions
.
axisY
)
{
yAxis
=
transitions
.
axisY
;
}
else
{
yAxis
=
$$
.
main
.
select
(
'.'
+
CLASS
[
_axisY
]);
if
(
withTransition
)
{
yAxis
=
yAxis
.
transition
();
}
}
});
selectedData
=
newData
.
concat
(
selectedData
);
// Add remained
// Expand shapes for selection
if
(
config
[
__point_focus_expand_enabled
])
{
$$
.
expandCircles
(
index
);
}
$$
.
expandBars
(
index
);
// Call event handler
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
).
each
(
function
(
d
)
{
config
[
__data_onmouseover
].
call
(
c3
,
d
);
});
})
.
on
(
'mouseout'
,
function
(
d
)
{
var
index
=
d
.
index
;
if
(
$$
.
hasArcType
())
{
return
;
}
$$
.
hideXGridFocus
();
$$
.
hideTooltip
();
// Undo expanded shapes
$$
.
unexpandCircles
(
index
);
$$
.
unexpandBars
();
// Call event handler
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
).
each
(
function
(
d
)
{
config
[
__data_onmouseout
].
call
(
$$
,
d
);
});
})
.
on
(
'mousemove'
,
function
(
d
)
{
var
selectedData
,
index
=
d
.
index
,
eventRect
=
$$
.
svg
.
select
(
'.'
+
CLASS
[
_eventRect
]
+
'-'
+
index
);
if
(
$$
.
dragging
)
{
return
;
}
// do nothing when dragging
if
(
$$
.
hasArcType
())
{
return
;
}
if
(
transitions
&&
transitions
.
axisY2
)
{
y2Axis
=
transitions
.
axisY2
;
}
else
{
y2Axis
=
$$
.
main
.
select
(
'.'
+
CLASS
[
_axisY2
]);
if
(
withTransition
)
{
y2Axis
=
y2Axis
.
transition
();
}
}
(
withTransition
?
$$
.
main
.
transition
()
:
$$
.
main
).
attr
(
"transform"
,
$$
.
getTranslate
(
'main'
));
xAxis
.
attr
(
"transform"
,
$$
.
getTranslate
(
'x'
));
yAxis
.
attr
(
"transform"
,
$$
.
getTranslate
(
'y'
));
y2Axis
.
attr
(
"transform"
,
$$
.
getTranslate
(
'y2'
));
$$
.
main
.
select
(
'.'
+
CLASS
[
_chartArcs
]).
attr
(
"transform"
,
$$
.
getTranslate
(
'arc'
));
};
c3_chart_internal_fn
.
transformAll
=
function
(
withTransition
,
transitions
)
{
var
$$
=
this
;
$$
.
transformMain
(
withTransition
,
transitions
);
if
(
$$
.
config
[
__subchart_show
])
{
$$
.
transformContext
(
withTransition
,
transitions
);
}
if
(
$$
.
legend
)
{
$$
.
transformLegend
(
withTransition
);
}
};
// Show tooltip
selectedData
=
$$
.
filterTargetsToShow
(
$$
.
data
.
targets
).
map
(
function
(
t
)
{
return
$$
.
addName
(
$$
.
getValueOnIndex
(
t
.
values
,
index
));
});
c3_chart_internal_fn
.
updateSvgSize
=
function
()
{
var
$$
=
this
;
$$
.
svg
.
attr
(
'width'
,
$$
.
currentWidth
).
attr
(
'height'
,
$$
.
currentHeight
);
$$
.
svg
.
select
(
'#'
+
$$
.
clipId
).
select
(
'rect'
)
.
attr
(
'width'
,
$$
.
width
)
.
attr
(
'height'
,
$$
.
height
);
$$
.
svg
.
select
(
'#'
+
$$
.
clipIdForXAxis
).
select
(
'rect'
)
.
attr
(
'x'
,
generateCall
(
$$
.
getXAxisClipX
,
$$
))
.
attr
(
'y'
,
generateCall
(
$$
.
getXAxisClipY
,
$$
))
.
attr
(
'width'
,
generateCall
(
$$
.
getXAxisClipWidth
,
$$
))
.
attr
(
'height'
,
generateCall
(
$$
.
getXAxisClipHeight
,
$$
));
$$
.
svg
.
select
(
'#'
+
$$
.
clipIdForYAxis
).
select
(
'rect'
)
.
attr
(
'x'
,
generateCall
(
$$
.
getYAxisClipX
,
$$
))
.
attr
(
'y'
,
generateCall
(
$$
.
getYAxisClipY
,
$$
))
.
attr
(
'width'
,
generateCall
(
$$
.
getYAxisClipWidth
,
$$
))
.
attr
(
'height'
,
generateCall
(
$$
.
getYAxisClipHeight
,
$$
));
$$
.
svg
.
select
(
'.'
+
CLASS
[
_zoomRect
])
.
attr
(
'width'
,
$$
.
width
)
.
attr
(
'height'
,
$$
.
height
);
// MEMO: parent div's height will be bigger than svg when <!DOCTYPE html>
$$
.
selectChart
.
style
(
'max-height'
,
$$
.
currentHeight
+
"px"
);
};
if
(
config
[
__tooltip_grouped
])
{
$$
.
showTooltip
(
selectedData
,
d3
.
mouse
(
this
));
$$
.
showXGridFocus
(
selectedData
);
}
if
(
config
[
__tooltip_grouped
]
&&
(
!
config
[
__data_selection_enabled
]
||
config
[
__data_selection_grouped
]))
{
return
;
c3_chart_internal_fn
.
updateDimension
=
function
()
{
var
$$
=
this
;
if
(
$$
.
config
[
__axis_rotated
])
{
$$
.
axes
.
x
.
call
(
$$
.
xAxis
);
$$
.
axes
.
subx
.
call
(
$$
.
subXAxis
);
}
else
{
$$
.
axes
.
y
.
call
(
$$
.
yAxis
);
$$
.
axes
.
y2
.
call
(
$$
.
y2Axis
);
}
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
)
.
each
(
function
()
{
d3
.
select
(
this
).
classed
(
CLASS
[
_EXPANDED
],
true
);
if
(
config
[
__data_selection_enabled
])
{
eventRect
.
style
(
'cursor'
,
config
[
__data_selection_grouped
]
?
'pointer'
:
null
);
}
if
(
!
config
[
__tooltip_grouped
])
{
$$
.
hideXGridFocus
();
$$
.
hideTooltip
();
if
(
!
config
[
__data_selection_grouped
])
{
$$
.
unexpandCircles
(
index
);
$$
.
unexpandBars
();
}
}
})
.
filter
(
function
(
d
)
{
if
(
this
.
nodeName
===
'circle'
)
{
return
$$
.
isWithinCircle
(
this
,
$$
.
pointSelectR
(
d
));
}
else
if
(
this
.
nodeName
===
'path'
)
{
return
$$
.
isWithinBar
(
this
);
}
})
.
each
(
function
(
d
)
{
if
(
config
[
__data_selection_enabled
]
&&
(
config
[
__data_selection_grouped
]
||
config
[
__data_selection_isselectable
](
d
)))
{
eventRect
.
style
(
'cursor'
,
'pointer'
);
}
if
(
!
config
[
__tooltip_grouped
])
{
$$
.
showTooltip
([
d
],
d3
.
mouse
(
this
));
$$
.
showXGridFocus
([
d
]);
if
(
config
[
__point_focus_expand_enabled
])
{
$$
.
expandCircles
(
index
,
d
.
id
);
}
$$
.
expandBars
(
index
,
d
.
id
);
}
});
})
.
on
(
'click'
,
function
(
d
)
{
var
index
=
d
.
index
;
if
(
$$
.
hasArcType
()
||
!
$$
.
toggleShape
)
{
return
;
}
if
(
$$
.
cancelClick
)
{
$$
.
cancelClick
=
false
;
return
;
}
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
).
each
(
function
(
d
)
{
$$
.
toggleShape
(
this
,
d
,
index
);
});
})
.
call
(
d3
.
behavior
.
drag
().
origin
(
Object
)
.
on
(
'drag'
,
function
()
{
$$
.
drag
(
d3
.
mouse
(
this
));
})
.
on
(
'dragstart'
,
function
()
{
$$
.
dragstart
(
d3
.
mouse
(
this
));
})
.
on
(
'dragend'
,
function
()
{
$$
.
dragend
();
})
)
.
on
(
"dblclick.zoom"
,
null
);
};
c3_chart_internal_fn
.
generateEventRectsForMultipleXs
=
function
(
eventRectEnter
)
{
var
$$
=
this
,
d3
=
$$
.
d3
,
config
=
$$
.
config
;
eventRectEnter
.
append
(
'rect'
)
.
attr
(
'x'
,
0
)
.
attr
(
'y'
,
0
)
.
attr
(
'width'
,
$$
.
width
)
.
attr
(
'height'
,
$$
.
height
)
.
attr
(
'class'
,
CLASS
[
_eventRect
])
.
on
(
'mouseout'
,
function
()
{
if
(
$$
.
hasArcType
())
{
return
;
}
$$
.
hideXGridFocus
();
$$
.
hideTooltip
();
$$
.
unexpandCircles
();
})
.
on
(
'mousemove'
,
function
()
{
var
targetsToShow
=
$$
.
filterTargetsToShow
(
$$
.
data
.
targets
);
var
mouse
,
closest
,
sameXData
,
selectedData
;
if
(
$$
.
dragging
)
{
return
;
}
// do nothing when dragging
if
(
$$
.
hasArcType
(
targetsToShow
))
{
return
;
}
mouse
=
d3
.
mouse
(
this
);
closest
=
$$
.
findClosestFromTargets
(
targetsToShow
,
mouse
);
if
(
!
closest
)
{
return
;
}
if
(
$$
.
isScatterType
(
closest
))
{
sameXData
=
[
closest
];
}
else
{
sameXData
=
$$
.
filterSameX
(
targetsToShow
,
closest
.
x
);
}
// show tooltip when cursor is close to some point
selectedData
=
sameXData
.
map
(
function
(
d
)
{
return
$$
.
addName
(
d
);
});
$$
.
showTooltip
(
selectedData
,
mouse
);
// expand points
if
(
config
[
__point_focus_expand_enabled
])
{
$$
.
unexpandCircles
();
$$
.
expandCircles
(
closest
.
index
,
closest
.
id
);
}
// Show xgrid focus line
$$
.
showXGridFocus
(
selectedData
);
// Show cursor as pointer if point is close to mouse position
if
(
$$
.
dist
(
closest
,
mouse
)
<
100
)
{
$$
.
svg
.
select
(
'.'
+
CLASS
[
_eventRect
]).
style
(
'cursor'
,
'pointer'
);
if
(
!
$$
.
mouseover
)
{
config
[
__data_onmouseover
].
call
(
$$
,
closest
);
$$
.
mouseover
=
true
;
}
}
else
if
(
$$
.
mouseover
)
{
$$
.
svg
.
select
(
'.'
+
CLASS
[
_eventRect
]).
style
(
'cursor'
,
null
);
config
[
__data_onmouseout
].
call
(
$$
,
closest
);
$$
.
mouseover
=
false
;
}
})
.
on
(
'click'
,
function
()
{
var
targetsToShow
=
$$
.
filterTargetsToShow
(
$$
.
data
.
targets
);
var
mouse
,
closest
;
if
(
$$
.
hasArcType
(
targetsToShow
))
{
return
;
}
mouse
=
d3
.
mouse
(
this
);
closest
=
$$
.
findClosestFromTargets
(
targetsToShow
,
mouse
);
if
(
!
closest
)
{
return
;
}
// select if selection enabled
if
(
$$
.
dist
(
closest
,
mouse
)
<
100
&&
$$
.
toggleShape
)
{
$$
.
main
.
select
(
'.'
+
CLASS
[
_circles
]
+
$$
.
getTargetSelectorSuffix
(
closest
.
id
)).
select
(
'.'
+
CLASS
[
_circle
]
+
'-'
+
closest
.
index
).
each
(
function
()
{
$$
.
toggleShape
(
this
,
closest
,
closest
.
index
);
});
}
})
.
call
(
d3
.
behavior
.
drag
().
origin
(
Object
)
.
on
(
'drag'
,
function
()
{
$$
.
drag
(
d3
.
mouse
(
this
));
})
.
on
(
'dragstart'
,
function
()
{
$$
.
dragstart
(
d3
.
mouse
(
this
));
})
.
on
(
'dragend'
,
function
()
{
$$
.
dragend
();
})
)
.
on
(
"dblclick.zoom"
,
null
);
};
c3_chart_internal_fn
.
isTimeSeries
=
function
()
{
return
this
.
config
[
__axis_x_type
]
===
'timeseries'
;
};
c3_chart_internal_fn
.
isCategorized
=
function
()
{
return
this
.
config
[
__axis_x_type
].
indexOf
(
'categor'
)
>=
0
;
};
c3_chart_internal_fn
.
isCustomX
=
function
()
{
var
$$
=
this
,
config
=
$$
.
config
;
return
!
$$
.
isTimeSeries
()
&&
(
config
[
__data_x
]
||
notEmpty
(
config
[
__data_xs
]));
};
c3_chart_internal_fn
.
getTranslate
=
function
(
target
)
{
var
$$
=
this
,
config
=
$$
.
config
,
x
,
y
;
if
(
target
===
'main'
)
{
x
=
asHalfPixel
(
$$
.
margin
.
left
);
y
=
asHalfPixel
(
$$
.
margin
.
top
);
}
else
if
(
target
===
'context'
)
{
x
=
asHalfPixel
(
$$
.
margin2
.
left
);
y
=
asHalfPixel
(
$$
.
margin2
.
top
);
}
else
if
(
target
===
'legend'
)
{
x
=
$$
.
margin3
.
left
;
y
=
$$
.
margin3
.
top
;
}
else
if
(
target
===
'x'
)
{
x
=
0
;
y
=
config
[
__axis_rotated
]
?
0
:
$$
.
height
;
}
else
if
(
target
===
'y'
)
{
x
=
0
;
y
=
config
[
__axis_rotated
]
?
$$
.
height
:
0
;
}
else
if
(
target
===
'y2'
)
{
x
=
config
[
__axis_rotated
]
?
0
:
$$
.
width
;
y
=
config
[
__axis_rotated
]
?
1
:
0
;
}
else
if
(
target
===
'subx'
)
{
x
=
0
;
y
=
config
[
__axis_rotated
]
?
0
:
$$
.
height2
;
}
else
if
(
target
===
'arc'
)
{
x
=
$$
.
arcWidth
/
2
;
y
=
$$
.
arcHeight
/
2
;
}
return
"translate("
+
x
+
","
+
y
+
")"
;
};
c3_chart_internal_fn
.
initialOpacity
=
function
(
d
)
{
return
d
.
value
!==
null
&&
this
.
withoutFadeIn
[
d
.
id
]
?
1
:
0
;
};
c3_chart_internal_fn
.
opacityForCircle
=
function
(
d
)
{
var
$$
=
this
;
return
isValue
(
d
.
value
)
?
$$
.
isScatterType
(
d
)
?
0.5
:
1
:
0
;
};
c3_chart_internal_fn
.
opacityForText
=
function
()
{
return
this
.
hasDataLabel
()
?
1
:
0
;
};
c3_chart_internal_fn
.
xx
=
function
(
d
)
{
return
d
?
this
.
x
(
d
.
x
)
:
null
;
};
c3_chart_internal_fn
.
xv
=
function
(
d
)
{
var
$$
=
this
;
return
Math
.
ceil
(
$$
.
x
(
$$
.
isTimeSeries
()
?
$$
.
parseDate
(
d
.
value
)
:
d
.
value
));
};
c3_chart_internal_fn
.
yv
=
function
(
d
)
{
var
$$
=
this
,
yScale
=
d
.
axis
&&
d
.
axis
===
'y2'
?
$$
.
y2
:
$$
.
y
;
return
Math
.
ceil
(
yScale
(
d
.
value
));
};
c3_chart_internal_fn
.
subxx
=
function
(
d
)
{
return
d
?
this
.
subX
(
d
.
x
)
:
null
;
};
c3_chart_internal_fn
.
transformMain
=
function
(
withTransition
,
transitions
)
{
var
$$
=
this
,
xAxis
,
yAxis
,
y2Axis
;
if
(
transitions
&&
transitions
.
axisX
)
{
xAxis
=
transitions
.
axisX
;
}
else
{
xAxis
=
$$
.
main
.
select
(
'.'
+
CLASS
[
_axisX
]);
if
(
withTransition
)
{
xAxis
=
xAxis
.
transition
();
}
}
if
(
transitions
&&
transitions
.
axisY
)
{
yAxis
=
transitions
.
axisY
;
}
else
{
yAxis
=
$$
.
main
.
select
(
'.'
+
CLASS
[
_axisY
]);
if
(
withTransition
)
{
yAxis
=
yAxis
.
transition
();
}
}
if
(
transitions
&&
transitions
.
axisY2
)
{
y2Axis
=
transitions
.
axisY2
;
}
else
{
y2Axis
=
$$
.
main
.
select
(
'.'
+
CLASS
[
_axisY2
]);
if
(
withTransition
)
{
y2Axis
=
y2Axis
.
transition
();
}
}
(
withTransition
?
$$
.
main
.
transition
()
:
$$
.
main
).
attr
(
"transform"
,
$$
.
getTranslate
(
'main'
));
xAxis
.
attr
(
"transform"
,
$$
.
getTranslate
(
'x'
));
yAxis
.
attr
(
"transform"
,
$$
.
getTranslate
(
'y'
));
y2Axis
.
attr
(
"transform"
,
$$
.
getTranslate
(
'y2'
));
$$
.
main
.
select
(
'.'
+
CLASS
[
_chartArcs
]).
attr
(
"transform"
,
$$
.
getTranslate
(
'arc'
));
};
c3_chart_internal_fn
.
transformAll
=
function
(
withTransition
,
transitions
)
{
var
$$
=
this
;
$$
.
transformMain
(
withTransition
,
transitions
);
if
(
$$
.
config
[
__subchart_show
])
{
$$
.
transformContext
(
withTransition
,
transitions
);
}
if
(
$$
.
legend
)
{
$$
.
transformLegend
(
withTransition
);
}
};
c3_chart_internal_fn
.
updateSvgSize
=
function
()
{
var
$$
=
this
;
$$
.
svg
.
attr
(
'width'
,
$$
.
currentWidth
).
attr
(
'height'
,
$$
.
currentHeight
);
$$
.
svg
.
select
(
'#'
+
$$
.
clipId
).
select
(
'rect'
)
.
attr
(
'width'
,
$$
.
width
)
.
attr
(
'height'
,
$$
.
height
);
$$
.
svg
.
select
(
'#'
+
$$
.
clipIdForXAxis
).
select
(
'rect'
)
.
attr
(
'x'
,
generateCall
(
$$
.
getXAxisClipX
,
$$
))
.
attr
(
'y'
,
generateCall
(
$$
.
getXAxisClipY
,
$$
))
.
attr
(
'width'
,
generateCall
(
$$
.
getXAxisClipWidth
,
$$
))
.
attr
(
'height'
,
generateCall
(
$$
.
getXAxisClipHeight
,
$$
));
$$
.
svg
.
select
(
'#'
+
$$
.
clipIdForYAxis
).
select
(
'rect'
)
.
attr
(
'x'
,
generateCall
(
$$
.
getYAxisClipX
,
$$
))
.
attr
(
'y'
,
generateCall
(
$$
.
getYAxisClipY
,
$$
))
.
attr
(
'width'
,
generateCall
(
$$
.
getYAxisClipWidth
,
$$
))
.
attr
(
'height'
,
generateCall
(
$$
.
getYAxisClipHeight
,
$$
));
$$
.
svg
.
select
(
'.'
+
CLASS
[
_zoomRect
])
.
attr
(
'width'
,
$$
.
width
)
.
attr
(
'height'
,
$$
.
height
);
// MEMO: parent div's height will be bigger than svg when <!DOCTYPE html>
$$
.
selectChart
.
style
(
'max-height'
,
$$
.
currentHeight
+
"px"
);
};
c3_chart_internal_fn
.
updateDimension
=
function
()
{
var
$$
=
this
;
if
(
$$
.
config
[
__axis_rotated
])
{
$$
.
axes
.
x
.
call
(
$$
.
xAxis
);
$$
.
axes
.
subx
.
call
(
$$
.
subXAxis
);
}
else
{
$$
.
axes
.
y
.
call
(
$$
.
yAxis
);
$$
.
axes
.
y2
.
call
(
$$
.
y2Axis
);
}
$$
.
updateSizes
();
$$
.
updateScales
();
$$
.
updateSvgSize
();
$$
.
transformAll
(
false
);
};
$$
.
updateSizes
();
$$
.
updateScales
();
$$
.
updateSvgSize
();
$$
.
transformAll
(
false
);
};
c3_chart_internal_fn
.
observeInserted
=
function
(
selection
)
{
var
$$
=
this
,
observer
=
new
MutationObserver
(
function
(
mutations
)
{
...
...
@@ -1958,8 +1654,12 @@
$$
.
config
[
__data_xs
][
id
]
=
xs
[
id
];
});
};
c3_chart_internal_fn
.
isSingleX
=
function
(
xs
)
{
return
this
.
d3
.
set
(
Object
.
keys
(
xs
).
map
(
function
(
id
)
{
return
xs
[
id
];
})).
size
()
===
1
;
c3_chart_internal_fn
.
hasMultipleX
=
function
(
xs
)
{
return
this
.
d3
.
set
(
Object
.
keys
(
xs
).
map
(
function
(
id
)
{
return
xs
[
id
];
})).
size
()
>
1
;
};
c3_chart_internal_fn
.
isMultipleX
=
function
()
{
var
$$
=
this
,
config
=
$$
.
config
;
return
notEmpty
(
config
[
__data_xs
])
&&
$$
.
hasMultipleX
(
config
[
__data_xs
]);
};
c3_chart_internal_fn
.
addName
=
function
(
data
)
{
var
$$
=
this
,
name
;
...
...
@@ -2411,110 +2111,412 @@
});
});
// set target types
if
(
config
[
__data_type
])
{
$$
.
setTargetType
(
$$
.
mapToIds
(
targets
).
filter
(
function
(
id
)
{
return
!
(
id
in
config
[
__data_types
]);
}),
config
[
__data_type
]);
// set target types
if
(
config
[
__data_type
])
{
$$
.
setTargetType
(
$$
.
mapToIds
(
targets
).
filter
(
function
(
id
)
{
return
!
(
id
in
config
[
__data_types
]);
}),
config
[
__data_type
]);
}
// cache as original id keyed
targets
.
forEach
(
function
(
d
)
{
$$
.
addCache
(
d
.
id_org
,
d
);
});
return
targets
;
};
c3_chart_internal_fn
.
load
=
function
(
targets
,
args
)
{
var
$$
=
this
;
if
(
targets
)
{
// filter loading targets if needed
if
(
args
.
filter
)
{
targets
=
targets
.
filter
(
args
.
filter
);
}
// set type if args.types || args.type specified
if
(
args
.
type
||
args
.
types
)
{
targets
.
forEach
(
function
(
t
)
{
$$
.
setTargetType
(
t
.
id
,
args
.
types
?
args
.
types
[
t
.
id
]
:
args
.
type
);
});
}
// Update/Add data
$$
.
data
.
targets
.
forEach
(
function
(
d
)
{
for
(
var
i
=
0
;
i
<
targets
.
length
;
i
++
)
{
if
(
d
.
id
===
targets
[
i
].
id
)
{
d
.
values
=
targets
[
i
].
values
;
targets
.
splice
(
i
,
1
);
break
;
}
}
});
$$
.
data
.
targets
=
$$
.
data
.
targets
.
concat
(
targets
);
// add remained
}
// Set targets
$$
.
updateTargets
(
$$
.
data
.
targets
);
// Redraw with new targets
$$
.
redraw
({
withUpdateOrgXDomain
:
true
,
withUpdateXDomain
:
true
,
withLegend
:
true
});
if
(
args
.
done
)
{
args
.
done
();
}
};
c3_chart_internal_fn
.
loadFromArgs
=
function
(
args
)
{
var
$$
=
this
;
if
(
args
.
data
)
{
$$
.
load
(
$$
.
convertDataToTargets
(
args
.
data
),
args
);
}
else
if
(
args
.
url
)
{
$$
.
convertUrlToData
(
args
.
url
,
args
.
mimeType
,
args
.
keys
,
function
(
data
)
{
$$
.
load
(
$$
.
convertDataToTargets
(
data
),
args
);
});
}
else
if
(
args
.
json
)
{
$$
.
load
(
$$
.
convertDataToTargets
(
$$
.
convertJsonToData
(
args
.
json
,
args
.
keys
)),
args
);
}
else
if
(
args
.
rows
)
{
$$
.
load
(
$$
.
convertDataToTargets
(
$$
.
convertRowsToData
(
args
.
rows
)),
args
);
}
else
if
(
args
.
columns
)
{
$$
.
load
(
$$
.
convertDataToTargets
(
$$
.
convertColumnsToData
(
args
.
columns
)),
args
);
}
else
{
$$
.
load
(
null
,
args
);
}
};
c3_chart_internal_fn
.
unload
=
function
(
targetIds
,
done
)
{
var
$$
=
this
;
if
(
!
done
)
{
done
=
function
()
{};
}
// filter existing target
targetIds
=
targetIds
.
filter
(
function
(
id
)
{
return
$$
.
hasTarget
(
$$
.
data
.
targets
,
id
);
});
// If no target, call done and return
if
(
!
targetIds
||
targetIds
.
length
===
0
)
{
done
();
return
;
}
$$
.
svg
.
selectAll
(
targetIds
.
map
(
function
(
id
)
{
return
$$
.
selectorTarget
(
id
);
}))
.
transition
()
.
style
(
'opacity'
,
0
)
.
remove
()
.
call
(
$$
.
endall
,
done
);
targetIds
.
forEach
(
function
(
id
)
{
// Reset fadein for future load
$$
.
withoutFadeIn
[
id
]
=
false
;
// Remove target's elements
if
(
$$
.
legend
)
{
$$
.
legend
.
selectAll
(
'.'
+
CLASS
[
_legendItem
]
+
$$
.
getTargetSelectorSuffix
(
id
)).
remove
();
}
// Remove target
$$
.
data
.
targets
=
$$
.
data
.
targets
.
filter
(
function
(
t
)
{
return
t
.
id
!==
id
;
});
});
};
c3_chart_internal_fn
.
categoryName
=
function
(
i
)
{
var
config
=
this
.
config
;
return
i
<
config
[
__axis_x_categories
].
length
?
config
[
__axis_x_categories
][
i
]
:
i
;
};
c3_chart_internal_fn
.
initEventRect
=
function
()
{
var
$$
=
this
,
CLASS
=
$$
.
CLASS
;
$$
.
main
.
select
(
'.'
+
CLASS
[
_chart
]).
append
(
"g"
)
.
attr
(
"class"
,
CLASS
[
_eventRects
])
.
style
(
'fill-opacity'
,
0
);
};
c3_chart_internal_fn
.
redrawEventRect
=
function
()
{
var
$$
=
this
,
config
=
$$
.
config
,
CLASS
=
$$
.
CLASS
,
eventRectUpdate
,
maxDataCountTarget
,
isMultipleX
=
$$
.
isMultipleX
();
// rects for mouseover
var
eventRects
=
$$
.
main
.
select
(
'.'
+
CLASS
[
_eventRects
])
.
style
(
'cursor'
,
config
[
__zoom_enabled
]
?
config
[
__axis_rotated
]
?
'ns-resize'
:
'ew-resize'
:
null
)
.
classed
(
CLASS
[
_eventRectsMultiple
],
isMultipleX
)
.
classed
(
CLASS
[
_eventRectsSingle
],
!
isMultipleX
);
// clear old rects
eventRects
.
selectAll
(
'.'
+
CLASS
[
_eventRect
]).
remove
();
// open as public variable
$$
.
eventRect
=
eventRects
.
selectAll
(
'.'
+
CLASS
[
_eventRect
]);
if
(
isMultipleX
)
{
eventRectUpdate
=
$$
.
eventRect
.
data
([
0
]);
// enter : only one rect will be added
$$
.
generateEventRectsForMultipleXs
(
eventRectUpdate
.
enter
());
// update
$$
.
updateEventRect
(
eventRectUpdate
);
// exit : not needed because always only one rect exists
}
else
{
// Set data and update $$.eventRect
maxDataCountTarget
=
$$
.
getMaxDataCountTarget
(
$$
.
data
.
targets
);
eventRects
.
datum
(
maxDataCountTarget
?
maxDataCountTarget
.
values
:
[]);
$$
.
eventRect
=
eventRects
.
selectAll
(
'.'
+
CLASS
[
_eventRect
]);
eventRectUpdate
=
$$
.
eventRect
.
data
(
function
(
d
)
{
return
d
;
});
// enter
$$
.
generateEventRectsForSingleX
(
eventRectUpdate
.
enter
());
// update
$$
.
updateEventRect
(
eventRectUpdate
);
// exit
eventRectUpdate
.
exit
().
remove
();
}
};
c3_chart_internal_fn
.
updateEventRect
=
function
(
eventRectUpdate
)
{
var
$$
=
this
,
config
=
$$
.
config
,
x
,
y
,
w
,
h
,
rectW
,
rectX
;
// set update selection if null
eventRectUpdate
=
eventRectUpdate
||
$$
.
eventRect
.
data
(
function
(
d
)
{
return
d
;
});
if
(
$$
.
isMultipleX
())
{
// TODO: rotated not supported yet
x
=
0
;
y
=
0
;
w
=
$$
.
width
;
h
=
$$
.
height
;
}
else
{
if
((
$$
.
isCustomX
()
||
$$
.
isTimeSeries
())
&&
!
$$
.
isCategorized
())
{
rectW
=
function
(
d
)
{
var
prevX
=
$$
.
getPrevX
(
d
.
index
),
nextX
=
$$
.
getNextX
(
d
.
index
),
dx
=
$$
.
data
.
xs
[
d
.
id
][
d
.
index
],
w
=
(
$$
.
x
(
nextX
?
nextX
:
dx
)
-
$$
.
x
(
prevX
?
prevX
:
dx
))
/
2
;
return
w
<
0
?
0
:
w
;
};
rectX
=
function
(
d
)
{
var
prevX
=
$$
.
getPrevX
(
d
.
index
),
dx
=
$$
.
data
.
xs
[
d
.
id
][
d
.
index
];
return
(
$$
.
x
(
dx
)
+
$$
.
x
(
prevX
?
prevX
:
dx
))
/
2
;
};
}
else
{
rectW
=
$$
.
getEventRectWidth
();
rectX
=
function
(
d
)
{
return
$$
.
x
(
d
.
x
)
-
(
rectW
/
2
);
};
}
x
=
config
[
__axis_rotated
]
?
0
:
rectX
;
y
=
config
[
__axis_rotated
]
?
rectX
:
0
;
w
=
config
[
__axis_rotated
]
?
$$
.
width
:
rectW
;
h
=
config
[
__axis_rotated
]
?
rectW
:
$$
.
height
;
}
eventRectUpdate
.
attr
(
'class'
,
$$
.
classEvent
.
bind
(
$$
))
.
attr
(
"x"
,
x
)
.
attr
(
"y"
,
y
)
.
attr
(
"width"
,
w
)
.
attr
(
"height"
,
h
);
};
c3_chart_internal_fn
.
generateEventRectsForSingleX
=
function
(
eventRectEnter
)
{
var
$$
=
this
,
d3
=
$$
.
d3
,
config
=
$$
.
config
;
eventRectEnter
.
append
(
"rect"
)
.
attr
(
"class"
,
generateCall
(
$$
.
classEvent
,
$$
))
.
style
(
"cursor"
,
config
[
__data_selection_enabled
]
&&
config
[
__data_selection_grouped
]
?
"pointer"
:
null
)
.
on
(
'mouseover'
,
function
(
d
)
{
var
index
=
d
.
index
,
selectedData
,
newData
;
if
(
$$
.
dragging
)
{
return
;
}
// do nothing if dragging
if
(
$$
.
hasArcType
())
{
return
;
}
selectedData
=
$$
.
data
.
targets
.
map
(
function
(
t
)
{
return
$$
.
addName
(
$$
.
getValueOnIndex
(
t
.
values
,
index
));
});
// Sort selectedData as names order
newData
=
[];
Object
.
keys
(
config
[
__data_names
]).
forEach
(
function
(
id
)
{
for
(
var
j
=
0
;
j
<
selectedData
.
length
;
j
++
)
{
if
(
selectedData
[
j
]
&&
selectedData
[
j
].
id
===
id
)
{
newData
.
push
(
selectedData
[
j
]);
selectedData
.
shift
(
j
);
break
;
}
}
// cache as original id keyed
targets
.
forEach
(
function
(
d
)
{
$$
.
addCache
(
d
.
id_org
,
d
);
});
selectedData
=
newData
.
concat
(
selectedData
);
// Add remained
return
targets
;
};
// Expand shapes for selection
if
(
config
[
__point_focus_expand_enabled
])
{
$$
.
expandCircles
(
index
);
}
$$
.
expandBars
(
index
);
c3_chart_internal_fn
.
load
=
function
(
targets
,
args
)
{
var
$$
=
this
;
if
(
targets
)
{
// filter loading targets if needed
if
(
args
.
filter
)
{
targets
=
targets
.
filter
(
args
.
filter
);
}
// set type if args.types || args.type specified
if
(
args
.
type
||
args
.
types
)
{
targets
.
forEach
(
function
(
t
)
{
$$
.
setTargetType
(
t
.
id
,
args
.
types
?
args
.
types
[
t
.
id
]
:
args
.
type
);
// Call event handler
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
).
each
(
function
(
d
)
{
config
[
__data_onmouseover
].
call
(
c3
,
d
);
});
}
// Update/Add data
$$
.
data
.
targets
.
forEach
(
function
(
d
)
{
for
(
var
i
=
0
;
i
<
targets
.
length
;
i
++
)
{
if
(
d
.
id
===
targets
[
i
].
id
)
{
d
.
values
=
targets
[
i
].
values
;
targets
.
splice
(
i
,
1
);
break
;
}
}
})
.
on
(
'mouseout'
,
function
(
d
)
{
var
index
=
d
.
index
;
if
(
$$
.
hasArcType
())
{
return
;
}
$$
.
hideXGridFocus
();
$$
.
hideTooltip
();
// Undo expanded shapes
$$
.
unexpandCircles
(
index
);
$$
.
unexpandBars
();
// Call event handler
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
).
each
(
function
(
d
)
{
config
[
__data_onmouseout
].
call
(
$$
,
d
);
});
$$
.
data
.
targets
=
$$
.
data
.
targets
.
concat
(
targets
);
// add remained
}
})
.
on
(
'mousemove'
,
function
(
d
)
{
var
selectedData
,
index
=
d
.
index
,
eventRect
=
$$
.
svg
.
select
(
'.'
+
CLASS
[
_eventRect
]
+
'-'
+
index
);
// Set targets
$$
.
updateTargets
(
$$
.
data
.
targets
);
if
(
$$
.
dragging
)
{
return
;
}
// do nothing when dragging
if
(
$$
.
hasArcType
())
{
return
;
}
// Redraw with new targets
$$
.
redraw
({
withUpdateOrgXDomain
:
true
,
withUpdateXDomain
:
true
,
withLegend
:
true
});
// Show tooltip
selectedData
=
$$
.
filterTargetsToShow
(
$$
.
data
.
targets
).
map
(
function
(
t
)
{
return
$$
.
addName
(
$$
.
getValueOnIndex
(
t
.
values
,
index
));
});
if
(
args
.
done
)
{
args
.
done
();
}
};
c3_chart_internal_fn
.
loadFromArgs
=
function
(
args
)
{
var
$$
=
this
;
if
(
args
.
data
)
{
$$
.
load
(
$$
.
convertDataToTargets
(
args
.
data
),
args
);
if
(
config
[
__tooltip_grouped
])
{
$$
.
showTooltip
(
selectedData
,
d3
.
mouse
(
this
));
$$
.
showXGridFocus
(
selectedData
);
}
else
if
(
args
.
url
)
{
$$
.
convertUrlToData
(
args
.
url
,
args
.
mimeType
,
args
.
keys
,
function
(
data
)
{
$$
.
load
(
$$
.
convertDataToTargets
(
data
),
args
);
});
if
(
config
[
__tooltip_grouped
]
&&
(
!
config
[
__data_selection_enabled
]
||
config
[
__data_selection_grouped
]))
{
return
;
}
else
if
(
args
.
json
)
{
$$
.
load
(
$$
.
convertDataToTargets
(
$$
.
convertJsonToData
(
args
.
json
,
args
.
keys
)),
args
);
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
)
.
each
(
function
()
{
d3
.
select
(
this
).
classed
(
CLASS
[
_EXPANDED
],
true
);
if
(
config
[
__data_selection_enabled
])
{
eventRect
.
style
(
'cursor'
,
config
[
__data_selection_grouped
]
?
'pointer'
:
null
);
}
else
if
(
args
.
rows
)
{
$$
.
load
(
$$
.
convertDataToTargets
(
$$
.
convertRowsToData
(
args
.
rows
)),
args
);
if
(
!
config
[
__tooltip_grouped
])
{
$$
.
hideXGridFocus
();
$$
.
hideTooltip
();
if
(
!
config
[
__data_selection_grouped
])
{
$$
.
unexpandCircles
(
index
);
$$
.
unexpandBars
();
}
else
if
(
args
.
columns
)
{
$$
.
load
(
$$
.
convertDataToTargets
(
$$
.
convertColumnsToData
(
args
.
columns
)),
args
);
}
else
{
$$
.
load
(
null
,
args
);
})
.
filter
(
function
(
d
)
{
if
(
this
.
nodeName
===
'circle'
)
{
return
$$
.
isWithinCircle
(
this
,
$$
.
pointSelectR
(
d
));
}
};
c3_chart_internal_fn
.
unload
=
function
(
targetIds
,
done
)
{
var
$$
=
this
;
if
(
!
done
)
{
done
=
function
()
{};
else
if
(
this
.
nodeName
===
'path'
)
{
return
$$
.
isWithinBar
(
this
);
}
// filter existing target
targetIds
=
targetIds
.
filter
(
function
(
id
)
{
return
$$
.
hasTarget
(
$$
.
data
.
targets
,
id
);
});
// If no target, call done and return
if
(
!
targetIds
||
targetIds
.
length
===
0
)
{
done
();
return
;
})
.
each
(
function
(
d
)
{
if
(
config
[
__data_selection_enabled
]
&&
(
config
[
__data_selection_grouped
]
||
config
[
__data_selection_isselectable
](
d
)))
{
eventRect
.
style
(
'cursor'
,
'pointer'
);
}
$$
.
svg
.
selectAll
(
targetIds
.
map
(
function
(
id
)
{
return
$$
.
selectorTarget
(
id
);
}))
.
transition
()
.
style
(
'opacity'
,
0
)
.
remove
()
.
call
(
$$
.
endall
,
done
);
targetIds
.
forEach
(
function
(
id
)
{
// Reset fadein for future load
$$
.
withoutFadeIn
[
id
]
=
false
;
// Remove target's elements
if
(
$$
.
legend
)
{
$$
.
legend
.
selectAll
(
'.'
+
CLASS
[
_legendItem
]
+
$$
.
getTargetSelectorSuffix
(
id
)).
remove
();
if
(
!
config
[
__tooltip_grouped
])
{
$$
.
showTooltip
([
d
],
d3
.
mouse
(
this
));
$$
.
showXGridFocus
([
d
]);
if
(
config
[
__point_focus_expand_enabled
])
{
$$
.
expandCircles
(
index
,
d
.
id
);
}
$$
.
expandBars
(
index
,
d
.
id
);
}
// Remove target
$$
.
data
.
targets
=
$$
.
data
.
targets
.
filter
(
function
(
t
)
{
return
t
.
id
!==
id
;
});
})
.
on
(
'click'
,
function
(
d
)
{
var
index
=
d
.
index
;
if
(
$$
.
hasArcType
()
||
!
$$
.
toggleShape
)
{
return
;
}
if
(
$$
.
cancelClick
)
{
$$
.
cancelClick
=
false
;
return
;
}
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
).
each
(
function
(
d
)
{
$$
.
toggleShape
(
this
,
d
,
index
);
});
})
.
call
(
d3
.
behavior
.
drag
().
origin
(
Object
)
.
on
(
'drag'
,
function
()
{
$$
.
drag
(
d3
.
mouse
(
this
));
})
.
on
(
'dragstart'
,
function
()
{
$$
.
dragstart
(
d3
.
mouse
(
this
));
})
.
on
(
'dragend'
,
function
()
{
$$
.
dragend
();
})
)
.
on
(
"dblclick.zoom"
,
null
);
};
c3_chart_internal_fn
.
categoryName
=
function
(
i
)
{
var
config
=
this
.
config
;
return
i
<
config
[
__axis_x_categories
].
length
?
config
[
__axis_x_categories
][
i
]
:
i
;
c3_chart_internal_fn
.
generateEventRectsForMultipleXs
=
function
(
eventRectEnter
)
{
var
$$
=
this
,
d3
=
$$
.
d3
,
config
=
$$
.
config
;
eventRectEnter
.
append
(
'rect'
)
.
attr
(
'x'
,
0
)
.
attr
(
'y'
,
0
)
.
attr
(
'width'
,
$$
.
width
)
.
attr
(
'height'
,
$$
.
height
)
.
attr
(
'class'
,
CLASS
[
_eventRect
])
.
on
(
'mouseout'
,
function
()
{
if
(
$$
.
hasArcType
())
{
return
;
}
$$
.
hideXGridFocus
();
$$
.
hideTooltip
();
$$
.
unexpandCircles
();
})
.
on
(
'mousemove'
,
function
()
{
var
targetsToShow
=
$$
.
filterTargetsToShow
(
$$
.
data
.
targets
);
var
mouse
,
closest
,
sameXData
,
selectedData
;
if
(
$$
.
dragging
)
{
return
;
}
// do nothing when dragging
if
(
$$
.
hasArcType
(
targetsToShow
))
{
return
;
}
mouse
=
d3
.
mouse
(
this
);
closest
=
$$
.
findClosestFromTargets
(
targetsToShow
,
mouse
);
if
(
!
closest
)
{
return
;
}
if
(
$$
.
isScatterType
(
closest
))
{
sameXData
=
[
closest
];
}
else
{
sameXData
=
$$
.
filterSameX
(
targetsToShow
,
closest
.
x
);
}
// show tooltip when cursor is close to some point
selectedData
=
sameXData
.
map
(
function
(
d
)
{
return
$$
.
addName
(
d
);
});
$$
.
showTooltip
(
selectedData
,
mouse
);
// expand points
if
(
config
[
__point_focus_expand_enabled
])
{
$$
.
unexpandCircles
();
$$
.
expandCircles
(
closest
.
index
,
closest
.
id
);
}
// Show xgrid focus line
$$
.
showXGridFocus
(
selectedData
);
// Show cursor as pointer if point is close to mouse position
if
(
$$
.
dist
(
closest
,
mouse
)
<
100
)
{
$$
.
svg
.
select
(
'.'
+
CLASS
[
_eventRect
]).
style
(
'cursor'
,
'pointer'
);
if
(
!
$$
.
mouseover
)
{
config
[
__data_onmouseover
].
call
(
$$
,
closest
);
$$
.
mouseover
=
true
;
}
}
else
if
(
$$
.
mouseover
)
{
$$
.
svg
.
select
(
'.'
+
CLASS
[
_eventRect
]).
style
(
'cursor'
,
null
);
config
[
__data_onmouseout
].
call
(
$$
,
closest
);
$$
.
mouseover
=
false
;
}
})
.
on
(
'click'
,
function
()
{
var
targetsToShow
=
$$
.
filterTargetsToShow
(
$$
.
data
.
targets
);
var
mouse
,
closest
;
if
(
$$
.
hasArcType
(
targetsToShow
))
{
return
;
}
mouse
=
d3
.
mouse
(
this
);
closest
=
$$
.
findClosestFromTargets
(
targetsToShow
,
mouse
);
if
(
!
closest
)
{
return
;
}
// select if selection enabled
if
(
$$
.
dist
(
closest
,
mouse
)
<
100
&&
$$
.
toggleShape
)
{
$$
.
main
.
select
(
'.'
+
CLASS
[
_circles
]
+
$$
.
getTargetSelectorSuffix
(
closest
.
id
)).
select
(
'.'
+
CLASS
[
_circle
]
+
'-'
+
closest
.
index
).
each
(
function
()
{
$$
.
toggleShape
(
this
,
closest
,
closest
.
index
);
});
}
})
.
call
(
d3
.
behavior
.
drag
().
origin
(
Object
)
.
on
(
'drag'
,
function
()
{
$$
.
drag
(
d3
.
mouse
(
this
));
})
.
on
(
'dragstart'
,
function
()
{
$$
.
dragstart
(
d3
.
mouse
(
this
));
})
.
on
(
'dragend'
,
function
()
{
$$
.
dragend
();
})
)
.
on
(
"dblclick.zoom"
,
null
);
};
c3_chart_internal_fn
.
getCurrentWidth
=
function
()
{
...
...
c3.min.js
View file @
0516616d
This source diff could not be displayed because it is too large. You can
view the blob
instead.
src/core.js
View file @
0516616d
...
...
@@ -127,7 +127,7 @@ c3_chart_internal_fn.initParams = function () {
c3_chart_internal_fn
.
initWithData
=
function
(
data
)
{
var
$$
=
this
,
d3
=
$$
.
d3
,
config
=
$$
.
config
;
var
main
,
eventRect
,
binding
=
true
;
var
main
,
binding
=
true
;
if
(
$$
.
initPie
)
{
$$
.
initPie
();
}
if
(
$$
.
initBrush
)
{
$$
.
initBrush
();
}
...
...
@@ -220,9 +220,7 @@ c3_chart_internal_fn.initWithData = function (data) {
.
attr
(
'class'
,
CLASS
[
_chart
]);
// Cover whole with rects for events
eventRect
=
main
.
select
(
'.'
+
CLASS
[
_chart
]).
append
(
"g"
)
.
attr
(
"class"
,
CLASS
[
_eventRects
])
.
style
(
'fill-opacity'
,
0
);
$$
.
initEventRect
();
// Define g for bar chart area
if
(
$$
.
initBar
)
{
$$
.
initBar
();
}
...
...
@@ -400,9 +398,7 @@ c3_chart_internal_fn.updateTargets = function (targets) {
c3_chart_internal_fn
.
redraw
=
function
(
options
,
transitions
)
{
var
$$
=
this
,
main
=
$$
.
main
,
d3
=
$$
.
d3
,
config
=
$$
.
config
;
var
eventRect
,
eventRectUpdate
;
var
areaIndices
=
$$
.
getShapeIndices
(
$$
.
isAreaType
),
barIndices
=
$$
.
getShapeIndices
(
$$
.
isBarType
),
lineIndices
=
$$
.
getShapeIndices
(
$$
.
isLineType
),
maxDataCountTarget
;
var
rectX
,
rectW
;
var
areaIndices
=
$$
.
getShapeIndices
(
$$
.
isAreaType
),
barIndices
=
$$
.
getShapeIndices
(
$$
.
isBarType
),
lineIndices
=
$$
.
getShapeIndices
(
$$
.
isLineType
);
var
withY
,
withSubchart
,
withTransition
,
withTransitionForExit
,
withTransitionForAxis
,
withTransform
,
withUpdateXDomain
,
withUpdateOrgXDomain
,
withLegend
;
var
hideAxis
=
$$
.
hasArcType
();
var
drawArea
,
drawBar
,
drawLine
,
xForText
,
yForText
;
...
...
@@ -544,70 +540,9 @@ c3_chart_internal_fn.redraw = function (options, transitions) {
.
selectAll
(
'circle'
)
.
remove
();
// event rect
if
(
config
[
__interaction_enabled
])
{
// rect for mouseover
eventRect
=
main
.
select
(
'.'
+
CLASS
[
_eventRects
])
.
style
(
'cursor'
,
config
[
__zoom_enabled
]
?
config
[
__axis_rotated
]
?
'ns-resize'
:
'ew-resize'
:
null
);
if
(
notEmpty
(
config
[
__data_xs
])
&&
!
$$
.
isSingleX
(
config
[
__data_xs
]))
{
if
(
!
eventRect
.
classed
(
CLASS
[
_eventRectsMultiple
]))
{
eventRect
.
classed
(
CLASS
[
_eventRectsMultiple
],
true
).
classed
(
CLASS
[
_eventRectsSingle
],
false
)
.
selectAll
(
'.'
+
CLASS
[
_eventRect
]).
remove
();
}
eventRectUpdate
=
main
.
select
(
'.'
+
CLASS
[
_eventRects
]).
selectAll
(
'.'
+
CLASS
[
_eventRect
])
.
data
([
0
]);
// enter : only one rect will be added
$$
.
generateEventRectsForMultipleXs
(
eventRectUpdate
.
enter
());
// update
eventRectUpdate
.
attr
(
'x'
,
0
)
.
attr
(
'y'
,
0
)
.
attr
(
'width'
,
$$
.
width
)
.
attr
(
'height'
,
$$
.
height
);
// exit : not needed because always only one rect exists
}
else
{
if
(
!
eventRect
.
classed
(
CLASS
[
_eventRectsSingle
]))
{
eventRect
.
classed
(
CLASS
[
_eventRectsMultiple
],
false
).
classed
(
CLASS
[
_eventRectsSingle
],
true
)
.
selectAll
(
'.'
+
CLASS
[
_eventRect
]).
remove
();
}
if
((
$$
.
isCustomX
()
||
$$
.
isTimeSeries
())
&&
!
$$
.
isCategorized
())
{
rectW
=
function
(
d
)
{
var
prevX
=
$$
.
getPrevX
(
d
.
index
),
nextX
=
$$
.
getNextX
(
d
.
index
),
dx
=
$$
.
data
.
xs
[
d
.
id
][
d
.
index
],
w
=
(
$$
.
x
(
nextX
?
nextX
:
dx
)
-
$$
.
x
(
prevX
?
prevX
:
dx
))
/
2
;
return
w
<
0
?
0
:
w
;
};
rectX
=
function
(
d
)
{
var
prevX
=
$$
.
getPrevX
(
d
.
index
),
dx
=
$$
.
data
.
xs
[
d
.
id
][
d
.
index
];
return
(
$$
.
x
(
dx
)
+
$$
.
x
(
prevX
?
prevX
:
dx
))
/
2
;
};
}
else
{
rectW
=
$$
.
getEventRectWidth
();
rectX
=
function
(
d
)
{
return
$$
.
x
(
d
.
x
)
-
(
rectW
/
2
);
};
}
// Set data
maxDataCountTarget
=
$$
.
getMaxDataCountTarget
(
$$
.
data
.
targets
);
main
.
select
(
'.'
+
CLASS
[
_eventRects
])
.
datum
(
maxDataCountTarget
?
maxDataCountTarget
.
values
:
[]);
// Update rects
eventRectUpdate
=
main
.
select
(
'.'
+
CLASS
[
_eventRects
]).
selectAll
(
'.'
+
CLASS
[
_eventRect
])
.
data
(
function
(
d
)
{
return
d
;
});
// enter
$$
.
generateEventRectsForSingleX
(
eventRectUpdate
.
enter
());
// update
eventRectUpdate
.
attr
(
'class'
,
generateCall
(
$$
.
classEvent
,
$$
))
.
attr
(
"x"
,
config
[
__axis_rotated
]
?
0
:
rectX
)
.
attr
(
"y"
,
config
[
__axis_rotated
]
?
rectX
:
0
)
.
attr
(
"width"
,
config
[
__axis_rotated
]
?
$$
.
width
:
rectW
)
.
attr
(
"height"
,
config
[
__axis_rotated
]
?
rectW
:
$$
.
height
);
// exit
eventRectUpdate
.
exit
().
remove
();
}
$$
.
redrawEventRect
();
}
// transition should be derived from one transition
...
...
@@ -616,30 +551,8 @@ c3_chart_internal_fn.redraw = function (options, transitions) {
$$
.
addTransitionForBar
(
transitions
,
drawBar
);
$$
.
addTransitionForLine
(
transitions
,
drawLine
);
/*
transitions.push(mainLine.transition()
.attr("d", drawLine)
.style("stroke", $$.color)
.style("opacity", 1));
*/
$$
.
addTransitionForArea
(
transitions
,
drawArea
);
/*
transitions.push(mainArea.transition()
.attr("d", drawArea)
.style("fill", $$.color)
.style("opacity", $$.orgAreaOpacity));
*/
$$
.
addTransitionForCircle
(
transitions
,
cx
,
cy
);
/*
transitions.push(mainCircle.transition()
.style('opacity', generateCall($$.opacityForCircle, $$))
.style("fill", $$.color)
.attr("cx", cx)
.attr("cy", cy));
transitions.push(main.selectAll('.' + CLASS[_selectedCircle]).transition()
.attr("cx", cx)
.attr("cy", cy));
*/
$$
.
addTransitionForText
(
transitions
,
xForText
,
yForText
,
options
.
flow
);
$$
.
addTransitionForRegion
(
transitions
);
$$
.
addTransitionForGrid
(
transitions
);
...
...
@@ -769,11 +682,7 @@ c3_chart_internal_fn.redraw = function (options, transitions) {
mainRegion
.
select
(
'rect'
).
filter
(
$$
.
isRegionOnX
)
.
attr
(
"x"
,
generateCall
(
$$
.
regionX
,
$$
))
.
attr
(
"width"
,
generateCall
(
$$
.
regionWidth
,
$$
));
eventRectUpdate
.
attr
(
"x"
,
config
[
__axis_rotated
]
?
0
:
rectX
)
.
attr
(
"y"
,
config
[
__axis_rotated
]
?
rectX
:
0
)
.
attr
(
"width"
,
config
[
__axis_rotated
]
?
$$
.
width
:
rectW
)
.
attr
(
"height"
,
config
[
__axis_rotated
]
?
rectW
:
$$
.
height
);
$$
.
updateEventRect
();
// callback for end of flow
done
();
...
...
@@ -815,219 +724,6 @@ c3_chart_internal_fn.updateAndRedraw = function (options) {
$$
.
redraw
(
options
,
transitions
);
};
c3_chart_internal_fn
.
generateEventRectsForSingleX
=
function
(
eventRectEnter
)
{
var
$$
=
this
,
d3
=
$$
.
d3
,
config
=
$$
.
config
;
eventRectEnter
.
append
(
"rect"
)
.
attr
(
"class"
,
generateCall
(
$$
.
classEvent
,
$$
))
.
style
(
"cursor"
,
config
[
__data_selection_enabled
]
&&
config
[
__data_selection_grouped
]
?
"pointer"
:
null
)
.
on
(
'mouseover'
,
function
(
d
)
{
var
index
=
d
.
index
,
selectedData
,
newData
;
if
(
$$
.
dragging
)
{
return
;
}
// do nothing if dragging
if
(
$$
.
hasArcType
())
{
return
;
}
selectedData
=
$$
.
data
.
targets
.
map
(
function
(
t
)
{
return
$$
.
addName
(
$$
.
getValueOnIndex
(
t
.
values
,
index
));
});
// Sort selectedData as names order
newData
=
[];
Object
.
keys
(
config
[
__data_names
]).
forEach
(
function
(
id
)
{
for
(
var
j
=
0
;
j
<
selectedData
.
length
;
j
++
)
{
if
(
selectedData
[
j
]
&&
selectedData
[
j
].
id
===
id
)
{
newData
.
push
(
selectedData
[
j
]);
selectedData
.
shift
(
j
);
break
;
}
}
});
selectedData
=
newData
.
concat
(
selectedData
);
// Add remained
// Expand shapes for selection
if
(
config
[
__point_focus_expand_enabled
])
{
$$
.
expandCircles
(
index
);
}
$$
.
expandBars
(
index
);
// Call event handler
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
).
each
(
function
(
d
)
{
config
[
__data_onmouseover
].
call
(
c3
,
d
);
});
})
.
on
(
'mouseout'
,
function
(
d
)
{
var
index
=
d
.
index
;
if
(
$$
.
hasArcType
())
{
return
;
}
$$
.
hideXGridFocus
();
$$
.
hideTooltip
();
// Undo expanded shapes
$$
.
unexpandCircles
(
index
);
$$
.
unexpandBars
();
// Call event handler
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
).
each
(
function
(
d
)
{
config
[
__data_onmouseout
].
call
(
$$
,
d
);
});
})
.
on
(
'mousemove'
,
function
(
d
)
{
var
selectedData
,
index
=
d
.
index
,
eventRect
=
$$
.
svg
.
select
(
'.'
+
CLASS
[
_eventRect
]
+
'-'
+
index
);
if
(
$$
.
dragging
)
{
return
;
}
// do nothing when dragging
if
(
$$
.
hasArcType
())
{
return
;
}
// Show tooltip
selectedData
=
$$
.
filterTargetsToShow
(
$$
.
data
.
targets
).
map
(
function
(
t
)
{
return
$$
.
addName
(
$$
.
getValueOnIndex
(
t
.
values
,
index
));
});
if
(
config
[
__tooltip_grouped
])
{
$$
.
showTooltip
(
selectedData
,
d3
.
mouse
(
this
));
$$
.
showXGridFocus
(
selectedData
);
}
if
(
config
[
__tooltip_grouped
]
&&
(
!
config
[
__data_selection_enabled
]
||
config
[
__data_selection_grouped
]))
{
return
;
}
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
)
.
each
(
function
()
{
d3
.
select
(
this
).
classed
(
CLASS
[
_EXPANDED
],
true
);
if
(
config
[
__data_selection_enabled
])
{
eventRect
.
style
(
'cursor'
,
config
[
__data_selection_grouped
]
?
'pointer'
:
null
);
}
if
(
!
config
[
__tooltip_grouped
])
{
$$
.
hideXGridFocus
();
$$
.
hideTooltip
();
if
(
!
config
[
__data_selection_grouped
])
{
$$
.
unexpandCircles
(
index
);
$$
.
unexpandBars
();
}
}
})
.
filter
(
function
(
d
)
{
if
(
this
.
nodeName
===
'circle'
)
{
return
$$
.
isWithinCircle
(
this
,
$$
.
pointSelectR
(
d
));
}
else
if
(
this
.
nodeName
===
'path'
)
{
return
$$
.
isWithinBar
(
this
);
}
})
.
each
(
function
(
d
)
{
if
(
config
[
__data_selection_enabled
]
&&
(
config
[
__data_selection_grouped
]
||
config
[
__data_selection_isselectable
](
d
)))
{
eventRect
.
style
(
'cursor'
,
'pointer'
);
}
if
(
!
config
[
__tooltip_grouped
])
{
$$
.
showTooltip
([
d
],
d3
.
mouse
(
this
));
$$
.
showXGridFocus
([
d
]);
if
(
config
[
__point_focus_expand_enabled
])
{
$$
.
expandCircles
(
index
,
d
.
id
);
}
$$
.
expandBars
(
index
,
d
.
id
);
}
});
})
.
on
(
'click'
,
function
(
d
)
{
var
index
=
d
.
index
;
if
(
$$
.
hasArcType
()
||
!
$$
.
toggleShape
)
{
return
;
}
if
(
$$
.
cancelClick
)
{
$$
.
cancelClick
=
false
;
return
;
}
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
).
each
(
function
(
d
)
{
$$
.
toggleShape
(
this
,
d
,
index
);
});
})
.
call
(
d3
.
behavior
.
drag
().
origin
(
Object
)
.
on
(
'drag'
,
function
()
{
$$
.
drag
(
d3
.
mouse
(
this
));
})
.
on
(
'dragstart'
,
function
()
{
$$
.
dragstart
(
d3
.
mouse
(
this
));
})
.
on
(
'dragend'
,
function
()
{
$$
.
dragend
();
})
)
.
on
(
"dblclick.zoom"
,
null
);
};
c3_chart_internal_fn
.
generateEventRectsForMultipleXs
=
function
(
eventRectEnter
)
{
var
$$
=
this
,
d3
=
$$
.
d3
,
config
=
$$
.
config
;
eventRectEnter
.
append
(
'rect'
)
.
attr
(
'x'
,
0
)
.
attr
(
'y'
,
0
)
.
attr
(
'width'
,
$$
.
width
)
.
attr
(
'height'
,
$$
.
height
)
.
attr
(
'class'
,
CLASS
[
_eventRect
])
.
on
(
'mouseout'
,
function
()
{
if
(
$$
.
hasArcType
())
{
return
;
}
$$
.
hideXGridFocus
();
$$
.
hideTooltip
();
$$
.
unexpandCircles
();
})
.
on
(
'mousemove'
,
function
()
{
var
targetsToShow
=
$$
.
filterTargetsToShow
(
$$
.
data
.
targets
);
var
mouse
,
closest
,
sameXData
,
selectedData
;
if
(
$$
.
dragging
)
{
return
;
}
// do nothing when dragging
if
(
$$
.
hasArcType
(
targetsToShow
))
{
return
;
}
mouse
=
d3
.
mouse
(
this
);
closest
=
$$
.
findClosestFromTargets
(
targetsToShow
,
mouse
);
if
(
!
closest
)
{
return
;
}
if
(
$$
.
isScatterType
(
closest
))
{
sameXData
=
[
closest
];
}
else
{
sameXData
=
$$
.
filterSameX
(
targetsToShow
,
closest
.
x
);
}
// show tooltip when cursor is close to some point
selectedData
=
sameXData
.
map
(
function
(
d
)
{
return
$$
.
addName
(
d
);
});
$$
.
showTooltip
(
selectedData
,
mouse
);
// expand points
if
(
config
[
__point_focus_expand_enabled
])
{
$$
.
unexpandCircles
();
$$
.
expandCircles
(
closest
.
index
,
closest
.
id
);
}
// Show xgrid focus line
$$
.
showXGridFocus
(
selectedData
);
// Show cursor as pointer if point is close to mouse position
if
(
$$
.
dist
(
closest
,
mouse
)
<
100
)
{
$$
.
svg
.
select
(
'.'
+
CLASS
[
_eventRect
]).
style
(
'cursor'
,
'pointer'
);
if
(
!
$$
.
mouseover
)
{
config
[
__data_onmouseover
].
call
(
$$
,
closest
);
$$
.
mouseover
=
true
;
}
}
else
if
(
$$
.
mouseover
)
{
$$
.
svg
.
select
(
'.'
+
CLASS
[
_eventRect
]).
style
(
'cursor'
,
null
);
config
[
__data_onmouseout
].
call
(
$$
,
closest
);
$$
.
mouseover
=
false
;
}
})
.
on
(
'click'
,
function
()
{
var
targetsToShow
=
$$
.
filterTargetsToShow
(
$$
.
data
.
targets
);
var
mouse
,
closest
;
if
(
$$
.
hasArcType
(
targetsToShow
))
{
return
;
}
mouse
=
d3
.
mouse
(
this
);
closest
=
$$
.
findClosestFromTargets
(
targetsToShow
,
mouse
);
if
(
!
closest
)
{
return
;
}
// select if selection enabled
if
(
$$
.
dist
(
closest
,
mouse
)
<
100
&&
$$
.
toggleShape
)
{
$$
.
main
.
select
(
'.'
+
CLASS
[
_circles
]
+
$$
.
getTargetSelectorSuffix
(
closest
.
id
)).
select
(
'.'
+
CLASS
[
_circle
]
+
'-'
+
closest
.
index
).
each
(
function
()
{
$$
.
toggleShape
(
this
,
closest
,
closest
.
index
);
});
}
})
.
call
(
d3
.
behavior
.
drag
().
origin
(
Object
)
.
on
(
'drag'
,
function
()
{
$$
.
drag
(
d3
.
mouse
(
this
));
})
.
on
(
'dragstart'
,
function
()
{
$$
.
dragstart
(
d3
.
mouse
(
this
));
})
.
on
(
'dragend'
,
function
()
{
$$
.
dragend
();
})
)
.
on
(
"dblclick.zoom"
,
null
);
};
c3_chart_internal_fn
.
isTimeSeries
=
function
()
{
return
this
.
config
[
__axis_x_type
]
===
'timeseries'
;
};
...
...
src/data.js
View file @
0516616d
...
...
@@ -38,8 +38,12 @@ c3_chart_internal_fn.addXs = function (xs) {
$$
.
config
[
__data_xs
][
id
]
=
xs
[
id
];
});
};
c3_chart_internal_fn
.
isSingleX
=
function
(
xs
)
{
return
this
.
d3
.
set
(
Object
.
keys
(
xs
).
map
(
function
(
id
)
{
return
xs
[
id
];
})).
size
()
===
1
;
c3_chart_internal_fn
.
hasMultipleX
=
function
(
xs
)
{
return
this
.
d3
.
set
(
Object
.
keys
(
xs
).
map
(
function
(
id
)
{
return
xs
[
id
];
})).
size
()
>
1
;
};
c3_chart_internal_fn
.
isMultipleX
=
function
()
{
var
$$
=
this
,
config
=
$$
.
config
;
return
notEmpty
(
config
[
__data_xs
])
&&
$$
.
hasMultipleX
(
config
[
__data_xs
]);
};
c3_chart_internal_fn
.
addName
=
function
(
data
)
{
var
$$
=
this
,
name
;
...
...
src/interaction.js
0 → 100644
View file @
0516616d
c3_chart_internal_fn
.
initEventRect
=
function
()
{
var
$$
=
this
,
CLASS
=
$$
.
CLASS
;
$$
.
main
.
select
(
'.'
+
CLASS
[
_chart
]).
append
(
"g"
)
.
attr
(
"class"
,
CLASS
[
_eventRects
])
.
style
(
'fill-opacity'
,
0
);
};
c3_chart_internal_fn
.
redrawEventRect
=
function
()
{
var
$$
=
this
,
config
=
$$
.
config
,
CLASS
=
$$
.
CLASS
,
eventRectUpdate
,
maxDataCountTarget
,
isMultipleX
=
$$
.
isMultipleX
();
// rects for mouseover
var
eventRects
=
$$
.
main
.
select
(
'.'
+
CLASS
[
_eventRects
])
.
style
(
'cursor'
,
config
[
__zoom_enabled
]
?
config
[
__axis_rotated
]
?
'ns-resize'
:
'ew-resize'
:
null
)
.
classed
(
CLASS
[
_eventRectsMultiple
],
isMultipleX
)
.
classed
(
CLASS
[
_eventRectsSingle
],
!
isMultipleX
);
// clear old rects
eventRects
.
selectAll
(
'.'
+
CLASS
[
_eventRect
]).
remove
();
// open as public variable
$$
.
eventRect
=
eventRects
.
selectAll
(
'.'
+
CLASS
[
_eventRect
]);
if
(
isMultipleX
)
{
eventRectUpdate
=
$$
.
eventRect
.
data
([
0
]);
// enter : only one rect will be added
$$
.
generateEventRectsForMultipleXs
(
eventRectUpdate
.
enter
());
// update
$$
.
updateEventRect
(
eventRectUpdate
);
// exit : not needed because always only one rect exists
}
else
{
// Set data and update $$.eventRect
maxDataCountTarget
=
$$
.
getMaxDataCountTarget
(
$$
.
data
.
targets
);
eventRects
.
datum
(
maxDataCountTarget
?
maxDataCountTarget
.
values
:
[]);
$$
.
eventRect
=
eventRects
.
selectAll
(
'.'
+
CLASS
[
_eventRect
]);
eventRectUpdate
=
$$
.
eventRect
.
data
(
function
(
d
)
{
return
d
;
});
// enter
$$
.
generateEventRectsForSingleX
(
eventRectUpdate
.
enter
());
// update
$$
.
updateEventRect
(
eventRectUpdate
);
// exit
eventRectUpdate
.
exit
().
remove
();
}
};
c3_chart_internal_fn
.
updateEventRect
=
function
(
eventRectUpdate
)
{
var
$$
=
this
,
config
=
$$
.
config
,
x
,
y
,
w
,
h
,
rectW
,
rectX
;
// set update selection if null
eventRectUpdate
=
eventRectUpdate
||
$$
.
eventRect
.
data
(
function
(
d
)
{
return
d
;
});
if
(
$$
.
isMultipleX
())
{
// TODO: rotated not supported yet
x
=
0
;
y
=
0
;
w
=
$$
.
width
;
h
=
$$
.
height
;
}
else
{
if
((
$$
.
isCustomX
()
||
$$
.
isTimeSeries
())
&&
!
$$
.
isCategorized
())
{
rectW
=
function
(
d
)
{
var
prevX
=
$$
.
getPrevX
(
d
.
index
),
nextX
=
$$
.
getNextX
(
d
.
index
),
dx
=
$$
.
data
.
xs
[
d
.
id
][
d
.
index
],
w
=
(
$$
.
x
(
nextX
?
nextX
:
dx
)
-
$$
.
x
(
prevX
?
prevX
:
dx
))
/
2
;
return
w
<
0
?
0
:
w
;
};
rectX
=
function
(
d
)
{
var
prevX
=
$$
.
getPrevX
(
d
.
index
),
dx
=
$$
.
data
.
xs
[
d
.
id
][
d
.
index
];
return
(
$$
.
x
(
dx
)
+
$$
.
x
(
prevX
?
prevX
:
dx
))
/
2
;
};
}
else
{
rectW
=
$$
.
getEventRectWidth
();
rectX
=
function
(
d
)
{
return
$$
.
x
(
d
.
x
)
-
(
rectW
/
2
);
};
}
x
=
config
[
__axis_rotated
]
?
0
:
rectX
;
y
=
config
[
__axis_rotated
]
?
rectX
:
0
;
w
=
config
[
__axis_rotated
]
?
$$
.
width
:
rectW
;
h
=
config
[
__axis_rotated
]
?
rectW
:
$$
.
height
;
}
eventRectUpdate
.
attr
(
'class'
,
$$
.
classEvent
.
bind
(
$$
))
.
attr
(
"x"
,
x
)
.
attr
(
"y"
,
y
)
.
attr
(
"width"
,
w
)
.
attr
(
"height"
,
h
);
};
c3_chart_internal_fn
.
generateEventRectsForSingleX
=
function
(
eventRectEnter
)
{
var
$$
=
this
,
d3
=
$$
.
d3
,
config
=
$$
.
config
;
eventRectEnter
.
append
(
"rect"
)
.
attr
(
"class"
,
generateCall
(
$$
.
classEvent
,
$$
))
.
style
(
"cursor"
,
config
[
__data_selection_enabled
]
&&
config
[
__data_selection_grouped
]
?
"pointer"
:
null
)
.
on
(
'mouseover'
,
function
(
d
)
{
var
index
=
d
.
index
,
selectedData
,
newData
;
if
(
$$
.
dragging
)
{
return
;
}
// do nothing if dragging
if
(
$$
.
hasArcType
())
{
return
;
}
selectedData
=
$$
.
data
.
targets
.
map
(
function
(
t
)
{
return
$$
.
addName
(
$$
.
getValueOnIndex
(
t
.
values
,
index
));
});
// Sort selectedData as names order
newData
=
[];
Object
.
keys
(
config
[
__data_names
]).
forEach
(
function
(
id
)
{
for
(
var
j
=
0
;
j
<
selectedData
.
length
;
j
++
)
{
if
(
selectedData
[
j
]
&&
selectedData
[
j
].
id
===
id
)
{
newData
.
push
(
selectedData
[
j
]);
selectedData
.
shift
(
j
);
break
;
}
}
});
selectedData
=
newData
.
concat
(
selectedData
);
// Add remained
// Expand shapes for selection
if
(
config
[
__point_focus_expand_enabled
])
{
$$
.
expandCircles
(
index
);
}
$$
.
expandBars
(
index
);
// Call event handler
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
).
each
(
function
(
d
)
{
config
[
__data_onmouseover
].
call
(
c3
,
d
);
});
})
.
on
(
'mouseout'
,
function
(
d
)
{
var
index
=
d
.
index
;
if
(
$$
.
hasArcType
())
{
return
;
}
$$
.
hideXGridFocus
();
$$
.
hideTooltip
();
// Undo expanded shapes
$$
.
unexpandCircles
(
index
);
$$
.
unexpandBars
();
// Call event handler
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
).
each
(
function
(
d
)
{
config
[
__data_onmouseout
].
call
(
$$
,
d
);
});
})
.
on
(
'mousemove'
,
function
(
d
)
{
var
selectedData
,
index
=
d
.
index
,
eventRect
=
$$
.
svg
.
select
(
'.'
+
CLASS
[
_eventRect
]
+
'-'
+
index
);
if
(
$$
.
dragging
)
{
return
;
}
// do nothing when dragging
if
(
$$
.
hasArcType
())
{
return
;
}
// Show tooltip
selectedData
=
$$
.
filterTargetsToShow
(
$$
.
data
.
targets
).
map
(
function
(
t
)
{
return
$$
.
addName
(
$$
.
getValueOnIndex
(
t
.
values
,
index
));
});
if
(
config
[
__tooltip_grouped
])
{
$$
.
showTooltip
(
selectedData
,
d3
.
mouse
(
this
));
$$
.
showXGridFocus
(
selectedData
);
}
if
(
config
[
__tooltip_grouped
]
&&
(
!
config
[
__data_selection_enabled
]
||
config
[
__data_selection_grouped
]))
{
return
;
}
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
)
.
each
(
function
()
{
d3
.
select
(
this
).
classed
(
CLASS
[
_EXPANDED
],
true
);
if
(
config
[
__data_selection_enabled
])
{
eventRect
.
style
(
'cursor'
,
config
[
__data_selection_grouped
]
?
'pointer'
:
null
);
}
if
(
!
config
[
__tooltip_grouped
])
{
$$
.
hideXGridFocus
();
$$
.
hideTooltip
();
if
(
!
config
[
__data_selection_grouped
])
{
$$
.
unexpandCircles
(
index
);
$$
.
unexpandBars
();
}
}
})
.
filter
(
function
(
d
)
{
if
(
this
.
nodeName
===
'circle'
)
{
return
$$
.
isWithinCircle
(
this
,
$$
.
pointSelectR
(
d
));
}
else
if
(
this
.
nodeName
===
'path'
)
{
return
$$
.
isWithinBar
(
this
);
}
})
.
each
(
function
(
d
)
{
if
(
config
[
__data_selection_enabled
]
&&
(
config
[
__data_selection_grouped
]
||
config
[
__data_selection_isselectable
](
d
)))
{
eventRect
.
style
(
'cursor'
,
'pointer'
);
}
if
(
!
config
[
__tooltip_grouped
])
{
$$
.
showTooltip
([
d
],
d3
.
mouse
(
this
));
$$
.
showXGridFocus
([
d
]);
if
(
config
[
__point_focus_expand_enabled
])
{
$$
.
expandCircles
(
index
,
d
.
id
);
}
$$
.
expandBars
(
index
,
d
.
id
);
}
});
})
.
on
(
'click'
,
function
(
d
)
{
var
index
=
d
.
index
;
if
(
$$
.
hasArcType
()
||
!
$$
.
toggleShape
)
{
return
;
}
if
(
$$
.
cancelClick
)
{
$$
.
cancelClick
=
false
;
return
;
}
$$
.
main
.
selectAll
(
'.'
+
CLASS
[
_shape
]
+
'-'
+
index
).
each
(
function
(
d
)
{
$$
.
toggleShape
(
this
,
d
,
index
);
});
})
.
call
(
d3
.
behavior
.
drag
().
origin
(
Object
)
.
on
(
'drag'
,
function
()
{
$$
.
drag
(
d3
.
mouse
(
this
));
})
.
on
(
'dragstart'
,
function
()
{
$$
.
dragstart
(
d3
.
mouse
(
this
));
})
.
on
(
'dragend'
,
function
()
{
$$
.
dragend
();
})
)
.
on
(
"dblclick.zoom"
,
null
);
};
c3_chart_internal_fn
.
generateEventRectsForMultipleXs
=
function
(
eventRectEnter
)
{
var
$$
=
this
,
d3
=
$$
.
d3
,
config
=
$$
.
config
;
eventRectEnter
.
append
(
'rect'
)
.
attr
(
'x'
,
0
)
.
attr
(
'y'
,
0
)
.
attr
(
'width'
,
$$
.
width
)
.
attr
(
'height'
,
$$
.
height
)
.
attr
(
'class'
,
CLASS
[
_eventRect
])
.
on
(
'mouseout'
,
function
()
{
if
(
$$
.
hasArcType
())
{
return
;
}
$$
.
hideXGridFocus
();
$$
.
hideTooltip
();
$$
.
unexpandCircles
();
})
.
on
(
'mousemove'
,
function
()
{
var
targetsToShow
=
$$
.
filterTargetsToShow
(
$$
.
data
.
targets
);
var
mouse
,
closest
,
sameXData
,
selectedData
;
if
(
$$
.
dragging
)
{
return
;
}
// do nothing when dragging
if
(
$$
.
hasArcType
(
targetsToShow
))
{
return
;
}
mouse
=
d3
.
mouse
(
this
);
closest
=
$$
.
findClosestFromTargets
(
targetsToShow
,
mouse
);
if
(
!
closest
)
{
return
;
}
if
(
$$
.
isScatterType
(
closest
))
{
sameXData
=
[
closest
];
}
else
{
sameXData
=
$$
.
filterSameX
(
targetsToShow
,
closest
.
x
);
}
// show tooltip when cursor is close to some point
selectedData
=
sameXData
.
map
(
function
(
d
)
{
return
$$
.
addName
(
d
);
});
$$
.
showTooltip
(
selectedData
,
mouse
);
// expand points
if
(
config
[
__point_focus_expand_enabled
])
{
$$
.
unexpandCircles
();
$$
.
expandCircles
(
closest
.
index
,
closest
.
id
);
}
// Show xgrid focus line
$$
.
showXGridFocus
(
selectedData
);
// Show cursor as pointer if point is close to mouse position
if
(
$$
.
dist
(
closest
,
mouse
)
<
100
)
{
$$
.
svg
.
select
(
'.'
+
CLASS
[
_eventRect
]).
style
(
'cursor'
,
'pointer'
);
if
(
!
$$
.
mouseover
)
{
config
[
__data_onmouseover
].
call
(
$$
,
closest
);
$$
.
mouseover
=
true
;
}
}
else
if
(
$$
.
mouseover
)
{
$$
.
svg
.
select
(
'.'
+
CLASS
[
_eventRect
]).
style
(
'cursor'
,
null
);
config
[
__data_onmouseout
].
call
(
$$
,
closest
);
$$
.
mouseover
=
false
;
}
})
.
on
(
'click'
,
function
()
{
var
targetsToShow
=
$$
.
filterTargetsToShow
(
$$
.
data
.
targets
);
var
mouse
,
closest
;
if
(
$$
.
hasArcType
(
targetsToShow
))
{
return
;
}
mouse
=
d3
.
mouse
(
this
);
closest
=
$$
.
findClosestFromTargets
(
targetsToShow
,
mouse
);
if
(
!
closest
)
{
return
;
}
// select if selection enabled
if
(
$$
.
dist
(
closest
,
mouse
)
<
100
&&
$$
.
toggleShape
)
{
$$
.
main
.
select
(
'.'
+
CLASS
[
_circles
]
+
$$
.
getTargetSelectorSuffix
(
closest
.
id
)).
select
(
'.'
+
CLASS
[
_circle
]
+
'-'
+
closest
.
index
).
each
(
function
()
{
$$
.
toggleShape
(
this
,
closest
,
closest
.
index
);
});
}
})
.
call
(
d3
.
behavior
.
drag
().
origin
(
Object
)
.
on
(
'drag'
,
function
()
{
$$
.
drag
(
d3
.
mouse
(
this
));
})
.
on
(
'dragstart'
,
function
()
{
$$
.
dragstart
(
d3
.
mouse
(
this
));
})
.
on
(
'dragend'
,
function
()
{
$$
.
dragend
();
})
)
.
on
(
"dblclick.zoom"
,
null
);
};
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