Browse Source

Merge pull request #2 from masayuki0812/master

Update fork
pull/204/head
Peter Göbel 11 years ago
parent
commit
02df7024be
  1. 2
      bower.json
  2. 389
      c3.js
  3. 6
      c3.min.js
  4. 39
      htdocs/samples/axes_x_tick_culling.html
  5. 55
      htdocs/samples/axes_x_tick_rotate.html
  6. 32
      htdocs/samples/grids.html
  7. 2
      htdocs/samples/simple.html
  8. 2
      package.json

2
bower.json

@ -1,7 +1,7 @@
{ {
"name": "c3", "name": "c3",
"main": "c3.min.js", "main": "c3.min.js",
"version": "0.1.33", "version": "0.1.34",
"homepage": "https://github.com/masayuki0812/c3", "homepage": "https://github.com/masayuki0812/c3",
"authors": [ "authors": [
"Masayuki Tanaka <masayuki0812@mac.com>" "Masayuki Tanaka <masayuki0812@mac.com>"

389
c3.js

@ -2,7 +2,7 @@
'use strict'; 'use strict';
var c3 = { var c3 = {
version: "0.1.33" version: "0.1.34"
}; };
var CLASS = { var CLASS = {
@ -33,12 +33,15 @@
shape: 'c3-shape', shape: 'c3-shape',
shapes: 'c3-shapes', shapes: 'c3-shapes',
line: 'c3-line', line: 'c3-line',
lines: 'c3-lines',
bar: 'c3-bar', bar: 'c3-bar',
bars: 'c3-bars', bars: 'c3-bars',
circle: 'c3-circle', circle: 'c3-circle',
circles: 'c3-circles', circles: 'c3-circles',
arc: 'c3-arc', arc: 'c3-arc',
arcs: 'c3-arcs',
area: 'c3-area', area: 'c3-area',
areas: 'c3-areas',
text: 'c3-text', text: 'c3-text',
texts: 'c3-texts', texts: 'c3-texts',
grid: 'c3-grid', grid: 'c3-grid',
@ -193,7 +196,7 @@
__axis_y_label = getConfig(['axis', 'y', 'label'], {}), __axis_y_label = getConfig(['axis', 'y', 'label'], {}),
__axis_y_inner = getConfig(['axis', 'y', 'inner'], false), __axis_y_inner = getConfig(['axis', 'y', 'inner'], false),
__axis_y_tick_format = getConfig(['axis', 'y', 'tick', 'format']), __axis_y_tick_format = getConfig(['axis', 'y', 'tick', 'format']),
__axis_y_padding = getConfig(['axis', 'y', 'padding'], {}), __axis_y_padding = getConfig(['axis', 'y', 'padding']),
__axis_y_ticks = getConfig(['axis', 'y', 'ticks'], 10), __axis_y_ticks = getConfig(['axis', 'y', 'ticks'], 10),
__axis_y2_show = getConfig(['axis', 'y2', 'show'], false), __axis_y2_show = getConfig(['axis', 'y2', 'show'], false),
__axis_y2_max = getConfig(['axis', 'y2', 'max']), __axis_y2_max = getConfig(['axis', 'y2', 'max']),
@ -202,7 +205,7 @@
__axis_y2_label = getConfig(['axis', 'y2', 'label'], {}), __axis_y2_label = getConfig(['axis', 'y2', 'label'], {}),
__axis_y2_inner = getConfig(['axis', 'y2', 'inner'], false), __axis_y2_inner = getConfig(['axis', 'y2', 'inner'], false),
__axis_y2_tick_format = getConfig(['axis', 'y2', 'tick', 'format']), __axis_y2_tick_format = getConfig(['axis', 'y2', 'tick', 'format']),
__axis_y2_padding = getConfig(['axis', 'y2', 'padding'], {}), __axis_y2_padding = getConfig(['axis', 'y2', 'padding']),
__axis_y2_ticks = getConfig(['axis', 'y2', 'ticks'], 10); __axis_y2_ticks = getConfig(['axis', 'y2', 'ticks'], 10);
// grid // grid
@ -576,6 +579,9 @@
} }
firstData = target.values[0], lastData = target.values[target.values.length - 1]; firstData = target.values[0], lastData = target.values[target.values.length - 1];
base = x(lastData.x) - x(firstData.x); base = x(lastData.x) - x(firstData.x);
if (base === 0) {
return __axis_rotated ? height : width;
}
maxDataCount = getMaxDataCount(); maxDataCount = getMaxDataCount();
ratio = (hasBarType(c3.data.targets) ? (maxDataCount - (isCategorized ? 0.25 : 1)) / maxDataCount : 1); ratio = (hasBarType(c3.data.targets) ? (maxDataCount - (isCategorized ? 0.25 : 1)) / maxDataCount : 1);
return maxDataCount > 1 ? (base * ratio) / (maxDataCount - 1) : base; return maxDataCount > 1 ? (base * ratio) / (maxDataCount - 1) : base;
@ -689,7 +695,8 @@
} }
} else { } else {
axis.tickOffset = function () { axis.tickOffset = function () {
var edgeX = getEdgeX(c3.data.targets), base = x(edgeX[1]) - x(edgeX[0]); var edgeX = getEdgeX(c3.data.targets), diff = x(edgeX[1]) - x(edgeX[0]),
base = diff ? diff : (__axis_rotated ? height : width);
return (base / getMaxDataCount()) / 2; return (base / getMaxDataCount()) / 2;
}; };
} }
@ -1335,6 +1342,11 @@
firstX = xDomain[0], lastX = xDomain[1], firstX = xDomain[0], lastX = xDomain[1],
padding = getXDomainPadding(targets), padding = getXDomainPadding(targets),
min = 0, max = 0; min = 0, max = 0;
// show center of x domain if min and max are the same
if ((firstX - lastX) === 0) {
firstX = isTimeSeries ? new Date(firstX.getTime() * 0.5) : -0.5;
lastX = isTimeSeries ? new Date(lastX.getTime() * 1.5) : 0.5;
}
if (firstX || firstX === 0) { if (firstX || firstX === 0) {
min = isTimeSeries ? new Date(firstX.getTime() - padding.left) : firstX - padding.left; min = isTimeSeries ? new Date(firstX.getTime() - padding.left) : firstX - padding.left;
} }
@ -1729,13 +1741,16 @@
function classTexts(d) { return generateClass(CLASS.texts, d.id); } function classTexts(d) { return generateClass(CLASS.texts, d.id); }
function classShape(d, i) { return generateClass(CLASS.shape, i); } function classShape(d, i) { return generateClass(CLASS.shape, i); }
function classShapes(d) { return generateClass(CLASS.shapes, d.id); } function classShapes(d) { return generateClass(CLASS.shapes, d.id); }
function classLine(d) { return classShapes(d) + generateClass(CLASS.line, d.id); } function classLine(d) { return classShape(d) + generateClass(CLASS.line, d.id); }
function classLines(d) { return classShapes(d) + generateClass(CLASS.lines, d.id); }
function classCircle(d, i) { return classShape(d, i) + generateClass(CLASS.circle, i); } function classCircle(d, i) { return classShape(d, i) + generateClass(CLASS.circle, i); }
function classCircles(d) { return classShapes(d) + generateClass(CLASS.circles, d.id); } function classCircles(d) { return classShapes(d) + generateClass(CLASS.circles, d.id); }
function classBar(d, i) { return classShape(d, i) + generateClass(CLASS.bar, i); } function classBar(d, i) { return classShape(d, i) + generateClass(CLASS.bar, i); }
function classBars(d) { return classShapes(d) + generateClass(CLASS.bars, d.id); } function classBars(d) { return classShapes(d) + generateClass(CLASS.bars, d.id); }
function classArc(d) { return classShapes(d.data) + generateClass(CLASS.arc, d.data.id); } function classArc(d) { return classShape(d.data) + generateClass(CLASS.arc, d.data.id); }
function classArea(d) { return classShapes(d) + generateClass(CLASS.area, d.id); } function classArcs(d) { return classShapes(d.data) + generateClass(CLASS.arcs, d.data.id); }
function classArea(d) { return classShape(d) + generateClass(CLASS.area, d.id); }
function classAreas(d) { return classShapes(d) + generateClass(CLASS.areas, d.id); }
function classRegion(d, i) { return generateClass(CLASS.region, i) + ' ' + ('class' in d ? d.class : ''); } function classRegion(d, i) { return generateClass(CLASS.region, i) + ' ' + ('class' in d ? d.class : ''); }
function classEvent(d, i) { return generateClass(CLASS.eventRect, i); } function classEvent(d, i) { return generateClass(CLASS.eventRect, i); }
function classTarget(id) { function classTarget(id) {
@ -1781,7 +1796,7 @@
} }
function getDataLabelWidth(min, max) { function getDataLabelWidth(min, max) {
var widths = [], paddingCoef = 1.3; var widths = [], paddingCoef = 1.3;
d3.select('svg').selectAll('.dummy') selectChart.select('svg').selectAll('.dummy')
.data([min, max]) .data([min, max])
.enter().append('text') .enter().append('text')
.text(function (d) { return d; }) .text(function (d) { return d; })
@ -2121,10 +2136,13 @@
function isArcType(d) { function isArcType(d) {
return isPieType(d) || isDonutType(d); return isPieType(d) || isDonutType(d);
} }
/* not used
function lineData(d) { function lineData(d) {
return isLineType(d) ? d.values : []; return isLineType(d) ? [d] : [];
}
function arcData(d) {
return isArcType(d.data) ? [d] : [];
} }
/* not used
function scatterData(d) { function scatterData(d) {
return isScatterType(d) ? d.values : []; return isScatterType(d) ? d.values : [];
} }
@ -2261,7 +2279,7 @@
function selectBar(target, d) { function selectBar(target, d) {
__data_onselected(d, target.node()); __data_onselected(d, target.node());
target.transition().duration(100).style("fill", function () { return d3.rgb(color(d)).darker(1); }); target.transition().duration(100).style("fill", function () { return d3.rgb(color(d)).brighter(0.75); });
} }
function unselectBar(target, d) { function unselectBar(target, d) {
__data_onunselected(d, target.node()); __data_onunselected(d, target.node());
@ -2270,6 +2288,12 @@
function toggleBar(selected, target, d, i) { function toggleBar(selected, target, d, i) {
selected ? selectBar(target, d, i) : unselectBar(target, d, i); selected ? selectBar(target, d, i) : unselectBar(target, d, i);
} }
function toggleArc(selected, target, d, i) {
toggleBar(selected, target, d.data, i);
}
function getToggle(that) {
return that.nodeName === 'circle' ? togglePoint : (d3.select(that).classed(CLASS.bar) ? toggleBar : toggleArc);
}
function filterRemoveNull(data) { function filterRemoveNull(data) {
return data.filter(function (d) { return isValue(d.value); }); return data.filter(function (d) { return isValue(d.value); });
@ -2408,17 +2432,17 @@
function generateGetBarPoints(barIndices, isSub) { function generateGetBarPoints(barIndices, isSub) {
var barTargetsNum = barIndices.__max__ + 1, var barTargetsNum = barIndices.__max__ + 1,
barW = getBarW(xAxis, barTargetsNum), barW = getBarW(xAxis, barTargetsNum),
x = getBarX(barW, barTargetsNum, barIndices, !!isSub), barX = getBarX(barW, barTargetsNum, barIndices, !!isSub),
y = getBarY(!!isSub), barY = getBarY(!!isSub),
barOffset = getBarOffset(barIndices, !!isSub), barOffset = getBarOffset(barIndices, !!isSub),
yScale = isSub ? getSubYScale : getYScale; yScale = isSub ? getSubYScale : getYScale;
return function (d, i) { return function (d, i) {
var y0 = yScale(d.id)(0), var y0 = yScale(d.id)(0),
offset = barOffset(d, i) || y0, // offset is for stacked bar chart offset = barOffset(d, i) || y0, // offset is for stacked bar chart
posX = x(d), posY = y(d); posX = barX(d), posY = barY(d);
// fix posY not to overflow opposite quadrant // fix posY not to overflow opposite quadrant
if (__axis_rotated) { if (__axis_rotated) {
if ((d.value > 0 && posY < offset) || (d.value < 0 && posY > offset)) { posY = offset; } if ((0 < d.value && posY < y0) || (d.value < 0 && y0 < posY)) { posY = y0; }
} }
// 4 points that make a bar // 4 points that make a bar
return [ return [
@ -2593,32 +2617,15 @@
// Define svgs // Define svgs
svg = selectChart.append("svg") svg = selectChart.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.on('mouseenter', __onenter) .on('mouseenter', __onenter)
.on('mouseleave', __onleave); .on('mouseleave', __onleave);
// Define defs // Define defs
defs = svg.append("defs"); defs = svg.append("defs");
defs.append("clipPath") defs.append("clipPath").attr("id", clipId).append("rect");
.attr("id", clipId) defs.append("clipPath").attr("id", clipIdForXAxis).append("rect");
.append("rect") defs.append("clipPath").attr("id", clipIdForYAxis).append("rect");
.attr("width", width) updateSvgSize();
.attr("height", height);
defs.append("clipPath")
.attr("id", clipIdForXAxis)
.append("rect")
.attr("x", getXAxisClipX)
.attr("y", getXAxisClipY)
.attr("width", getXAxisClipWidth)
.attr("height", getXAxisClipHeight);
defs.append("clipPath")
.attr("id", clipIdForYAxis)
.append("rect")
.attr("x", getYAxisClipX)
.attr("y", getYAxisClipY)
.attr("width", getYAxisClipWidth)
.attr("height", getYAxisClipHeight);
// Define regions // Define regions
main = svg.append("g").attr("transform", translate.main); main = svg.append("g").attr("transform", translate.main);
@ -2649,6 +2656,33 @@
/*-- Main Region --*/ /*-- Main Region --*/
// Grids
grid = main.append('g')
.attr("clip-path", clipPath)
.attr('class', CLASS.grid);
// X-Grid
if (__grid_x_show) {
grid.append("g").attr("class", CLASS.xgrids);
}
if (notEmpty(__grid_x_lines)) {
grid.append('g').attr("class", CLASS.xgridLines);
}
if (__point_focus_line_enabled) {
grid.append('g')
.attr("class", CLASS.xgridFocus)
.append('line')
.attr('class', CLASS.xgridFocus);
}
// Y-Grid
if (__grid_y_show) {
grid.append('g').attr('class', CLASS.ygrids);
}
if (notEmpty(__grid_y_lines)) {
grid.append('g').attr('class', CLASS.ygridLines);
}
// Add Axis // Add Axis
if (__axis_x_show) { if (__axis_x_show) {
main.append("g") main.append("g")
@ -2683,33 +2717,6 @@
.style("text-anchor", textAnchorForY2AxisLabel); .style("text-anchor", textAnchorForY2AxisLabel);
} }
// Grids
grid = main.append('g')
.attr("clip-path", clipPath)
.attr('class', CLASS.grid);
// X-Grid
if (__grid_x_show) {
grid.append("g").attr("class", CLASS.xgrids);
}
if (notEmpty(__grid_x_lines)) {
grid.append('g').attr("class", CLASS.xgridLines);
}
if (__point_focus_line_enabled) {
grid.append('g')
.attr("class", CLASS.xgridFocus)
.append('line')
.attr('class', CLASS.xgridFocus);
}
// Y-Grid
if (__grid_y_show) {
grid.append('g').attr('class', CLASS.ygrids);
}
if (notEmpty(__grid_y_lines)) {
grid.append('g').attr('class', CLASS.ygridLines);
}
// Regions // Regions
main.append('g') main.append('g')
.attr("clip-path", clipPath) .attr("clip-path", clipPath)
@ -3034,17 +3041,20 @@
.call(zoom).on("dblclick.zoom", null); .call(zoom).on("dblclick.zoom", null);
} }
function toggleShape(target, d, i) { function toggleShape(that, d, i) {
var shape = d3.select(target), var shape = d3.select(that), isSelected = shape.classed(CLASS.SELECTED), isWithin, toggle;
isSelected = shape.classed(CLASS.SELECTED); if (that.nodeName === 'circle') {
var isWithin = false, toggle; isWithin = isWithinCircle(that, pointSelectR(d) * 1.5);
if (target.nodeName === 'circle') {
isWithin = isWithinCircle(target, pointSelectR(d) * 1.5);
toggle = togglePoint; toggle = togglePoint;
} }
else if (target.nodeName === 'path') { else if (that.nodeName === 'path') {
isWithin = isWithinBar(target); if (shape.classed(CLASS.bar)) {
toggle = toggleBar; isWithin = isWithinBar(that);
toggle = toggleBar;
} else { // would be arc
isWithin = true;
toggle = toggleArc;
}
} }
if (__data_selection_grouped || isWithin) { if (__data_selection_grouped || isWithin) {
if (__data_selection_enabled && __data_selection_isselectable(d)) { if (__data_selection_enabled && __data_selection_isselectable(d)) {
@ -3057,7 +3067,7 @@
shape.classed(CLASS.SELECTED, !isSelected); shape.classed(CLASS.SELECTED, !isSelected);
toggle(!isSelected, shape, d, i); toggle(!isSelected, shape, d, i);
} }
__data_onclick(d, target); __data_onclick(d, that);
} }
} }
@ -3141,7 +3151,7 @@
function redraw(options) { function redraw(options) {
var xaxis, subxaxis, yaxis, y2axis, xgrid, xgridData, xgridLines, xgridLine, ygrid, ygridLines, ygridLine; var xaxis, subxaxis, yaxis, y2axis, xgrid, xgridData, xgridLines, xgridLine, ygrid, ygridLines, ygridLine;
var mainCircle, mainBar, mainRegion, mainText, contextBar, eventRect, eventRectUpdate; var mainLine, mainArea, mainCircle, mainBar, mainArc, mainRegion, mainText, contextLine, contextBar, eventRect, eventRectUpdate;
var barIndices = getBarIndices(), maxDataCountTarget; var barIndices = getBarIndices(), maxDataCountTarget;
var rectX, rectW; var rectX, rectW;
var withY, withSubchart, withTransition, withTransitionForExit, withTransitionForAxis, withTransform, withUpdateXDomain, withUpdateOrgXDomain, withLegend; var withY, withSubchart, withTransition, withTransitionForExit, withTransitionForAxis, withTransform, withUpdateXDomain, withUpdateOrgXDomain, withLegend;
@ -3229,14 +3239,14 @@
break; break;
} }
} }
d3.selectAll('.' + CLASS.axisX + ' .tick text').each(function (e) { svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function (e) {
var index = tickValues.indexOf(e); var index = tickValues.indexOf(e);
if (index >= 0) { if (index >= 0) {
d3.select(this).style('display', index % intervalForCulling ? 'none' : 'block'); d3.select(this).style('display', index % intervalForCulling ? 'none' : 'block');
} }
}); });
} else { } else {
d3.selectAll('.' + CLASS.axisX + ' .tick text').style('display', 'block'); svg.selectAll('.' + CLASS.axisX + ' .tick text').style('display', 'block');
} }
} }
@ -3388,55 +3398,53 @@
mainBar = main.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar) mainBar = main.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar)
.data(barData); .data(barData);
mainBar.enter().append('path') mainBar.enter().append('path')
.attr('d', drawBar) .attr("class", classBar)
.style("stroke", 'none') .style("stroke", 'none')
.style("opacity", 0) .style("fill", color);
.style("fill", function (d) { return color(d); })
.attr("class", classBar);
mainBar mainBar
.style("opacity", initialOpacity) .style("opacity", initialOpacity)
.transition().duration(duration) .transition().duration(duration)
.attr('d', drawBar) .attr('d', drawBar)
.style("fill", color)
.style("opacity", 1); .style("opacity", 1);
mainBar.exit().transition().duration(durationForExit) mainBar.exit().transition().duration(durationForExit)
.style('opacity', 0) .style('opacity', 0)
.remove(); .remove();
mainText = main.selectAll('.' + CLASS.texts).selectAll('.' + CLASS.text)
.data(barOrLineData);
mainText.enter().append('text')
.attr("class", classText)
.attr('text-anchor', function (d) { return __axis_rotated ? (d.value < 0 ? 'end' : 'start') : 'middle'; })
.style("stroke", 'none')
.style("fill-opacity", 0);
mainText
.text(function (d) { return formatByAxisId(d.id)(d.value); })
.style("fill-opacity", initialOpacityForText)
.transition().duration(duration)
.attr('x', xForText)
.attr('y', yForText)
.style("fill-opacity", opacityForText);
mainText.exit()
.transition().duration(durationForExit)
.style('fill-opacity', 0)
.remove();
// lines and cricles // lines and cricles
main.selectAll('.' + CLASS.line) mainLine = main.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line)
.data(lineData);
mainLine.enter().append('path')
.attr('class', classLine)
.style("stroke", color);
mainLine
.style("opacity", initialOpacity) .style("opacity", initialOpacity)
.transition().duration(duration) .transition().duration(duration)
.attr("d", lineOnMain) .attr("d", lineOnMain)
.style("opacity", 1); .style("opacity", 1);
main.selectAll('.' + CLASS.area) mainLine.exit().transition().duration(durationForExit)
.style('opacity', 0)
.remove();
mainArea = main.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area)
.data(lineData);
mainArea.enter().append('path')
.attr("class", classArea)
.style("fill", color)
.style("opacity", function () { orgAreaOpacity = +d3.select(this).style('opacity'); return 0; });
mainArea
.style("opacity", 0) .style("opacity", 0)
.transition().duration(duration) .transition().duration(duration)
.attr("d", areaOnMain) .attr("d", areaOnMain)
.style("opacity", orgAreaOpacity); .style("opacity", orgAreaOpacity);
mainArea.exit().transition().duration(durationForExit)
.style('opacity', 0)
.remove();
mainCircle = main.selectAll('.' + CLASS.circles).selectAll('.' + CLASS.circle) mainCircle = main.selectAll('.' + CLASS.circles).selectAll('.' + CLASS.circle)
.data(lineOrScatterData); .data(lineOrScatterData);
mainCircle.enter().append("circle") mainCircle.enter().append("circle")
.attr("class", classCircle) .attr("class", classCircle)
.style('opacity', 0)
.attr("r", pointR); .attr("r", pointR);
mainCircle mainCircle
.style("opacity", initialOpacity) .style("opacity", initialOpacity)
@ -3446,10 +3454,74 @@
.attr("cy", __axis_rotated ? circleX : circleY); .attr("cy", __axis_rotated ? circleX : circleY);
mainCircle.exit().remove(); mainCircle.exit().remove();
mainText = main.selectAll('.' + CLASS.texts).selectAll('.' + CLASS.text)
.data(barOrLineData);
mainText.enter().append('text')
.attr("class", classText)
.attr('text-anchor', function (d) { return __axis_rotated ? (d.value < 0 ? 'end' : 'start') : 'middle'; })
.style("stroke", 'none')
.style("fill-opacity", 0);
mainText
.text(function (d) { return formatByAxisId(d.id)(d.value); })
.style("fill-opacity", initialOpacityForText)
.transition().duration(duration)
.attr('x', xForText)
.attr('y', yForText)
.style("fill-opacity", opacityForText);
mainText.exit()
.transition().duration(durationForExit)
.style('fill-opacity', 0)
.remove();
// arc // arc
main.each(function () { transiting = true; }).selectAll('.' + CLASS.chartArc).select('.' + CLASS.arc) mainArc = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arc)
.data(arcData);
mainArc.enter().append('path')
.attr("class", classArc)
.style("fill", function (d) { return color(d.data); })
.style("cursor", function (d) { return __data_selection_isselectable(d) ? "pointer" : null; })
.style("opacity", 0)
.each(function (d) { this._current = d; })
.on('mouseover', function (d, i) {
var updated, arcData, callback;
if (transiting) { // skip while transiting
return;
}
updated = updateAngle(d);
arcData = convertToArcData(updated);
callback = getArcOnMouseOver();
// transitions
expandArc(updated.data.id);
toggleFocusLegend(updated.data.id, true);
callback(arcData, i);
})
.on('mousemove', function (d) {
var updated = updateAngle(d), arcData = convertToArcData(updated), selectedData = [arcData];
showTooltip(selectedData, d3.mouse(this));
})
.on('mouseout', function (d, i) {
var updated, arcData, callback;
if (transiting) { // skip while transiting
return;
}
updated = updateAngle(d);
arcData = convertToArcData(updated);
callback = getArcOnMouseOut();
// transitions
unexpandArc(updated.data.id);
revertLegend();
hideTooltip();
callback(arcData, i);
})
.on('click', function (d, i) {
var updated = updateAngle(d), arcData = convertToArcData(updated), callback = getArcOnClick();
toggleShape(this, d, i);
callback(arcData, i);
});
mainArc
.attr("transform", withTransform ? "scale(0)" : "") .attr("transform", withTransform ? "scale(0)" : "")
.style("opacity", function (d) { return d === this._current ? 0 : 1; }) .style("opacity", function (d) { return d === this._current ? 0 : 1; })
.each(function () { transiting = true; })
.transition().duration(duration) .transition().duration(duration)
.attrTween("d", function (d) { .attrTween("d", function (d) {
var updated = updateAngle(d), interpolate; var updated = updateAngle(d), interpolate;
@ -3473,6 +3545,9 @@
.call(endall, function () { .call(endall, function () {
transiting = false; transiting = false;
}); });
mainArc.exit().transition().duration(durationForExit)
.style('opacity', 0)
.remove();
main.selectAll('.' + CLASS.chartArc).select('text') main.selectAll('.' + CLASS.chartArc).select('text')
.attr("transform", transformForArcLabel) .attr("transform", transformForArcLabel)
.style("opacity", 0) .style("opacity", 0)
@ -3506,10 +3581,9 @@
contextBar = context.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar) contextBar = context.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar)
.data(barData); .data(barData);
contextBar.enter().append('path') contextBar.enter().append('path')
.attr('d', drawBarOnSub) .attr("class", classBar)
.style("stroke", 'none') .style("stroke", 'none')
.style("fill", function (d) { return color(d); }) .style("fill", color);
.attr("class", classBar);
contextBar contextBar
.style("opacity", initialOpacity) .style("opacity", initialOpacity)
.transition().duration(duration) .transition().duration(duration)
@ -3519,11 +3593,19 @@
.style('opacity', 0) .style('opacity', 0)
.remove(); .remove();
// lines // lines
context.selectAll('.' + CLASS.line) contextLine = context.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line)
.data(lineData);
contextLine.enter().append('path')
.attr('class', classLine)
.style('stroke', color);
contextLine
.style("opacity", initialOpacity) .style("opacity", initialOpacity)
.transition().duration(duration) .transition().duration(duration)
.attr("d", lineOnSub) .attr("d", lineOnSub)
.style('opacity', 1); .style('opacity', 1);
contextLine.exit().transition().duration(duration)
.style('opacity', 0)
.remove();
} }
} }
@ -3702,7 +3784,7 @@
.style("pointer-events", "none"); .style("pointer-events", "none");
mainTextEnter.append('g') mainTextEnter.append('g')
.attr('class', classTexts) .attr('class', classTexts)
.style("fill", function (d) { return color(d); }); .style("fill", color);
//-- Bar --// //-- Bar --//
mainBarUpdate = main.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar) mainBarUpdate = main.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar)
@ -3715,34 +3797,28 @@
// Bars for each data // Bars for each data
mainBarEnter.append('g') mainBarEnter.append('g')
.attr("class", classBars) .attr("class", classBars)
.style("stroke", "none")
.style("cursor", function (d) { return __data_selection_isselectable(d) ? "pointer" : null; }); .style("cursor", function (d) { return __data_selection_isselectable(d) ? "pointer" : null; });
//-- Line --// //-- Line --//
mainLineUpdate = main.select('.' + CLASS.chartLines) mainLineUpdate = main.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine)
.selectAll('.' + CLASS.chartLine)
.data(targets) .data(targets)
.attr('class', classChartLine); .attr('class', classChartLine);
mainLineEnter = mainLineUpdate.enter().append('g') mainLineEnter = mainLineUpdate.enter().append('g')
.attr('class', classChartLine) .attr('class', classChartLine)
.style('opacity', 0) .style('opacity', 0)
.style("pointer-events", "none"); .style("pointer-events", "none");
// Lines for each data // Lines for each data
mainLineEnter.append("path") mainLineEnter.append('g')
.attr("class", classLine) .attr("class", classLines);
.style("opacity", 0)
.style("stroke", function (d) { return color(d); });
// Areas // Areas
mainLineEnter.append("path") mainLineEnter.append('g')
.attr("class", classArea) .attr('class', classAreas);
.style("opacity", function () { orgAreaOpacity = +d3.select(this).style('opacity'); return 0; })
.style("fill", function (d) { return color(d); });
// Circles for each data point on lines // Circles for each data point on lines
mainLineEnter.append('g') mainLineEnter.append('g')
.attr("class", function (d) { return generateClass(CLASS.selectedCircles, d.id); }); .attr("class", function (d) { return generateClass(CLASS.selectedCircles, d.id); });
mainLineEnter.append('g') mainLineEnter.append('g')
.attr("class", classCircles) .attr("class", classCircles)
.style("fill", function (d) { return color(d); }) .style("fill", color)
.style("cursor", function (d) { return __data_selection_isselectable(d) ? "pointer" : null; }); .style("cursor", function (d) { return __data_selection_isselectable(d) ? "pointer" : null; });
// Update date for selected circles // Update date for selected circles
targets.forEach(function (t) { targets.forEach(function (t) {
@ -3759,47 +3835,8 @@
.attr("class", classChartArc); .attr("class", classChartArc);
mainPieEnter = mainPieUpdate.enter().append("g") mainPieEnter = mainPieUpdate.enter().append("g")
.attr("class", classChartArc); .attr("class", classChartArc);
mainPieEnter.append("path") mainPieEnter.append('g')
.attr("class", classArc) .attr('class', classArcs);
.style("opacity", 0)
.style("fill", function (d) { return color(d.data); })
.style("cursor", function (d) { return __data_selection_isselectable(d) ? "pointer" : null; })
.each(function (d) { this._current = d; })
.on('mouseover', function (d, i) {
var updated, arcData, callback;
if (transiting) { // skip while transiting
return;
}
updated = updateAngle(d);
arcData = convertToArcData(updated);
callback = getArcOnMouseOver();
// transitions
expandArc(updated.data.id);
toggleFocusLegend(updated.data.id, true);
callback(arcData, i);
})
.on('mousemove', function (d) {
var updated = updateAngle(d), arcData = convertToArcData(updated), selectedData = [arcData];
showTooltip(selectedData, d3.mouse(this));
})
.on('mouseout', function (d, i) {
var updated, arcData, callback;
if (transiting) { // skip while transiting
return;
}
updated = updateAngle(d);
arcData = convertToArcData(updated);
callback = getArcOnMouseOut();
// transitions
unexpandArc(updated.data.id);
revertLegend();
hideTooltip();
callback(arcData, i);
})
.on('click', function (d, i) {
var updated = updateAngle(d), arcData = convertToArcData(updated), callback = getArcOnClick();
callback(arcData, i);
});
mainPieEnter.append("text") mainPieEnter.append("text")
.attr("dy", ".35em") .attr("dy", ".35em")
.style("opacity", 0) .style("opacity", 0)
@ -3820,8 +3857,7 @@
.attr('class', classChartBar); .attr('class', classChartBar);
// Bars for each data // Bars for each data
contextBarEnter.append('g') contextBarEnter.append('g')
.attr("class", classBars) .attr("class", classBars);
.style("fill", function (d) { return color(d); });
//-- Line --// //-- Line --//
contextLineUpdate = context.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine) contextLineUpdate = context.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine)
@ -3831,10 +3867,8 @@
.style('opacity', 0) .style('opacity', 0)
.attr('class', classChartLine); .attr('class', classChartLine);
// Lines for each data // Lines for each data
contextLineEnter.append("path") contextLineEnter.append('g')
.attr("class", classLine) .attr("class", classLines);
.style("opacity", 0)
.style("stroke", function (d) { return color(d); });
} }
/*-- Show --*/ /*-- Show --*/
@ -4300,26 +4334,24 @@
return d3.merge( return d3.merge(
main.selectAll('.' + CLASS.shapes + getTargetSelectorSuffix(targetId)).selectAll('.' + CLASS.shape) main.selectAll('.' + CLASS.shapes + getTargetSelectorSuffix(targetId)).selectAll('.' + CLASS.shape)
.filter(function () { return d3.select(this).classed(CLASS.SELECTED); }) .filter(function () { return d3.select(this).classed(CLASS.SELECTED); })
.map(function (d) { return d.map(function (_d) { return _d.__data__; }); }) .map(function (d) { return d.map(function (d) { var data = d.__data__; return data.data ? data.data : data; }); })
); );
}; };
c3.select = function (ids, indices, resetOther) { c3.select = function (ids, indices, resetOther) {
if (! __data_selection_enabled) { return; } if (! __data_selection_enabled) { return; }
main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) { main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) {
var shape = d3.select(this), var shape = d3.select(this), id = d.data ? d.data.id : d.id, toggle = getToggle(this),
select = (this.nodeName === 'circle') ? selectPoint : selectBar, isTargetId = __data_selection_grouped || !ids || ids.indexOf(id) >= 0,
unselect = (this.nodeName === 'circle') ? unselectPoint : unselectBar,
isTargetId = __data_selection_grouped || !ids || ids.indexOf(d.id) >= 0,
isTargetIndex = !indices || indices.indexOf(i) >= 0, isTargetIndex = !indices || indices.indexOf(i) >= 0,
isSelected = shape.classed(CLASS.SELECTED); isSelected = shape.classed(CLASS.SELECTED);
if (isTargetId && isTargetIndex) { if (isTargetId && isTargetIndex) {
if (__data_selection_isselectable(d) && !isSelected) { if (__data_selection_isselectable(d) && !isSelected) {
select(shape.classed(CLASS.SELECTED, true), d, i); toggle(true, shape.classed(CLASS.SELECTED, true), d, i);
} }
} else if (isDefined(resetOther) && resetOther) { } else if (isDefined(resetOther) && resetOther) {
if (isSelected) { if (isSelected) {
unselect(shape.classed(CLASS.SELECTED, false), d, i); toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
} }
} }
}); });
@ -4328,15 +4360,14 @@
c3.unselect = function (ids, indices) { c3.unselect = function (ids, indices) {
if (! __data_selection_enabled) { return; } if (! __data_selection_enabled) { return; }
main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) { main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) {
var shape = d3.select(this), var shape = d3.select(this), id = d.data ? d.data.id : d.id, toggle = getToggle(this),
unselect = (this.nodeName === 'circle') ? unselectPoint : unselectBar, isTargetId = __data_selection_grouped || !ids || ids.indexOf(id) >= 0,
isTargetId = __data_selection_grouped || !ids || ids.indexOf(d.id) >= 0,
isTargetIndex = !indices || indices.indexOf(i) >= 0, isTargetIndex = !indices || indices.indexOf(i) >= 0,
isSelected = shape.classed(CLASS.SELECTED); isSelected = shape.classed(CLASS.SELECTED);
if (isTargetId && isTargetIndex) { if (isTargetId && isTargetIndex) {
if (__data_selection_isselectable(d)) { if (__data_selection_isselectable(d)) {
if (isSelected) { if (isSelected) {
unselect(shape.classed(CLASS.SELECTED, false), d, i); toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
} }
} }
} }

6
c3.min.js vendored

File diff suppressed because one or more lines are too long

39
htdocs/samples/axes_x_tick_culling.html

@ -0,0 +1,39 @@
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
]
},
axis: {
x: {
tick: {
culling: {
max: 2
}
}
}
},
tooltip: {
// enabled: false
},
zoom: {
// enabled: true
},
subchart: {
// show: true
}
});
</script>
</body>
</html>

