Related
(Highcharts version 6)
Is it possible to have a time line looking chart in addition to data points like in this example:
https://jsfiddle.net/s1eL30Lh/97/
<script src="https://code.highcharts.com/stock/highstock.js"></script>
but without using highstock and instead only use highcharts ?
I know it's possible to use xrange module but it's not quite the same:
https://jsfiddle.net/deep3015/q18yvy75/
If the ranges are long enough to simulate a line then you lack the ability to add "data points" on top of the line, and if you make the ranges small enough to look like data points then you don't have a line.
NOTE
I'm aware of the new chart type 'timeline' in version 7 but I need to work with version 6.1
Yes, it is possible. However, you can't use flags series because it is only supported by Highstock. Check the demo and code posted below.
Code:
function toMs(yeah, month) {
return Date.UTC(yeah, month, 1);
}
var series = [{
// First series
name: 'Running',
color: 'green',
id: 'green',
dataRaw: [{
y: 1,
xRanges: [
// first value: from; second value: to
[toMs(2000, 1), toMs(2002, 8)],
[toMs(2006, 10), toMs(2006, 11)]
]
}]
}, {
// Second series
name: 'Filed',
color: 'yellow',
id: 'yellow',
dataRaw: [{
y: 1,
xRanges: [
// first value: from; second value: to
[toMs(2002, 8), toMs(2006, 10)]
]
}]
},
{
// Second series
name: 'Granted',
color: 'blue',
id: 'blue',
dataRaw: [{
y: 1,
xRanges: [
// first value: from; second value: to
[toMs(2006, 11), toMs(2021, 8)]
]
}]
}
].map(function(series) {
series.data = [];
series.dataRaw.forEach(function(dataRaw) {
dataRaw.xRanges.forEach(function(xRange) {
series.data.push([xRange[0], dataRaw.y], [xRange[1], dataRaw.y], [xRange[1], null]); // null breakes the line
}); // forEach
}); // forEach
return series;
});
console.log(series);
var chart = Highcharts.chart('container', {
chart: {
type: 'scatter'
},
title: {
text: 'Example'
},
plotOptions: {
scatter: {
lineWidth: 5,
marker: {
enabled: true,
symbol: 'circle',
fillColor: '#FFFFFF',
lineWidth: 2,
lineColor: null,
radius: 5
},
dataLabels: {
enabled: true,
align: 'right',
rotation: -30,
x: -2,
y: 15,
formatter: function() {
return Highcharts.dateFormat('%Y-%m', this.x);
}
},
tooltip: {
pointFormatter: function() {
return Highcharts.dateFormat('%Y-%m', this.x);
}
}
},
flags: {
lineWidth: 1
}
},
xAxis: {
title: {
text: 'Time'
},
type: 'datetime',
minTickInterval: 365 * 24 * 36e5,
labels: {
align: 'left'
},
plotBands: [{
from: Date.UTC(2000, 10, 27),
to: Date.UTC(2004, 11, 1),
color: '#EFFFFF',
label: {
text: 'Office 1',
style: {
color: '#999999'
},
y: 30
}
}, {
from: Date.UTC(2004, 11, 1),
to: Date.UTC(2012, 9, 1),
color: '#FFFFEF',
label: {
text: 'Office 2',
style: {
color: '#999999'
},
y: 30
}
}, {
from: Date.UTC(2012, 9, 1),
to: Date.UTC(2020, 10, 27),
color: '#FFEFFF',
label: {
text: 'Office 3',
style: {
color: '#999999'
},
y: 30
}
}]
},
yAxis: {
tickInterval: 1
},
series: series,
annotations: [{
labelOptions: {
backgroundColor: 'rgba(255,255,255,0.5)'
},
labels: [{
distance: 10,
point: {
xAxis: 0,
yAxis: 0,
x: toMs(2002, 8),
y: 1
},
text: 'Filled Date'
}]
}]
});
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/6.1/highcharts.js"></script>
<script src="https://code.highcharts.com/6.1/modules/annotations.js"></script>
<div id="container" style="height: 400px"></div>
Demo:
https://jsfiddle.net/BlackLabel/6eahoxjv/
I want to create a dumbbell chart using highcharts.
I used x-range chart for this
here is the link: https://jsfiddle.net/thushara07/nLkxa0wr/15/
series: [{
// name: 'Project 3',
// pointPadding: 0,
// groupPadding: 0,
//borderColor: 'gray',
pointWidth: 5,
data: [{
x: 32,
x2: 33,
y: 0,
// partialFill: 0.25
}, {
x: 44,
x2:45,
y: 1
}, {
x:30,
x2: 32,
y: 2
}],
dataLabels: {
align: 'left',
enabled: true
}
}]
expected output: I want to show markers for each line created as shown
(https://images.app.goo.gl/LAKQBdsaKBH2hjS59
)
It can be done by adding additional scatter series that is linked to x-range:
Code:
Highcharts.chart('container', {
yAxis: {
title: {
text: ''
},
categories: ['Prototyping', 'Development', 'Testing'],
reversed: true
},
series: [{
type: 'xrange',
pointWidth: 5,
id: 'main',
data: [{
x: 32,
x2: 33,
y: 0
}, {
x: 44,
x2: 45,
y: 1
}, {
x: 30,
x2: 32,
y: 2
}],
dataLabels: {
align: 'center',
enabled: true
}
}, {
type: 'scatter',
linkedTo: 'main',
marker: {
radius: 5
},
data: [{
x: 32,
y: 0,
color: 'red'
}, {
x: 33,
y: 0,
color: 'grey'
}, {
x: 44,
y: 1,
color: 'red'
}, {
x: 45,
y: 1,
color: 'grey'
}, {
x: 30,
y: 2,
color: 'red'
}, {
x: 32,
y: 2,
color: 'grey'
}]
}]
});
Demo:
https://jsfiddle.net/BlackLabel/4qj89cog/
API reference:
https://api.highcharts.com/highcharts/series.scatter
https://api.highcharts.com/highcharts/series.scatter.linkedTo
I am making a simple bar graph using echarts js with symbols on x Axis. I am also trying to do datascroll for the xAxis, but when I am scrolling the symbol positions are not changing with the scroll. I go through the API doc of echarts but found nothing.
I am trying this JsFiddle
var advertLineChart = document.getElementById('advertLineChart');
var myAdvertLineChart = echarts.init(advertLineChart);
createAdvertLineChart();
function createAdvertLineChart() {
var option = {
title: {
x: 'center',
text: 'ECharts例子个数统计',
subtext: 'Rainbow bar example',
link: 'http://echarts.baidu.com/doc/example.html'
},
tooltip: {
trigger: 'item'
},
toolbox: {
show: true,
orient: 'vertical',
y: 'center',
itemSize: 12,
feature: {
mark: {
show: true,
title: {
mark: 'Create line mark',
markUndo: 'Undo line mark',
markClear: 'Clear all line Marks'
},
lineStyle: {
width: 2,
color: '#1e90ff',
type: 'dashed'
}
},
dataZoom: {
show: true,
title: {
dataZoom: 'Data Zoom',
dataZoomReset: 'Data zoom reset'
}
},
dataView: {
show: true,
title: 'Show Data',
readOnly: false,
lang: ['Data View', 'Close', 'Refresh']
},
magicType: {
show: true,
type: ['line', 'bar'],
title: {
line: 'Line View',
bar: 'Bar View'
}
},
restore: {
show: true,
title: 'Restore'
},
saveAsImage: {
show: true,
title: 'Save as Image',
lang: ['Click Save']
}
}
},
dataZoom: {
show: true,
realtime: true,
showDetail: true,
//orient: 'vertical', // 'horizontal'
//x: 0,
y: 36,
//width: 400,
height: 20,
//backgroundColor: 'rgba(221,160,221,0.5)',
//dataBackgroundColor: 'rgba(138,43,226,0.5)',
//fillerColor: 'rgba(38,143,26,0.6)',
//handleColor: 'rgba(128,43,16,0.8)',
//xAxisIndex:[],
//yAxisIndex:[],
start: 40,
end: 70,
zoomLock: true
},
calculable: true,
grid: {
borderWidth: 0,
y: 80,
y2: 60
},
xAxis: [{
type: 'category',
show: false,
data: ['Line', 'Bar', 'Scatter', 'K', 'Pie', 'Radar', 'Chord', 'Force', 'Map', 'Gauge', 'Funnel', 'Line1', 'Bar1', 'Scatter1', 'K1', 'Pie1', 'Radar1', 'Chord1', 'Force1', 'Map1', 'Gauge1', 'Funnel1', 'Funnel2', 'Line2', ]
}],
yAxis: [{
type: 'value',
show: false
}],
series: [{
name: 'ECharts例子个数统计',
type: 'bar',
itemStyle: {
normal: {
label: {
show: true,
position: 'top',
formatter: '{b}\n{c}'
}
}
},
data: [12, 21, 10, 4, 12, 5, 6, 5, 25, 23, 7, 12, 21, 10, 4, 12, 5, 6, 5, 25, 23, 7, 20, 100],
markPoint: {
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(0,0,0,0)',
formatter: function(params) {
return '<img src="' + params.data.symbol.replace('image://', '') + '"/>';
}
},
data: [{
xAxis: 0,
y: 320,
name: 'Line',
symbolSize: 16,
symbol: 'http://localhost:8080/api/advert/image/21af6834-2b44-4217-9516-3b2add06114c.png'
}, {
xAxis: 1,
y: 320,
name: 'Bar',
symbolSize: 16,
symbol: 'http://localhost:8080/api/advert/image/5268c2b2-0b1f-4373-b235-7f71b6bb4290.png'
}, {
xAxis: 2,
y: 320,
name: 'Scatter',
symbolSize: 16,
symbol: 'http://localhost:8080/api/advert/image/69a7df86-0bf6-4cea-a6b6-881a4052ec20.png'
}, {
xAxis: 3,
y: 320,
name: 'K',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/de874b8f-f8df-4905-9650-8efa8f19c015.png'
}, {
xAxis: 4,
y: 320,
name: 'Pie',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/b83f4915-8587-4df5-bde6-308ec0f472b3.png'
}, {
xAxis: 5,
y: 320,
name: 'Radar',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/db739705-c9e3-47bd-a3de-7e757ce0c434.png'
}, {
xAxis: 6,
y: 320,
name: 'Chord',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/131201d2-9154-4391-89e7-73d83c12d33c.png'
}, {
xAxis: 7,
y: 320,
name: 'Force',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/158dd833-a788-4e83-a7fd-ba42addaae31.png'
}, {
xAxis: 8,
y: 320,
name: 'Map',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/b6933882-f367-419e-8f6e-df65ae74a859.png '
}, {
xAxis: 9,
y: 320,
name: 'Gauge',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/bae5221a-02e7-407a-8fa3-36bb8456dafa.png'
}, {
xAxis: 10,
y: 320,
name: 'Funnel',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/03dc461c-20fc-49b7-8ef4-59649995fcb8.png'
}, {
xAxis: 11,
y: 320,
name: 'Line1',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/03dc461c-20fc-49b7-8ef4-59649995fcb8.png'
}, {
xAxis: 12,
y: 320,
name: 'Bar1',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/03dc461c-20fc-49b7-8ef4-59649995fcb8.png'
}, {
xAxis: 13,
y: 320,
name: 'Scatter1',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/03dc461c-20fc-49b7-8ef4-59649995fcb8.png'
}, {
xAxis: 14,
y: 320,
name: 'K1',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/03dc461c-20fc-49b7-8ef4-59649995fcb8.png'
}, {
xAxis: 15,
y: 320,
name: 'Pie1',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/03dc461c-20fc-49b7-8ef4-59649995fcb8.png'
}, {
xAxis: 16,
y: 320,
name: 'Radar1',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/03dc461c-20fc-49b7-8ef4-59649995fcb8.png'
}, {
xAxis: 17,
y: 320,
name: 'Chord1',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/03dc461c-20fc-49b7-8ef4-59649995fcb8.png'
}, {
xAxis: 18,
y: 320,
name: 'Force1',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/03dc461c-20fc-49b7-8ef4-59649995fcb8.png'
}, {
xAxis: 19,
y: 320,
name: 'Map1',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/03dc461c-20fc-49b7-8ef4-59649995fcb8.png'
}, {
xAxis: 20,
y: 320,
name: 'Gauge1',
symbolSize: 16,
symbol: 'http://neoma-server.appspot.com/api/advert/image/03dc461c-20fc-49b7-8ef4-59649995fcb8.png'
}, {
xAxis: 21,
y: 320,
name: 'Funnel1',
symbolSize: 16,
symbol: 'http://localhost:8080/api/advert/image/69a7df86-0bf6-4cea-a6b6-881a4052ec20.png'
}, {
xAxis: 22,
y: 320,
name: 'Funnel2',
symbolSize: 16,
symbol: 'http://localhost:8080/api/advert/image/5268c2b2-0b1f-4373-b235-7f71b6bb4290.png'
}, {
xAxis: 23,
y: 320,
name: 'Line2',
symbolSize: 16,
symbol: 'http://localhost:8080/api/advert/image/21af6834-2b44-4217-9516-3b2add06114c.png'
}, ]
}
}]
};
myAdvertLineChart.setOption(option);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/2.2.7/echarts-all.js"></script>
<div id="advertLineChart" style="width: 100%; height: 350px;"></div>
How to scroll the images correctly when scrolling the slider? Thanks in advance.
Thanks to this helpful post, I was able to re-format the legend so that clicking a legend item shows only that item, rather than hiding it and showing all other items.
Once the user clicks on a legend item, I'd like for the user to be able to click a button and once again see all of the legend items.
Here's the fiddle: http://jsfiddle.net/scheltense/qb13g51u/1/
And the code:
$(function () {
$('#container').highcharts({
credits: {
position: {
align: 'right',
x: -10,
y: -1
},
text: 'Source: Federal Emergency Management Agency',
href: 'http://www.FEMA.gov'
},
chart: {
type: 'area'
},
title: {
text: 'Federal Disaster Declarations: 2001-2013',
align: 'left',
x: 25,
y: 5
},
subtitle: {
text: 'The Federal Emergency Management Agency (FEMA) uses these categories to classify federal disasters delcarations.',
align: 'left',
x: 25,
y: 30
},
legend: {
backgroundColor: '#F5F3F2',
layout: 'vertical',
symbolHeight: 8,
symbolWidth: 10,
align: 'left',
verticalAlign: 'top',
floating: true,
x: 62,
y: 72,
padding: 3,
itemMarginTop: 3,
itemMarginBottom: 3,
itemStyle: {
lineHeight: '8px',
color: '#000000',
fontWeight: 'normal'
},
reversed: true
},
xAxis: {
categories: ['2001', '\'02', '\'03', '\'04', '\'05', '\'06', '\'07', '\'08', '\'09', '\'10', '\'11', '\'12', '\'13', '\'14*'],
tickmarkPlacement: 'on',
title: {
enabled: true
}
},
yAxis: {
title: {
text: 'Declarations'
},
max: 100,
labels: {
formatter: function () {
return this.value;
}
}
},
tooltip: {
shared: false,
valueSuffix: ''
},
plotOptions: {
area: {
events:
{
legendItemClick: function(event)
{
var seriesIndex = this.index;
var series = this.chart.series;
for (var i = 0; i < series.length; i++)
{
if (series[i].index != seriesIndex)
{
series[i].hide();
}
else
{
series[i].show();
}
}
return false;
}
},
stacking: 'normal',
lineColor: '#E5E2E0',
lineWidth: 0,
marker: {
enabled: false
}
}
},
series: [{
name: 'Other',
color: '#9fcad3',
data: [6, 5, 2, 3, 0, 4, 1, 1, 1, 1, 8, 4, 6, 0],
marker: {
symbol: 'circle'
}
}, {
name: 'Hurricane',
color: '#bb6b85',
data: [0, 4, 8, 14, 11, 0, 0, 8, 1, 1, 14, 15, 2, 0],
marker: {
symbol: 'circle'
}
}, {
name: 'Severe Winter Weather',
color: '#bba16b',
data: [4, 5, 6, 1, 2, 1, 5, 5, 5, 12, 5, 0, 3, 11],
marker: {
symbol: 'circle'
}
}, {
name: 'Flood',
color: '#6b85bb',
data: [5, 4, 0, 1, 2, 2, 1, 3, 3, 7, 19, 3, 15, 2],
marker: {
symbol: 'circle'
}
}, {
name: 'Severe Storm and Tornado',
color: '#6bbba1',
data: [27, 25, 35, 42, 30, 45, 56, 56, 48, 55, 50, 25, 36, 15],
marker: {
symbol: 'circle'
}
}]
}, function (chart) {
var point = chart.series[0].data[8],
text = chart.renderer.text(
'*through Aug. 5, 2014',
point.plotX + chart.plotLeft - 280,
point.plotY + chart.plotTop + 316
).attr({
zIndex: 5
})
.css({
color: '#909090',
fontSize: '10px'
})
.add(),
box = text.getBBox();
});
});
This is the portion of the code that shows only the legend item that has been clicked:
plotOptions: {
area: {
events:
{
legendItemClick: function(event)
{
var seriesIndex = this.index;
var series = this.chart.series;
for (var i = 0; i < series.length; i++)
{
if (series[i].index != seriesIndex)
{
series[i].hide();
}
else
{
series[i].show();
}
}
return false;
}
},
This is my first JavaScript project, so I apologize if the question is unclear, and I appreciate any help that can be provided.
Thanks very much.
The series object has a show() function (http://api.highcharts.com/highcharts#Series.show).
Assuming your button has an id of showall:
$('#showall').on('click', function() {
var series = $('#container').highcharts().series;
for(i=0;i<series.length;i++) {
if (!series[i].visible) series[i].show();
}
});
http://jsfiddle.net/qb13g51u/2/
I am trying to customize highcharts
1) I need to change the height of the plotlines
2) Show the marker value inside the marker image itself at a specific place(Inside the white circles at the top)
This is what I have achieved so far
Highcharts.setOptions({
global: {
useUTC: false
}
});
/*function updateData(x,y)
{
var series = chart.series[0];
series.addPoint([x, y], true, true);
}*/
var chart;
$(function () {
var color = '#AA34FF';
$('#container').highcharts({
chart: {
events: {
load: function(event) {
_bindCustomEvents();
}
},
backgroundColor: 'transparent'
},
series: [
{
color:
{
linearGradient:
{
x1: 0,
y1: 0,
x2: 0,
y2: 1
},
stops:
[
/*[0, '#a83e3e'],
[0.21, '#d34e47'],
[0.40, '#edbb5a'],
[0.57, '#e2e57a'],
[0.76, '#8dcc63'],
[1, '#7ab237']*/
[0, '#7ab237'],
[0.21, '#8dcc63'],
[0.40, '#e2e57a'],
[0.57, '#edbb5a'],
[0.76, '#d34e47'],
[1, '#a83e3e']
]
},
lineWidth: 4,
marker: {
enabled: false,
fillColor: '#FFFFFF',
lineWidth: 2,
lineColor: null,
},
type: 'spline',
data: [1, 2, 5, 3, 6, 7, 4],
backgroundColor: 'transparent',
plotShadow : false
},
{
name: '',
marker: {
symbol: 'diamond'
},
//same inmage for all points
marker: {
symbol: 'url(http://fc08.deviantart.net/fs71/f/2014/016/b/9/top_marker_by_skyrbe-d72ewk0.png)'
},
data: [8,8,8,8,8,8,8],
type:'scatter'
},
{
name: '',
marker: {
symbol: 'diamond'
},
//same inmage for all points
marker: {
symbol: 'url(http://fc03.deviantart.net/fs71/f/2014/016/f/a/bottom_marker_by_skyrbe-d72ew7w.png)'
},
data: [-1,-1,-1,-1,-1,-1,-1],
type:'scatter'
}
],
xAxis: {
categories: [
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat'
],
title: {
enabled: true,
text: null,
},
labels: {
style: {
fontFamily: 'gestaregular',
fontSize: '16px',
color:'#fff'
}
},
plotLines: [
{ // mark the weekend
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 0,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 1,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 2,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 3,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 4,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 5,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 6,
dashStyle: 'dash',
zIndex:10
}],
lineWidth: 0,
minorGridLineWidth: 0,
lineColor: 'transparent',
},
yAxis: {
labels: {
enabled: false
},
title: {
enabled: true,
text: null,
}
},
legend: {
enabled: false
},
minorTickLength: 0,
tickLength: 0
});
});
function _bindCustomEvents()
{
var chart = $('#container').highcharts();
chart.setTitle({ text: ''});
$('.highcharts-axis').hide();
$('.highcharts-grid').hide();
$('.highcharts-axis').find('path').hide();
}
FIDDLE LINK
This is how I want it to look like : Instead of '2' in the top circles , it should be the corresponding value from the center spline [1, 2, 5, 3, 6, 7, 4]
1) The plotLines are infinite. The extend as far as the plot area is. So, to limit this, how about you change your yAxis max:
yAxis: {
max: 8,
labels: {
enabled: false
},
title: {
enabled: true,
text: null
}
},
Or, you could create a column series on the points you want and give them a certain value for the height you want. Making the columns thin to mimic your plotLines will help like so:
series: [{
name: '',
type: 'column',
pointWidth: 1,
borderWidth: 0,
data: [8, 8, 8, 8, 8, 8, 8]
},
...
2) Which values in the circles (I am guessing)? The "Series 1: XX"? Or the whole tooltip?
EDIT:
For question 2 you can do this with a formatter function on the dataLabel for the scatter series (your circles). Here is the function:
var customFormatPoint = function (pointX, seriesIndex) {
var theChart = $('#container').highcharts();
var yValue = null;
var points = theChart.series[seriesIndex].options.data[pointX];
return points;
};
You call this from:
series: [{
name: '',
type: 'column',
pointWidth: 1,
borderWidth: 0,
dataLabels: {
enabled: true,
formatter: function () {
return customFormatPoint(this.point.x, 1);
}
},
data: [7.70, 7.70, 7.70, 7.70, 7.70, 7.70, 7.70]
}, {...
Key element here is that you have this.point.x which is that scatter point's xAxis location. You then need to send in which index the series is that contains the y value you want to show in the dataLabel.
I have also removed the plotLines and created a series that just contains the bars with width of 1 and no border. I had to mess around to get the end of the bar (its max value) to coincide with the scatter circle diameter.
Please see this jsFiddle.