From 7f5a025de45b06683f08866da2e9680dd149422f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=B6khan=20=C3=96zen?= Date: Thu, 4 Feb 2016 15:14:34 +0100 Subject: [PATCH] rebased, conflict resolved, bugfixed, refactored and tests added --- spec/arc-spec.js | 93 +++++++++++++++++++++++++++++++++++++++++++++ spec/legend-spec.js | 64 +++++++++++++++++++++++++++++++ src/arc.js | 34 +++++++++-------- src/config.js | 1 + src/core.js | 8 +--- 5 files changed, 177 insertions(+), 23 deletions(-) diff --git a/spec/arc-spec.js b/spec/arc-spec.js index 5a8038e..1c00224 100644 --- a/spec/arc-spec.js +++ b/spec/arc-spec.js @@ -193,6 +193,99 @@ describe('c3 chart arc', function () { }); }); }); + + describe('with more than one data_column ', function () { + beforeAll(function () { + args = { + data: { + columns: [ + ['padded1', 100], + ['padded2', 90], + ['padded3', 50], + ['padded4', 20] + ] + }, + type: 'gauge', + color: { + pattern: ['#FF0000', '#F97600', '#F6C600', '#60B044'], + threshold: { + values: [30, 80, 95] + } + } + } + }); + var arcColor = ['#60b044', '#f6c600', '#f97600', '#ff0000']; + + describe('should contain arcs ', function () { + it('each data_column should have one arc', function () { + chart.internal.main.selectAll('.c3-chart-arc .c3-arc').each(function (d, i) { + expect(d3.select(this).classed('c3-chart-data-' + args.data.columns[i][0])).toBeTruthy(); + }) + }); + + it('each arc should have the color from color_pattern if color_treshold is given ', function () { + chart.internal.main.selectAll('.c3-chart-arc .c3-arc').each(function (d, i) { + expect(d3.select(this).style('fill')).toBe(arcColor[i]); + }); + }); + }); + + describe('should contain backgrounds ', function () { + it('each data_column should have one background', function () { + chart.internal.main.selectAll('.c3-chart-arcs path.c3-chart-arcs-background').each(function (d, i) { + expect(d3.select(this).classed('c3-chart-arcs-background-'+ i)).toBeTruthy(); + }) + }); + + it('each background should have tbe same color', function () { + chart.internal.main.selectAll('.c3-chart-arcs path.c3-chart-arcs-background').each(function (d, i) { + expect(d3.select(this).style('fill')).toBe('#e0e0e0'); + }); + }); + }); + + describe('should contain labels', function () { + it('each data_column should have a label', function () { + chart.internal.main.selectAll('.c3-chart-arc .c3-gauge-value').each(function (d, i) { + expect(d3.select(this).text()).toBe(args.data.columns[i][1]); + }) + }); + + it('each label should have the same color', function () { + chart.internal.main.selectAll('.c3-chart-arc .c3-gauge-value').each(function (d, i) { + expect(d3.select(this).style('fill')).toBe('#000'); + }); + + }); + + it('if only one data_column is visible the label should have "" for transform', function () { + setTimeout(function () { + var textBeforeHide = chart.internal.main.select('.c3-chart-arc.c3-target.c3-target-padded4 text'); + expect(textBeforeHide.attr('transform')).not.toBe(''); + },1000); + chart.hide(['padded1', 'padded2', 'padded3']); + setTimeout(function () { + var textAfterHide = chart.internal.main.select('.c3-chart-arc.c3-target.c3-target-padded4 text'); + expect(textAfterHide.attr('transform')).toBe(''); + },1000); + + }); + }); + + describe('should contain labellines', function () { + it('each data_column should have a labelline', function () { + chart.internal.main.selectAll('.c3-chart-arc .c3-arc-label-line').each(function (d, i) { + expect(d3.select(this).classed('c3-data-' + args.data.columns[i][0])).toBeTruthy(); + }) + }); + + it('each labelline should have the color from color_pattern if color_treshold is given', function () { + chart.internal.main.selectAll('.c3-chart-arc .c3-arc-label-line').each(function (d, i) { + expect(d3.select(this).style('fill')).toBe(arcColor[i]); + }); + }); + }); + }); }); }); diff --git a/spec/legend-spec.js b/spec/legend-spec.js index 1f7b869..06b5b20 100644 --- a/spec/legend-spec.js +++ b/spec/legend-spec.js @@ -274,4 +274,68 @@ describe('c3 chart legend', function () { }); }); + describe('legend item tile coloring with color_treshold', function () { + beforeAll(function () { + args = { + data: { + columns: [ + ['padded1', 100], + ['padded2', 90], + ['padded3', 50], + ['padded4', 20] + ] + }, + type: 'gauge', + color: { + pattern: ['#FF0000', '#F97600', '#F6C600', '#60B044'], + threshold: { + values: [30, 80, 95] + } + } + } + }); + + // espacially for gauges with multiple arcs to have the same coloring between legend tiles, tooltip tiles and arc + it('selects the color from color_pattern if color_treshold is given', function () { + var tileColor = []; + d3.selectAll('.c3-legend-item-tile').each(function () { + tileColor.push(d3.select(this).style('stroke')); + }); + expect(tileColor[0]).toBe('rgb(96, 176, 68)'); + expect(tileColor[1]).toBe('rgb(246, 198, 0)'); + expect(tileColor[2]).toBe('rgb(249, 118, 0)'); + expect(tileColor[3]).toBe('rgb(255, 0, 0)'); + }) + }); + + describe('legend item tile coloring without color_treshold', function () { + beforeAll(function () { + args = { + data: { + columns: [ + ['padded1', 100], + ['padded2', 90], + ['padded3', 50], + ['padded4', 20] + ], + colors: { + 'padded1': '#60b044', + 'padded4': '#8b008b' + } + }, + type: 'gauge' + } + }); + + it('selects the color from data_colors, data_color or default', function () { + var tileColor = []; + d3.selectAll('.c3-legend-item-tile').each(function () { + tileColor.push(d3.select(this).style('stroke')); + }); + expect(tileColor[0]).toBe('rgb(96, 176, 68)'); + expect(tileColor[1]).toBe('rgb(31, 119, 180)'); + expect(tileColor[2]).toBe('rgb(255, 127, 14)'); + expect(tileColor[3]).toBe('rgb(139, 0, 139)'); + }) + }); }); diff --git a/src/arc.js b/src/arc.js index e285935..cb79bfb 100644 --- a/src/arc.js +++ b/src/arc.js @@ -15,7 +15,7 @@ c3_chart_internal_fn.initPie = function () { c3_chart_internal_fn.updateRadius = function () { var $$ = this, config = $$.config, w = config.gauge_width || config.donut_width, - gaugeArcWidth = $$.visibleTargetCount * $$.config.gauge_arcs_minWidth; + gaugeArcWidth = $$.filterTargetsToShow($$.data.targets).length * $$.config.gauge_arcs_minWidth; $$.radiusExpanded = Math.min($$.arcWidth, $$.arcHeight) / 2 * ($$.hasType('gauge') ? 0.85 : 1); $$.radius = $$.radiusExpanded * 0.95; $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6; @@ -66,7 +66,7 @@ c3_chart_internal_fn.updateAngle = function (d) { c3_chart_internal_fn.getSvgArc = function () { var $$ = this, hasGaugeType = $$.hasType('gauge'), - singleArcWidth = $$.gaugeArcWidth / $$.visibleTargetCount, + singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, arc = $$.d3.svg.arc().outerRadius(function(d) { return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius; }).innerRadius(function(d) { @@ -86,7 +86,7 @@ c3_chart_internal_fn.getSvgArc = function () { c3_chart_internal_fn.getSvgArcExpanded = function (rate) { rate = rate || 1; var $$ = this, hasGaugeType = $$.hasType('gauge'), - singleArcWidth = $$.gaugeArcWidth / $$.visibleTargetCount, + singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length, expandWidth = Math.min($$.radiusExpanded * rate - $$.radius, singleArcWidth * 0.8 - (1 - rate) * 100), arc = $$.d3.svg.arc().outerRadius(function(d){ return hasGaugeType ? $$.radius - singleArcWidth * d.index + expandWidth : $$.radiusExpanded * rate; @@ -121,7 +121,7 @@ c3_chart_internal_fn.transformForArcLabel = function (d) { } translate = "translate(" + (x * ratio) + ',' + (y * ratio) + ")"; } - else if (updated && hasGauge && $$.visibleTargetCount > 1) { + else if (updated && hasGauge && $$.filterTargetsToShow($$.data.targets).length > 1) { var y1 = Math.sin(updated.endAngle - Math.PI / 2); x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25); y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3; @@ -310,7 +310,7 @@ c3_chart_internal_fn.initArc = function () { c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransform) { var $$ = this, d3 = $$.d3, config = $$.config, main = $$.main, - mainArc, mainArcLabelLine, hasGaugeType = $$.hasType('gauge'); + mainArc, backgroundArc, mainArcLabelLine, hasGaugeType = $$.hasType('gauge'); mainArc = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arc) .data($$.arcData.bind($$)); mainArc.enter().append('path') @@ -329,18 +329,18 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf .data($$.arcData.bind($$)); mainArcLabelLine.enter().append('rect') .attr("class", function (d) { return CLASS.arcLabelLine + ' ' + CLASS.target + ' ' + CLASS.target + '-' + d.data.id; }); - if ($$.visibleTargetCount === 1) { + if ($$.filterTargetsToShow($$.data.targets).length === 1) { mainArcLabelLine.style("display", "none"); } else { mainArcLabelLine .style("fill", function (d) { return config.color_pattern.length > 0 ? $$.levelColor(d.data.values[0].value) : $$.color(d.data); }) - .style("display", config.gauge_label_show ? "" : "none") + .style("display", config.gauge_labelLine_show ? "" : "none") .each(function (d) { var lineLength = 0, lineThickness = 2, x = 0, y = 0, transform = ""; if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) { var updated = $$.updateAngle(d), - innerLineLength = $$.gaugeArcWidth / $$.visibleTargetCount * (updated.index + 1), + innerLineLength = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length * (updated.index + 1), lineAngle = updated.endAngle - Math.PI / 2, arcInnerRadius = $$.radius - innerLineLength, linePositioningAngle = lineAngle - (arcInnerRadius === 0 ? 0 : (1 / arcInnerRadius)); @@ -450,7 +450,7 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf .attr('class', function (d) { return $$.isGaugeType(d.data) ? CLASS.gaugeValue : ''; }) .text($$.textForArcLabel.bind($$)) .attr("transform", $$.transformForArcLabel.bind($$)) - .style('font-size', function (d) { return $$.isGaugeType(d.data) && $$.visibleTargetCount === 1 ? Math.round($$.radius / 5) + 'px' : ''; }) + .style('font-size', function (d) { return $$.isGaugeType(d.data) && $$.filterTargetsToShow($$.data.targets).length === 1 ? Math.round($$.radius / 5) + 'px' : ''; }) .transition().duration(duration) .style("opacity", function (d) { return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0; }); main.select('.' + CLASS.chartArcsTitle) @@ -458,7 +458,10 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf if (hasGaugeType) { var index = 0; - $$.arcs.selectAll('.' + CLASS.chartArcsBackground) + backgroundArc = $$.arcs.select('g.' + CLASS.chartArcsBackground).selectAll('path.' + CLASS.chartArcsBackground).data($$.data.targets); + backgroundArc.enter().append("path"); + backgroundArc + .attr("class", function (d, i) { return CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground +'-'+ i}) .attr("d", function (d1) { if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) { return "M 0 0"; } @@ -470,6 +473,8 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf }; return $$.getArc(d, true, true); }); + backgroundArc.exit().remove(); + $$.arcs.select('.' + CLASS.chartArcsGaugeUnit) .attr("dy", ".75em") .text(config.gauge_label_show ? config.gauge_units : ''); @@ -484,13 +489,10 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf } }; c3_chart_internal_fn.initGauge = function () { - var $$ = this, arcs = $$.arcs; + var arcs = this.arcs; if (this.hasType('gauge')) { - arcs.selectAll().data($$.data.targets).enter() - .append('path') - .attr("class", function(d) { - return CLASS.chartArcsBackground + ' ' + CLASS.target +'-'+ d.id; - }); + arcs.append('g') + .attr("class", CLASS.chartArcsBackground); arcs.append("text") .attr("class", CLASS.chartArcsGaugeUnit) .style("text-anchor", "middle") diff --git a/src/config.js b/src/config.js index 539f686..6762555 100644 --- a/src/config.js +++ b/src/config.js @@ -183,6 +183,7 @@ c3_chart_internal_fn.getDefaultConfig = function () { // gauge gauge_fullCircle: false, gauge_label_show: true, + gauge_labelLine_show: true, gauge_label_format: undefined, gauge_min: 0, gauge_max: 100, diff --git a/src/core.js b/src/core.js index 62cfd6b..5a0b7c9 100644 --- a/src/core.js +++ b/src/core.js @@ -139,7 +139,6 @@ c3_chart_internal_fn.initParams = function () { ["%Y/%-m/%-d", function () { return true; }] ]); - $$.visibleTargetCount = config.data_hide === true ? 0 : (config.data_columns ? (config.data_columns.length - (config.data_hide ? config.data_hide.length : 0)) : 0); $$.hiddenTargetIds = []; $$.hiddenLegendIds = []; $$.focusedTargetIds = []; @@ -225,11 +224,6 @@ c3_chart_internal_fn.initWithData = function (data) { $$.addHiddenLegendIds(config.legend_hide === true ? $$.mapToIds($$.data.targets) : config.legend_hide); } - // when gauge, hide legend // TODO: fix - if ($$.hasType('gauge') && $$.config.data_columns.length <= 1) { - config.legend_show = false; - } - // Init sizes and scales $$.updateSizes(); $$.updateScales(); @@ -781,7 +775,7 @@ c3_chart_internal_fn.getTranslate = function (target) { y = config.axis_rotated ? 0 : $$.height2; } else if (target === 'arc') { x = $$.arcWidth / 2; - y = $$.arcHeight / 2; + y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0);// to prevent wrong display of min and max label } return "translate(" + x + "," + y + ")"; };