55
htdocs/samples/axes_x_tick_rotate.html

@ -0,0 +1,55 @@
<html>
<head>
<link href="/css/c3.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250, 100, 600],
['data2', 50, 20, 10, 40, 15, 25],
]
},
axis: {
// rotated: true,
x: {
tick: {
format: function () { return "hogehogehogehogehoge"; },
rotate: 30,
},
label: {
text: 'Hogehoge',
position: 'outer-middle'
},
height: 90,
},
y: {
label: {
text: 'Y Label',
position: 'outer-center'
}
}
},
subchart: {
show: true
}
});
setTimeout(function () {
chart.load({
columns: [
// ['data1', 30, 200, 100, 400, 150, 250, 100, 400],
['data1', 1030, 2000, 1000, 1400, 1500, 1250, 1100, 140000],
]
})
}, 1000);
</script>
</body>
</html>

32
htdocs/samples/grids.html

@ -0,0 +1,32 @@
<html>
<head>
<link rel="stylesheet" type="text/css" href="/css/c3.css">
</head>
<body>
<div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.js"></script>
<script>
var chart = c3.generate({
bindto: '#chart',
data: {
columns: [
['sample', 30, 200, 100, 400, 150, 250]
]
},
axis: {
// rotated: true,
},
grid: {
x: {
show: true
},
y: {
show: true
}
}
});
</script>
</body>
</html>

2
htdocs/samples/simple.html

@ -6,7 +6,7 @@
<div id="chart"></div> <div id="chart"></div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="/js/c3.min.js"></script> <script src="/js/c3.js"></script>
<script> <script>
var chart = c3.generate({ var chart = c3.generate({
bindto: '#chart', bindto: '#chart',

2
package.json

@ -1,6 +1,6 @@
{ {
"name": "c3", "name": "c3",
"version": "0.1.33", "version": "0.1.34",
"description": "D3-based reusable chart library", "description": "D3-based reusable chart library",
"main": "c3.js", "main": "c3.js",
"scripts": { "scripts": {

Loading…
Cancel
Save