Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
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
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
d3bb3067
Commit
d3bb3067
authored
Nov 10, 2015
by
Adam Barth
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'playfair'
parents
16d7a95a
64b27be5
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
355 additions
and
0 deletions
+355
-0
README.md
packages/playfair/README.md
+5
-0
playfair.dart
packages/playfair/lib/playfair.dart
+14
-0
base.dart
packages/playfair/lib/src/base.dart
+284
-0
pubspec.yaml
packages/playfair/pubspec.yaml
+12
-0
playfair_test.dart
packages/playfair/test/playfair_test.dart
+40
-0
No files found.
packages/playfair/README.md
0 → 100644
View file @
d3bb3067
# playfair
[

](https://travis-ci.org/flutter/playfair)
[

](https://coveralls.io/r/domokit/playfair?branch=master)
A simple charting library for Sky.
packages/playfair/lib/playfair.dart
0 → 100644
View file @
d3bb3067
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library
playfair
;
import
'dart:ui'
as
ui
;
import
'dart:math'
as
math
;
import
'package:flutter/material.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/painting.dart'
;
part
'src/base.dart'
;
packages/playfair/lib/src/base.dart
0 → 100644
View file @
d3bb3067
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of
playfair
;
class
ChartData
{
const
ChartData
({
this
.
startX
,
this
.
endX
,
this
.
startY
,
this
.
endY
,
this
.
dataSet
,
this
.
numHorizontalGridlines
,
this
.
roundToPlaces
,
this
.
indicatorLine
,
this
.
indicatorText
});
final
double
startX
;
final
double
endX
;
final
double
startY
;
final
double
endY
;
final
int
numHorizontalGridlines
;
final
int
roundToPlaces
;
final
double
indicatorLine
;
final
String
indicatorText
;
final
List
<
Point
>
dataSet
;
}
// TODO(jackson): Make these configurable
const
double
kGridStrokeWidth
=
1.0
;
const
Color
kGridColor
=
const
Color
(
0xFFCCCCCC
);
const
Color
kMarkerColor
=
const
Color
(
0xFF000000
);
const
double
kMarkerStrokeWidth
=
2.0
;
const
double
kMarkerRadius
=
2.0
;
const
double
kScaleMargin
=
10.0
;
const
double
kIndicatorStrokeWidth
=
2.0
;
const
Color
kIndicatorColor
=
const
Color
(
0xFFFF4081
);
const
double
kIndicatorMargin
=
2.0
;
class
Chart
extends
StatelessComponent
{
Chart
({
Key
key
,
this
.
data
})
:
super
(
key:
key
);
final
ChartData
data
;
Widget
build
(
BuildContext
context
)
{
return
new
_ChartWrapper
(
textTheme:
Theme
.
of
(
context
).
text
,
data:
data
);
}
}
class
_ChartWrapper
extends
LeafRenderObjectWidget
{
_ChartWrapper
({
Key
key
,
this
.
textTheme
,
this
.
data
})
:
super
(
key:
key
);
final
TextTheme
textTheme
;
final
ChartData
data
;
RenderChart
createRenderObject
()
=>
new
RenderChart
(
textTheme:
textTheme
,
data:
data
);
void
updateRenderObject
(
RenderChart
renderObject
,
_ChartWrapper
oldWidget
)
{
renderObject
.
textTheme
=
textTheme
;
renderObject
.
data
=
data
;
}
}
class
RenderChart
extends
RenderConstrainedBox
{
RenderChart
({
TextTheme
textTheme
,
ChartData
data
})
:
_painter
=
new
ChartPainter
(
textTheme:
textTheme
,
data:
data
),
super
(
child:
null
,
additionalConstraints:
const
BoxConstraints
.
expand
());
final
ChartPainter
_painter
;
ChartData
get
data
=>
_painter
.
data
;
void
set
data
(
ChartData
value
)
{
assert
(
value
!=
null
);
if
(
value
==
_painter
.
data
)
return
;
_painter
.
data
=
value
;
markNeedsPaint
();
}
TextTheme
get
textTheme
=>
_painter
.
textTheme
;
void
set
textTheme
(
TextTheme
value
)
{
assert
(
value
!=
null
);
if
(
value
==
_painter
.
textTheme
)
return
;
_painter
.
textTheme
=
value
;
markNeedsPaint
();
}
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
assert
(
size
.
width
!=
null
);
assert
(
size
.
height
!=
null
);
_painter
.
paint
(
context
.
canvas
,
offset
&
size
);
super
.
paint
(
context
,
offset
);
}
}
class
Gridline
{
double
value
;
TextPainter
labelPainter
;
Point
labelPosition
;
Point
start
;
Point
end
;
}
class
Indicator
{
Point
start
;
Point
end
;
TextPainter
labelPainter
;
Point
labelPosition
;
}
class
ChartPainter
{
ChartPainter
({
TextTheme
textTheme
,
ChartData
data
})
:
_data
=
data
,
_textTheme
=
textTheme
;
ChartData
_data
;
ChartData
get
data
=>
_data
;
void
set
data
(
ChartData
value
)
{
assert
(
data
!=
null
);
if
(
_data
==
value
)
return
;
_data
=
value
;
_needsLayout
=
true
;
}
TextTheme
_textTheme
;
TextTheme
get
textTheme
=>
_textTheme
;
void
set
textTheme
(
TextTheme
value
)
{
assert
(
value
!=
null
);
if
(
_textTheme
==
value
)
return
;
_textTheme
=
value
;
_needsLayout
=
true
;
}
static
double
_roundToPlaces
(
double
value
,
int
places
)
{
int
multiplier
=
math
.
pow
(
10
,
places
);
return
(
value
*
multiplier
).
roundToDouble
()
/
multiplier
;
}
// If this is set to true we will _layout() the next time we paint()
bool
_needsLayout
=
true
;
// The last rectangle that we were drawn into. If it changes we will _layout()
Rect
_rect
;
// These are updated by _layout()
List
<
Gridline
>
_horizontalGridlines
;
List
<
Point
>
_markers
;
Indicator
_indicator
;
void
_layout
()
{
// Create the scale labels
double
yScaleWidth
=
0.0
;
_horizontalGridlines
=
new
List
<
Gridline
>();
assert
(
data
.
numHorizontalGridlines
>
1
);
double
stepSize
=
(
data
.
endY
-
data
.
startY
)
/
(
data
.
numHorizontalGridlines
-
1
);
for
(
int
i
=
0
;
i
<
data
.
numHorizontalGridlines
;
i
++)
{
Gridline
gridline
=
new
Gridline
()
..
value
=
_roundToPlaces
(
data
.
startY
+
stepSize
*
i
,
data
.
roundToPlaces
);
if
(
gridline
.
value
<
data
.
startY
||
gridline
.
value
>
data
.
endY
)
continue
;
// TODO(jackson): Align things so this doesn't ever happen
TextSpan
text
=
new
StyledTextSpan
(
_textTheme
.
body1
,
[
new
PlainTextSpan
(
"
${gridline.value}
"
)]
);
gridline
.
labelPainter
=
new
TextPainter
(
text
)
..
maxWidth
=
_rect
.
width
..
layout
();
_horizontalGridlines
.
add
(
gridline
);
yScaleWidth
=
math
.
max
(
yScaleWidth
,
gridline
.
labelPainter
.
maxIntrinsicWidth
);
}
yScaleWidth
+=
kScaleMargin
;
// Leave room for the scale on the right side
Rect
markerRect
=
new
Rect
.
fromLTWH
(
_rect
.
left
,
_rect
.
top
,
_rect
.
width
-
yScaleWidth
,
_rect
.
height
);
// Left align and vertically center the labels on the right side
for
(
Gridline
gridline
in
_horizontalGridlines
)
{
gridline
.
start
=
_convertPointToRectSpace
(
new
Point
(
data
.
startX
,
gridline
.
value
),
markerRect
);
gridline
.
end
=
_convertPointToRectSpace
(
new
Point
(
data
.
endX
,
gridline
.
value
),
markerRect
);
gridline
.
labelPosition
=
new
Point
(
gridline
.
end
.
x
+
kScaleMargin
,
gridline
.
end
.
y
-
gridline
.
labelPainter
.
size
.
height
/
2.0
);
}
// Place the markers
List
<
Point
>
dataSet
=
data
.
dataSet
;
assert
(
dataSet
!=
null
);
assert
(
dataSet
.
length
>
0
);
_markers
=
new
List
<
Point
>();
for
(
int
i
=
0
;
i
<
dataSet
.
length
;
i
++)
_markers
.
add
(
_convertPointToRectSpace
(
dataSet
[
i
],
markerRect
));
// Place the indicator line
if
(
data
.
indicatorLine
!=
null
&&
data
.
indicatorLine
>=
data
.
startY
&&
data
.
indicatorLine
<=
data
.
endY
)
{
_indicator
=
new
Indicator
()
..
start
=
_convertPointToRectSpace
(
new
Point
(
data
.
startX
,
data
.
indicatorLine
),
markerRect
)
..
end
=
_convertPointToRectSpace
(
new
Point
(
data
.
endX
,
data
.
indicatorLine
),
markerRect
);
if
(
data
.
indicatorText
!=
null
)
{
TextSpan
text
=
new
StyledTextSpan
(
_textTheme
.
body1
,
[
new
PlainTextSpan
(
"
${data.indicatorText}
"
)]
);
_indicator
.
labelPainter
=
new
TextPainter
(
text
)
..
maxWidth
=
markerRect
.
width
..
layout
();
_indicator
.
labelPosition
=
new
Point
(
((
_indicator
.
start
.
x
+
_indicator
.
end
.
x
)
/
2.0
)
-
_indicator
.
labelPainter
.
maxIntrinsicWidth
/
2.0
,
_indicator
.
start
.
y
-
_indicator
.
labelPainter
.
size
.
height
-
kIndicatorMargin
);
}
}
else
{
_indicator
=
null
;
}
// we don't need to compute layout again unless something changes
_needsLayout
=
false
;
}
Point
_convertPointToRectSpace
(
Point
point
,
Rect
rect
)
{
double
x
=
rect
.
left
+
((
point
.
x
-
data
.
startX
)
/
(
data
.
endX
-
data
.
startX
))
*
rect
.
width
;
double
y
=
rect
.
bottom
-
((
point
.
y
-
data
.
startY
)
/
(
data
.
endY
-
data
.
startY
))
*
rect
.
height
;
return
new
Point
(
x
,
y
);
}
void
_paintGrid
(
ui
.
Canvas
canvas
)
{
Paint
paint
=
new
Paint
()
..
strokeWidth
=
kGridStrokeWidth
..
color
=
kGridColor
;
for
(
Gridline
gridline
in
_horizontalGridlines
)
{
gridline
.
labelPainter
.
paint
(
canvas
,
gridline
.
labelPosition
.
toOffset
());
canvas
.
drawLine
(
gridline
.
start
,
gridline
.
end
,
paint
);
}
}
void
_paintChart
(
ui
.
Canvas
canvas
)
{
Paint
paint
=
new
Paint
()
..
strokeWidth
=
kMarkerStrokeWidth
..
color
=
kMarkerColor
;
Path
path
=
new
Path
();
path
.
moveTo
(
_markers
[
0
].
x
,
_markers
[
0
].
y
);
for
(
Point
marker
in
_markers
)
{
canvas
.
drawCircle
(
marker
,
kMarkerRadius
,
paint
);
path
.
lineTo
(
marker
.
x
,
marker
.
y
);
}
paint
.
style
=
ui
.
PaintingStyle
.
stroke
;
canvas
.
drawPath
(
path
,
paint
);
}
void
_paintIndicator
(
ui
.
Canvas
canvas
)
{
if
(
_indicator
==
null
)
return
;
Paint
paint
=
new
Paint
()
..
strokeWidth
=
kIndicatorStrokeWidth
..
color
=
kIndicatorColor
;
canvas
.
drawLine
(
_indicator
.
start
,
_indicator
.
end
,
paint
);
if
(
_indicator
.
labelPainter
!=
null
)
_indicator
.
labelPainter
.
paint
(
canvas
,
_indicator
.
labelPosition
.
toOffset
());
}
void
paint
(
ui
.
Canvas
canvas
,
Rect
rect
)
{
if
(
rect
!=
_rect
)
_needsLayout
=
true
;
_rect
=
rect
;
if
(
_needsLayout
)
_layout
();
_paintGrid
(
canvas
);
_paintChart
(
canvas
);
_paintIndicator
(
canvas
);
}
}
packages/playfair/pubspec.yaml
0 → 100644
View file @
d3bb3067
name
:
playfair
description
:
A simple charting library for Flutter
version
:
0.0.10
author
:
Flutter Authors <flutter-dev@googlegroups.com>
homepage
:
https://github.com/flutter/playfair
dependencies
:
flutter
:
"
>=0.0.3
<0.1.0"
dev_dependencies
:
sky_tools
:
any
test
:
^0.12.0
environment
:
sdk
:
'
>=1.8.0
<2.0.0'
packages/playfair/test/playfair_test.dart
0 → 100644
View file @
d3bb3067
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
library
playfair
.
test
;
import
'package:test/test.dart'
;
import
'package:playfair/playfair.dart'
;
import
'test_painting_canvas.dart'
;
void
main
(
)
{
test
(
'test_chart'
,
()
{
ChartData
data
=
new
ChartData
(
startX:
0.0
,
startY:
0.0
,
endX:
10.0
,
endY:
1.0
,
dataSet:
[
const
Point
(
0.0
,
0.0
),
const
Point
(
2.0
,
0.5
),
const
Point
(
5.0
,
0.2
),
const
Point
(
10.0
,
0.9
),
]
);
StringBuffer
buffer
=
new
StringBuffer
();
PaintingCanvas
canvas
=
new
TestPaintingCanvas
(
new
PictureRecorder
(),
const
Size
(
100.0
,
100.0
),
buffer
.
write
);
new
ChartPainter
(
data
).
paint
(
canvas
,
new
Rect
.
fromLTRB
(
0.0
,
0.0
,
100.0
,
100.0
));
// TODO(jackson): Update this to the correct value once Sky packages can test
// See https://github.com/domokit/sky_engine/issues/580
expect
(
buffer
.
toString
(),
equals
(
""
));
});
}
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