Skip to content

Commit

Permalink
Merge pull request #190 from n3-charts/issue_177
Browse files Browse the repository at this point in the history
Issue 177
  • Loading branch information
Lorem Ipsum committed Feb 4, 2015
2 parents 8b03849 + 1199d58 commit a90ffd8
Show file tree
Hide file tree
Showing 100 changed files with 788 additions and 958 deletions.
66 changes: 66 additions & 0 deletions .ideas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
+ a hidden series should be considered as non-existent (doesn't impact axes, range or whatever)
+ full redraw should happen when :
- the options.series array change or deep change (add/remove one, hide/show one)
+ an update should happen when :
- the options.axes change
+ there should be a super sweet CSS classes system so that people can style the **** out of the charts

#### Options :

```coffeescript
$scope.options =
axes:
x:
key: 'x'
labelFunction: (value) -> value
type: 'linear'
min: 0
max: 10
ticks: 2
y:
type: 'linear'
min: 0
max: 1
ticks: 5
y2:
type: 'linear'
min: 0
max: 1
ticks: [1, 2, 3, 4]

# Series styling should be handled in css
# ideally, each series has either a css class or a function that returns a class
# this way, the styling can be handled in a CSS file _and_ dynamically changed
# each time $rootScope.$apply() is ran
series: [
{
id: 'myId' # or auto-generated
y: 'value'
type: 'area' # can be 'area', 'column', 'dots', 'line' (default is 'line')
label: 'Pouet'
axis: 'y' # default is 'y'
visible: true
interpolation: # or undefined ?
type: 'linear'
tension: 0.7

# color, thickness, stripes, dots, dashed ?
cssClass: (series, index, ...?) -> 'my-series'
}
]
stacks: [
{axis: "y", series: ["id_0", "id_1", "id_2"]}
]
tooltip:

# this should be better, without overlapping which is a pain to maitain
# other modes could 'none'
mode: 'scrubber'

# this is a must have, and can be used in conjunction with 'none' so that
# the tooltip is handled externally
hook: (x, y, series) -> 'pouet'

legend:
mode: 'interactive' # 'inactive', 'hidden'
```
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ It can also contain, according to your series configuration, a `y` and a `y2` ke
+ `type` : optional, can be either linear' or 'log' (default is 'linear'). If set to 'log', the data may be clamped if its computed lower bound is 0 (this means the chart won't display an actual 0, but a close value - log scales can't display zero values).
+ `min` : optional, forces the axis minimum value (default is computed from data)
+ `max` : optional, forces the axis maximum value (default is computed from data)
+ `width` : optional, forces the axis width (default is 50)


##### Series
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "n3-line-chart",
"version": "1.1.5",
"version": "1.1.6",
"main": "build/line-chart.min.js",
"ignore": [
"**/.*",
Expand Down
33 changes: 12 additions & 21 deletions build/line-chart.coffee
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
###
line-chart - v1.1.5 - 11 January 2015
line-chart - v1.1.6 - 04 February 2015
https://github.com/n3-charts/line-chart
Copyright (c) 2015 n3-charts
###
Expand Down Expand Up @@ -30,10 +30,13 @@ directive('linechart', ['n3utils', '$window', '$timeout', (n3utils, $window, $ti
dimensions.width = +(attrs.width || parent.offsetWidth || 900) - left - right
dimensions.height = +(attrs.height || parent.offsetHeight || 500) - top - bottom

return

scope.redraw = ->
scope.updateDimensions(dim)
scope.update(dim)

return

isUpdatingOptions = false
initialHandlers =
Expand Down Expand Up @@ -69,7 +72,7 @@ directive('linechart', ['n3utils', '$window', '$timeout', (n3utils, $window, $ti
if isThumbnail
_u.adjustMarginsForThumbnail(dimensions, axes)
else
_u.adjustMargins(svg, dimensions, options, scope.data)
_u.adjustMargins(dimensions, options)

_u.createContent(svg, handlers)

Expand Down Expand Up @@ -765,28 +768,16 @@ mod.factory('n3utils', ['$window', '$log', '$rootScope', ($window, $log, $rootSc
dimensions.top = defaults.top
dimensions.bottom = defaults.bottom

adjustMargins: (svg, dimensions, options, data) ->
adjustMargins: (dimensions, options) ->
this.resetMargins(dimensions)
return unless data and data.length
return unless options.series.length

dimensions.left = this.getWidestTickWidth(svg, 'y')
dimensions.right = this.getWidestTickWidth(svg, 'y2')

if dimensions.right is 0 then dimensions.right = 20

return if options.tooltip.mode is 'scrubber'
series = options.series
return unless options.axes?

leftSeries = series.filter (s) -> s.axis isnt 'y2'
leftWidest = this.getWidestOrdinate(data, leftSeries, options)
dimensions.left = this.estimateSideTooltipWidth(svg, leftWidest).width + 20
{y, y2} = options.axes

rightSeries = series.filter (s) -> s.axis is 'y2'
return unless rightSeries.length
dimensions.left = y?.width if y?.width?
dimensions.right = y2?.width if y2?.width?

rightWidest = this.getWidestOrdinate(data, rightSeries, options)
dimensions.right = this.estimateSideTooltipWidth(svg, rightWidest).width + 20
return

adjustMarginsForThumbnail: (dimensions, axes) ->
dimensions.top = 1
Expand All @@ -812,7 +803,7 @@ mod.factory('n3utils', ['$window', '$log', '$rootScope', ($window, $log, $rootSc
bbox = this.getTextBBox

ticks = svg.select(".#{axisKey}.axis").selectAll('.tick')
ticks[0]?.map (t) -> max = Math.max(max, bbox(t).width)
ticks[0]?.forEach (t) -> max = Math.max(max, bbox(t).width)

return max

Expand Down
44 changes: 13 additions & 31 deletions build/line-chart.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

/*
line-chart - v1.1.5 - 11 January 2015
line-chart - v1.1.6 - 04 February 2015
https://github.com/n3-charts/line-chart
Copyright (c) 2015 n3-charts
*/
Expand Down Expand Up @@ -32,11 +32,11 @@ directive('linechart', [
left = _u.getPixelCssProp(parent, 'padding-left');
right = _u.getPixelCssProp(parent, 'padding-right');
dimensions.width = +(attrs.width || parent.offsetWidth || 900) - left - right;
return dimensions.height = +(attrs.height || parent.offsetHeight || 500) - top - bottom;
dimensions.height = +(attrs.height || parent.offsetHeight || 500) - top - bottom;
};
scope.redraw = function() {
scope.updateDimensions(dim);
return scope.update(dim);
scope.update(dim);
};
isUpdatingOptions = false;
initialHandlers = {
Expand Down Expand Up @@ -72,7 +72,7 @@ directive('linechart', [
if (isThumbnail) {
_u.adjustMarginsForThumbnail(dimensions, axes);
} else {
_u.adjustMargins(svg, dimensions, options, scope.data);
_u.adjustMargins(dimensions, options);
}
_u.createContent(svg, handlers);
if (dataPerSeries.length) {
Expand Down Expand Up @@ -815,37 +815,19 @@ mod.factory('n3utils', [
dimensions.top = defaults.top;
return dimensions.bottom = defaults.bottom;
},
adjustMargins: function(svg, dimensions, options, data) {
var leftSeries, leftWidest, rightSeries, rightWidest, series;
adjustMargins: function(dimensions, options) {
var y, y2, _ref;
this.resetMargins(dimensions);
if (!(data && data.length)) {
return;
}
if (!options.series.length) {
if (options.axes == null) {
return;
}
dimensions.left = this.getWidestTickWidth(svg, 'y');
dimensions.right = this.getWidestTickWidth(svg, 'y2');
if (dimensions.right === 0) {
dimensions.right = 20;
}
if (options.tooltip.mode === 'scrubber') {
return;
_ref = options.axes, y = _ref.y, y2 = _ref.y2;
if ((y != null ? y.width : void 0) != null) {
dimensions.left = y != null ? y.width : void 0;
}
series = options.series;
leftSeries = series.filter(function(s) {
return s.axis !== 'y2';
});
leftWidest = this.getWidestOrdinate(data, leftSeries, options);
dimensions.left = this.estimateSideTooltipWidth(svg, leftWidest).width + 20;
rightSeries = series.filter(function(s) {
return s.axis === 'y2';
});
if (!rightSeries.length) {
return;
if ((y2 != null ? y2.width : void 0) != null) {
dimensions.right = y2 != null ? y2.width : void 0;
}
rightWidest = this.getWidestOrdinate(data, rightSeries, options);
return dimensions.right = this.estimateSideTooltipWidth(svg, rightWidest).width + 20;
},
adjustMarginsForThumbnail: function(dimensions, axes) {
dimensions.top = 1;
Expand All @@ -871,7 +853,7 @@ mod.factory('n3utils', [
bbox = this.getTextBBox;
ticks = svg.select("." + axisKey + ".axis").selectAll('.tick');
if ((_ref = ticks[0]) != null) {
_ref.map(function(t) {
_ref.forEach(function(t) {
return max = Math.max(max, bbox(t).width);
});
}
Expand Down
4 changes: 2 additions & 2 deletions build/line-chart.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "line-chart",
"version": "1.1.5",
"version": "1.1.6",
"homepage": "https://github.com/n3-charts/line-chart",
"licenses": {
"type": "MIT",
Expand Down
5 changes: 4 additions & 1 deletion src/line-chart.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@ directive('linechart', ['n3utils', '$window', '$timeout', (n3utils, $window, $ti
dimensions.width = +(attrs.width || parent.offsetWidth || 900) - left - right
dimensions.height = +(attrs.height || parent.offsetHeight || 500) - top - bottom

return

scope.redraw = ->
scope.updateDimensions(dim)
scope.update(dim)

return

isUpdatingOptions = false
initialHandlers =
Expand Down Expand Up @@ -63,7 +66,7 @@ directive('linechart', ['n3utils', '$window', '$timeout', (n3utils, $window, $ti
if isThumbnail
_u.adjustMarginsForThumbnail(dimensions, axes)
else
_u.adjustMargins(svg, dimensions, options, scope.data)
_u.adjustMargins(dimensions, options)

_u.createContent(svg, handlers)

Expand Down
26 changes: 7 additions & 19 deletions src/utils/misc.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -174,28 +174,16 @@
dimensions.top = defaults.top
dimensions.bottom = defaults.bottom

adjustMargins: (svg, dimensions, options, data) ->
adjustMargins: (dimensions, options) ->
this.resetMargins(dimensions)
return unless data and data.length
return unless options.series.length
return unless options.axes?

dimensions.left = this.getWidestTickWidth(svg, 'y')
dimensions.right = this.getWidestTickWidth(svg, 'y2')
{y, y2} = options.axes

if dimensions.right is 0 then dimensions.right = 20
dimensions.left = y?.width if y?.width?
dimensions.right = y2?.width if y2?.width?

return if options.tooltip.mode is 'scrubber'
series = options.series

leftSeries = series.filter (s) -> s.axis isnt 'y2'
leftWidest = this.getWidestOrdinate(data, leftSeries, options)
dimensions.left = this.estimateSideTooltipWidth(svg, leftWidest).width + 20

rightSeries = series.filter (s) -> s.axis is 'y2'
return unless rightSeries.length

rightWidest = this.getWidestOrdinate(data, rightSeries, options)
dimensions.right = this.estimateSideTooltipWidth(svg, rightWidest).width + 20
return

adjustMarginsForThumbnail: (dimensions, axes) ->
dimensions.top = 1
Expand All @@ -221,7 +209,7 @@
bbox = this.getTextBBox

ticks = svg.select(".#{axisKey}.axis").selectAll('.tick')
ticks[0]?.map (t) -> max = Math.max(max, bbox(t).width)
ticks[0]?.forEach (t) -> max = Math.max(max, bbox(t).width)

return max

Expand Down
8 changes: 4 additions & 4 deletions test/unit/abscissas.mocha.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ describe "abscissas", ->
linePath = element.childByClass('line')

expect(linePath.hasClass('line')).to.equal true
expect(linePath.domElement.getAttribute('d')).to.equal 'M0,410L170,370L340,300L510,290L680,220L850,30'
expect(linePath.domElement.getAttribute('d')).to.equal 'M0,410L160,370L320,300L480,290L640,220L800,30'


describe 'default key', ->
Expand Down Expand Up @@ -84,7 +84,7 @@ describe "abscissas", ->
linePath = element.childByClass('line')

expect(linePath.hasClass('line')).to.equal true
expect(linePath.domElement.getAttribute('d')).to.equal 'M0,410L170,370L340,300L510,290L680,220L850,30'
expect(linePath.domElement.getAttribute('d')).to.equal 'M0,410L160,370L320,300L480,290L640,220L800,30'


describe 'min, max', ->
Expand Down Expand Up @@ -121,7 +121,7 @@ describe "abscissas", ->
linePath = element.childByClass('line')

expect(linePath.hasClass('line')).to.equal true
expect(linePath.domElement.getAttribute('d')).to.equal 'M-212,410L-191,370L-170,300L-149,290L-127,220L-106,30'
expect(linePath.domElement.getAttribute('d')).to.equal 'M-200,410L-180,370L-160,300L-140,290L-120,220L-100,30'

describe 'custom key', ->
beforeEach ->
Expand Down Expand Up @@ -155,4 +155,4 @@ describe "abscissas", ->
linePath = element.childByClass('line')

expect(linePath.hasClass('line')).to.equal true
expect(linePath.domElement.getAttribute('d')).to.equal 'M0,410L170,370L340,300L510,290L680,220L850,30'
expect(linePath.domElement.getAttribute('d')).to.equal 'M0,410L160,370L320,300L480,290L640,220L800,30'
6 changes: 3 additions & 3 deletions test/unit/area_series.mocha.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ describe 'area series', ->
areaPath = areaGroup.domElement.childNodes[0]
expect(areaPath.getAttribute('style').trim()).to.equal 'fill: rgb(70, 130, 180); opacity: 0.3;'
expect(areaPath.getAttribute('class')).to.equal 'area'
expect(areaPath.getAttribute('d')).to.equal 'M0,410L170,370L340,300L510,290L680,220L850,30L850,450L680,450L510,450L340,450L170,450L0,450Z'
expect(areaPath.getAttribute('d')).to.equal 'M0,410L160,370L320,300L480,290L640,220L800,30L800,450L640,450L480,450L320,450L160,450L0,450Z'

it 'should create stripes pattern when told so', ->
outerScope.$apply ->
Expand Down Expand Up @@ -92,7 +92,7 @@ describe 'area series', ->
areaPath = areaGroup.child('path')
expect(areaPath.getStyle().trim()).to.equal 'fill: url("#areaPattern_0") none; opacity: 1;'
expect(areaPath.hasClass('area')).to.equal true
expect(areaPath.getAttribute('d')).to.equal 'M0,410L170,370L340,300L510,290L680,220L850,30L850,450L680,450L510,450L340,450L170,450L0,450Z'
expect(areaPath.getAttribute('d')).to.equal 'M0,410L160,370L320,300L480,290L640,220L800,30L800,450L640,450L480,450L320,450L160,450L0,450Z'

it 'should create a line group', ->
lineGroup = element.childByClass('lineGroup series_0')
Expand All @@ -104,7 +104,7 @@ describe 'area series', ->
expect(dotsGroup.domElement.nodeName).to.equal 'g'
dots = dotsGroup.domElement.childNodes
expect(dots.length).to.equal 6
expectedX = 'X 0 170 340 510 680 850'
expectedX = 'X 0 160 320 480 640 800'
expectedY = 'Y 410 370 300 290 220 30'
computedX = Array::reduce.call(dots, (a, b) ->
a + ' ' + b.getAttribute('cx')
Expand Down
4 changes: 2 additions & 2 deletions test/unit/column_series.mocha.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ describe 'column series', ->
computedX = Array::reduce.call(columns, fn('x'), 'X')
computedY = Array::reduce.call(columns, fn('y'), 'Y')
computedH = Array::reduce.call(columns, fn('height'), 'H')
expect(computedX).to.eql 'X 121 243 364 486 607 729'
expect(computedX).to.eql 'X 114 229 343 457 571 686'
expect(computedY).to.eql 'Y 410 370 300 290 220 30'
expect(computedH).to.eql 'H 40 80 150 160 230 420'
i = 0
Expand Down Expand Up @@ -171,7 +171,7 @@ describe 'column series', ->
computedX = Array::reduce.call(columns, fn('x'), 'X')
computedY = Array::reduce.call(columns, fn('y'), 'Y')
computedH = Array::reduce.call(columns, fn('height'), 'H')
expect(computedX).to.eql 'X 121 243 364 486 607 729'
expect(computedX).to.eql 'X 114 229 343 457 571 686'
expect(computedY).to.eql 'Y 0 370 300 290 220 30'
expect(computedH).to.eql 'H 450 80 150 160 230 420'
i = 0
Expand Down
Loading

0 comments on commit a90ffd8

Please sign in to comment.