How to create custom bar chart using google charts? - javascript

I want to create bar chart using google charts
Condition to create chart is like Bar should have fixed width and padding between the bars and it should be plot at center of grid lines.
I used google chart for this .
google.charts.load("current", {packages:['corechart']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
["Element", "Density", { role: "style" } ],
["Copper", 8.94, "#b87333"],
["Silver", 10.49, "silver"],
["Gold", 19.30, "gold"],
["Platinum", 21.45, "color: #e5e4e2"]
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1,
{ calc: getValueAt.bind(undefined, 1),
sourceColumn: 1,
type: "string",
role: "annotation" },
2]);
var options = {
title: "Density of Precious Metals, in g/cm^3",
width: 600,
height: 400,
bar: {
groupWidth: 20
},
legend: { position: "none" },
};
var chart = new google.visualization.ColumnChart(document.getElementById("columnchart_values"));
chart.draw(view, options);
}
function getValueAt(column, dataTable, row) {
return dataTable.getFormattedValue(row, column);
}
JsFiddle for the same
I want to create something like this.

in order to get the bars between the gridlines,
will need to use a continuous data type for the x-axis,
timeofday will work, which takes an array of either 3 or 4 numbers,
representing hours, minutes, seconds, and optionally milliseconds, respectively
['Time', 'Value'],
[[9, 30, 0], 20],
[[10, 30, 0], 30],
...
set the data values at the half minute mark,
then use ticks at the full minute mark...
ticks: [
[9, 0, 0],
[10, 0, 0],
...
for padding between the bars, use a percentage...
bar: {
groupWidth: '95%'
},
see following working snippet...
google.charts.load('current', {
packages:['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Time', 'Value'],
[[9, 30, 0], 20],
[[10, 30, 0], 30],
[[11, 30, 0], 57],
[[12, 30, 0], 70],
[[13, 30, 0], 80],
[[14, 30, 0], 55],
[[15, 30, 0], 45],
[[16, 30, 0], 20],
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: function (dt, row) {
return dt.getFormattedValue(row, 1);
},
role: 'annotation',
type: 'string'
}]);
var options = {
annotations: {
alwaysOutside: true,
stem: {
color: '#cb4335',
length: 20,
},
},
bar: {
groupWidth: '95%'
},
colors: ['#cb4335'],
hAxis: {
format: 'ha',
gridlines: {
color: 'transparent'
},
ticks: [
[9, 0, 0],
[10, 0, 0],
[11, 0, 0],
[12, 0, 0],
[13, 0, 0],
[14, 0, 0],
[15, 0, 0],
[16, 0, 0],
],
},
height: 400,
legend: {position: 'none'},
tooltip: {trigger: 'none'},
vAxis: {
textStyle: {
color: 'transparent'
}
},
};
var chart = new google.visualization.ColumnChart(document.getElementById('columnchart_values'));
chart.draw(view, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="columnchart_values"></div>
EDIT
to expand the gridlines, use option hAxis.viewWindow.min & max
and chartArea.width can extend the chart to the edges of the chart container
see following working snippet...
google.charts.load('current', {
packages:['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([
['Time', 'Value'],
[[9, 30, 0], 20],
[[10, 30, 0], 30],
[[11, 30, 0], 57],
[[12, 30, 0], 70],
[[13, 30, 0], 80],
[[14, 30, 0], 55],
[[15, 30, 0], 45],
[[16, 30, 0], 20],
]);
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
calc: function (dt, row) {
return dt.getFormattedValue(row, 1);
},
role: 'annotation',
type: 'string'
}]);
var options = {
annotations: {
alwaysOutside: true,
stem: {
color: '#cb4335',
length: 20,
},
},
bar: {
groupWidth: '95%'
},
chartArea: {
width: '100%'
},
colors: ['#cb4335'],
hAxis: {
format: 'ha',
gridlines: {
color: 'transparent'
},
ticks: [
[9, 0, 0],
[10, 0, 0],
[11, 0, 0],
[12, 0, 0],
[13, 0, 0],
[14, 0, 0],
[15, 0, 0],
[16, 0, 0],
],
viewWindow: {
min: [6, 0, 0],
max: [20, 0, 0]
}
},
height: 400,
legend: {position: 'none'},
tooltip: {trigger: 'none'},
vAxis: {
textStyle: {
color: 'transparent'
}
},
};
var chart = new google.visualization.ColumnChart(document.getElementById('columnchart_values'));
chart.draw(view, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="columnchart_values"></div>

Related

Set specific spacing between rows and columns in Highcharts heatmaps

As you can see, the first row and the last column are separated from the rest by a larger space.
There is also a fine horizontal grey line under the first row.
How can I achieve that result ?
Fiddle
Highcharts.chart('container', {
chart: {
type: 'heatmap',
marginTop: 40,
marginBottom: 80,
marginLeft: 300,
marginRight: 170,
plotBorderWidth: 0,
},
plotOptions: {
series: {},
heatmap: {
// shared options for all heatmap series
borderColor: '#ffffff',
borderWidth: 100
}
},
title: {
text: ''
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov'],
opposite: true,
},
yAxis: {
categories: ['Human Resources 1', 'Human Resources 2', 'Human Resources 3', 'Human Resources 4', 'Human Resources'],
title: null,
labels: {
align: 'left',
x: -200
},
},
colorAxis: {
dataClasses: [{
from: -1,
to: 0,
color: '#cccccc',
name: 'N/A'
}, {
from: 0,
to: 10,
color: '#4cd093ff',
name: 'Very Low Impact'
}, {
from: 0,
to: 20,
color: '#b4e788ff',
name: 'Low Impact'
}, {
from: 20,
to: 50,
color: '#fff89dff',
name: 'Medium Impact'
}, {
from: 50,
to: 100,
color: '#ffa271ff',
name: 'High Impact'
}, {
from: 100,
color: '#f46160ff',
name: 'Very High Impact'
}]
},
legend: {
align: 'right',
layout: 'vertical',
margin: 0,
verticalAlign: 'top',
y: 25,
squareSymbol: false,
itemMarginTop: 30,
symbolRadius: 0,
symbolHeight: 40,
symbolWidth: 5,
useHTML: true,
itemStyle: {
"color": "#333333",
"cursor": "pointer",
"fontSize": "12px",
"textOverflow": "ellipsis"
}
},
tooltip: {
formatter: function() {
return '<b>In ' + this.series.xAxis.categories[this.point.x] + '</b> impact of <br><b>' +
this.point.value + '</b> for <b>' + this.series.yAxis.categories[this.point.y] + '</b>';
}
},
series: [{
name: 'Sales per employee',
// rowsize: 0.5,
borderWidth: 2,
data: [
[0, 0, 10],
[0, 1, 19],
[0, 2, 8],
[0, 3, 24],
[0, 4, 67],
[1, 0, 92],
[1, 1, 58],
[1, 2, 78],
[1, 3, 117],
[1, 4, 48],
[2, 0, 35],
[2, 1, 15],
[2, 2, 123],
[2, 3, 64],
[2, 4, 52],
[3, 0, 72],
[3, 1, 132],
[3, 2, 114],
[3, 3, 19],
[3, 4, 16],
[4, 0, 38],
[4, 1, 5],
[4, 2, 8],
[4, 3, 117],
[4, 4, 115],
[5, 0, 88],
[5, 1, 32],
[5, 2, 12],
[5, 3, 6],
[5, 4, 120],
[6, 0, 13],
[6, 1, 44],
[6, 2, 88],
[6, 3, 98],
[6, 4, 96],
[7, 0, 31],
[7, 1, 1],
[7, 2, 82],
[7, 3, 32],
[7, 4, 30],
[8, 0, 85],
[8, 1, 97],
[8, 2, 123],
[8, 3, 64],
[8, 4, 84],
[9, 0, 47],
[9, 1, 114],
[9, 2, 31],
[9, 3, 48],
[9, 4, 91]
],
dataLabels: {
enabled: false,
color: '#000000'
}
}, ]
});
#container {
min-width: 310px;
max-width: 800px;
height: 400px;
margin: 0 auto
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/heatmap.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<div id="container"></div>
You can achieve this result using xAxis.breaks, yAxis.plotLines and Highcharts.SVGRenderer to render a rectangle that covers the break on the xAxis. Check the demo and code posted below.
Code:
chart: {
events: {
render: function() {
var chart = this,
xAxis = chart.xAxis[0],
x = xAxis.toPixels(8.5),
y = chart.plotTop,
width = (xAxis.toPixels(1) - xAxis.toPixels(0.5)) * 0.6,
element;
if (chart.customElements) {
chart.customElements.forEach(function(elem) {
elem.destroy();
});
}
chart.customElements = [];
element = chart.renderer.rect(x, y, width, chart.plotHeight).attr({
fill: '#fff',
zIndex: 100
}).add();
chart.customElements.push(element);
}
}
},
xAxis: {
breaks: [{
breakSize: 0.6,
from: 8.5,
to: 9
}]
},
yAxis: {
plotLines: [{
value: 3.5,
width: 5,
color: '#fff',
zIndex: 100
}, {
value: 3.5,
width: 1,
color: '#ccc',
zIndex: 101
}]
}
Demo:
https://jsfiddle.net/BlackLabel/16e3o8jk/
API reference:
https://api.highcharts.com/highcharts/xAxis.breaks
https://api.highcharts.com/highcharts/yAxis.plotLines
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#rect

Google chart spacing for data point

I'm having trouble getting the spacing between the "Applications" and the data to be separated (chart 1). It needs a space between the colon and the int. I want it to look like chart 2.
(Since I'm new I can't post pictures of the chart)
Chart 1:
2011
Applicaitons:10 <-- no spacing
Chart 2: (from Google)
25
Cats: 42 <-- spacing
I'm setting my data point dynamically, not like the example from Google charts. Please see below:
public string GetAppFiledPatIssuedByYear(DateTime? startDate, DateTime? endDate)
{
using (var db = new PatentDashboardEntities())
{
var appFiledAndPatentIssued = db.f_sp_Get_AppPatentsFiled(startDate, endDate);
StringBuilder sb = new StringBuilder();
//open parent array
sb.Append("[");
//add new row containing column names
sb.Append("[\"Year\",\"Applications\", \"Patents\"], ");
int count = 0;
foreach (f_sp_Get_AppPatentsFiled_Result result in appFiledAndPatentIssued)
{
if (count > 0)
sb.Append(", ");
count++;
sb.Append("[");
sb.Append("\"" + result.LatestYear.ToString().Trim() + "\", ");
sb.Append(result.AppCount.ToString().Trim() + ", ");
sb.Append(result.PatentCount.ToString().Trim());
sb.Append("]");
}
// In case of data is not coming from server.
if (startDate != null && endDate != null)
{
int startYear = startDate.Value.Year;
int endYear = endDate.Value.Year;
List<int> yearRange = new List<int>();
for (int i = startYear; i <= endYear; i++)
{
yearRange.Add(i);
}
if (count == 0)
{
foreach (var year in yearRange)
{
if (count > 0)
sb.Append(", ");
count++;
sb.Append("[");
sb.Append("\" " + year + "\", ");
sb.Append("0 ,");
sb.Append("0");
sb.Append("]");
}
}
}
// Close parent array
sb.Append("]");
return sb.ToString();
}
}
***** Code in JS where it is being built ******
function getAppFiledPatentsIssuedByYear() {
retrieveData("/PatentDashboard/GetAppFiledPatIssuedByYear?Date=" + $('#dtDateRange').val() + "", drawAppFiledPatIssuedByYearChart);}
function drawAppFiledPatIssuedByYearChart(json) {
var data = google.visualization.arrayToDataTable(json);
var options = {
isStacked: false,
height: 250,
width: "100%",
fontSize: 12,
fontName: fontName,
pointSize: 10,
legend: { position: 'top' },
chartArea: {
top: 50,
left: 60,
width: "100%"
},
hAxis: {
slantedText: true,
slantedTextAngle: 45,
textStyle: {
fontsize: 11
}
},
vAxis: {
format: "0",
textStyle: {
bold: true
},
viewWindow: {
min: 0
}
},
colors: filedAndIssuedColors
};
setVAxisTicks(data, options);
var chart = new google.visualization.LineChart(document.getElementById("patIssuedDiv"));
chart.draw(data, options);
var chartName = 'YearlyApplicationsFiledAndPatentsIssued';
var chartTitle = 'Yearly Applications Filed and Patents Issued';
setUpRawDataLink(chart, chartTitle, chartName, data);
setUpExcelLink($("#yearlyAppFiledandPatentsIssuedExportExcel"), { chartName: chartName });
setUpImageLink($("#yearlyAppFiledandPatentsIssuedExportImage"), chart, chartTitle);}
It's returning as a string (from backend) and later passing the content as JSON object back to the front end in the JS file.
Link to Google Datapoint
How do I get the spacing between "Applications:10" to "Applications: 10"
just not able to re-create the issue, seems to work fine here.
see following working snippet...
could it be the fontName? (what is it?)
what else is missing from the snippet below?
filedAndIssuedColors & setVAxisTicks -- but don't see how those could cause the issue.
google.charts.load('current', {
packages:['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([["Year","Applications", "Patents"], ["1990", 1, 0], ["1991", 11, 0], ["1992", 2, 0], ["1993", 1, 0], ["1994", 19, 0], ["1997", 1, 0], ["2000", 1, 0], ["2001", 9, 0], ["2002", 11, 0], ["2003", 2, 1], ["2004", 2, 0], ["2005", 15, 0], ["2006", 2, 1], ["2007", 34, 1], ["2008", 2, 5], ["2009", 2, 5], ["2010", 27, 1], ["2011", 14, 6], ["2012", 23, 7], ["2013", 22, 14], ["2014", 15, 6], ["2015", 94, 12], ["2016", 26, 22], ["2017", 96, 33], ["2018", 22, 51]]);
var options = {
isStacked: false,
height: 250,
width: "100%",
fontSize: 12,
//fontName: fontName,
pointSize: 10,
legend: { position: 'top' },
chartArea: {
top: 50,
left: 60,
width: "100%"
},
hAxis: {
slantedText: true,
slantedTextAngle: 45,
textStyle: {
fontsize: 11
}
},
vAxis: {
format: "0",
textStyle: {
bold: true
},
viewWindow: {
min: 0
}
},
//colors: filedAndIssuedColors
};
//setVAxisTicks(data, options);
var chart = new google.visualization.LineChart(document.getElementById("chart_div"));
chart.draw(data, options);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
EDIT
we can certainly add more space using a custom tooltip,
see following working snippet...
google.charts.load('current', {
packages:['corechart']
}).then(function () {
var data = google.visualization.arrayToDataTable([["Year","Applications", "Patents"], ["1990", 1, 0], ["1991", 11, 0], ["1992", 2, 0], ["1993", 1, 0], ["1994", 19, 0], ["1997", 1, 0], ["2000", 1, 0], ["2001", 9, 0], ["2002", 11, 0], ["2003", 2, 1], ["2004", 2, 0], ["2005", 15, 0], ["2006", 2, 1], ["2007", 34, 1], ["2008", 2, 5], ["2009", 2, 5], ["2010", 27, 1], ["2011", 14, 6], ["2012", 23, 7], ["2013", 22, 14], ["2014", 15, 6], ["2015", 94, 12], ["2016", 26, 22], ["2017", 96, 33], ["2018", 22, 51]]);
var options = {
isStacked: false,
height: 250,
width: "100%",
fontSize: 12,
fontName: 'Open Sans',
pointSize: 10,
legend: { position: 'top' },
chartArea: {
top: 50,
left: 60,
width: "100%"
},
hAxis: {
slantedText: true,
slantedTextAngle: 45,
textStyle: {
fontsize: 11
}
},
vAxis: {
format: "0",
textStyle: {
bold: true
},
viewWindow: {
min: 0
}
},
tooltip: {
isHtml: true
}
};
var view = new google.visualization.DataView(data);
view.setColumns([0, 1, {
type: 'string',
role: 'tooltip',
calc: function (dt, row) {
return '<div class="tooltip"><div><span>' + dt.getValue(row, 0) + '</span></div><div>' + dt.getColumnLabel(1) + ': <span>' + dt.getValue(row, 1) + '</span></div>';
},
p: {html: true}
}, 2, {
type: 'string',
role: 'tooltip',
calc: function (dt, row) {
return '<div class="tooltip"><div><span>' + dt.getValue(row, 0) + '</span></div><div>' + dt.getColumnLabel(2) + ': <span>' + dt.getValue(row, 2) + '</span></div>';
},
p: {html: true}
}]);
console.log('test');
var chart = new google.visualization.LineChart(document.getElementById("chart_div"));
chart.draw(view.toDataTable(), options);
});
.tooltip {
font-family: 'Open Sans';
font-size: 11pt;
padding: 4px;
}
.tooltip div {
padding: 4px;
}
.tooltip span {
font-weight: bold;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Multi-colored line chart with google visualization

I'm using google line chart in my project and facing a problem that I need to change color for some segments to visualize the target status changes over time. It should look like this:
I've searched around for quite long but couldn't find a way to do that with google chart.
My workaround is to add another series to the chart and alternately set the value of the second line eq to the first line based on the status but it looks tedious.
Is there a proper way to do this? Here is a sample of my workaround solution:
function drawMultipleTrendlineChart() {
var chart;
var data = new google.visualization.DataTable();
data.addColumn('date', 'Date');
data.addColumn('number', 'Sales value A');
data.addColumn('number', 'Sales value B');
data.addRows([
[new Date(2013, 3, 11), 200, 0],
[new Date(2013, 4, 02), 500, 0],
[new Date(2013, 5, 03), 700, 0],
[new Date(2013, 6, 04), 800, 800],
[new Date(2013, 7, 05), 500, 500],
[new Date(2013, 8, 06), 900, 0],
[new Date(2014, 0, 07), 800, 0],
[new Date(2014, 1, 08), 1100, 1100],
[new Date(2014, 2, 09), 1000, 1000],
[new Date(2014, 2, 10), 1000, 0],
[new Date(2014, 3, 11), 800, 0],
]);
var formatter = new google.visualization.NumberFormat({
fractionDigits: 2,
prefix: 'R$:'
});
formatter.format(data, 1);
var dateFormatter = new google.visualization.NumberFormat({
pattern: 'MMM yyyy'
});
dateFormatter.format(data, 0);
var chartHeight = 400;
var chartWidth = 600;
var chartOptions = {
tooltip: {
isHtml: true
},
title: 'Trendlines with multiple lines',
isStacked: true,
width: chartWidth,
height: chartHeight,
colors: ['#0000D8', '#00dddd'],
hAxis: {
title: 'example title',
slantedText: false,
slantedTextAngle: 45,
textStyle: {
fontSize: 10
},
format: 'dd-MM-yyyy'
},
chartArea: {
left: 50,
top: 20,
width: (chartWidth - 10),
height: (chartHeight - 90)
}
};
chart = new google.visualization.LineChart(document.getElementById('multipleTrendChart'));
chart.draw(data, chartOptions);
}
google.load('visualization', '1', {
packages: ['corechart'],
callback: drawMultipleTrendlineChart
});
<html>
<head>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
</script>
</head>
<body>
<div id="multipleTrendChart"></div>
</body>
</html>
After looking at this answer How to change color for negative values, I tried and this works for me. The answer is using DataView API to manipulate the data.
google.charts.load('current', {
callback: drawLineColors,
packages: ['corechart']
});
function drawLineColors() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'X');
data.addColumn('number', 'Blue Team');
data.addColumn('number', 'Red Team');
data.addRows([
[0, 0, 0],
[3, 1700, 1600],
[6, 1800, 1700],
[9, 2500, 2423],
[12, 3000, 2500],
[15, 4700, 5800],
[18, 5200, 5900],
[21, 5500, 6000],
[24, 6000, 6200],
[27, 6800, 6700],
[30, 7500, 7000],
[33, 7800, 8200],
[36, 7900, 9756],
[39, 8000, 10752],
[42, 9000, 13753],
[45, 15000, 17845]
]);
var options = {
legend: {
position: 'top'
},
enableInteractivity: false,
width: 712,
height: 156,
backgroundColor: {
fill: 'transparent'
},
curveType: 'function',
hAxis: {
title: 'Time'
},
vAxis: {
title: 'Team Gold'
}
};
var dataView = new google.visualization.DataView(data);
dataView.setColumns([
// reference first column by index
0,
// variance
{
calc: function(data, row) {
return data.getValue(row, 1);
},
type: 'number',
label: 'Y'
},
// variance color
{
calc: function(data, row) {
var val = data.getValue(row, 2) - data.getValue(row, 1);
if (val >= 0) {
return '#0000FF';
}
return '#FF0000';
},
type: 'string',
role: 'style'
}
]);
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(dataView, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Flot tooltips appear on line graph but not bar chart

I have an array of [Moment, integer] pairs that I'm plotting in a graph using flot. When I plot the data as a bar chart, the tooltips do not appear.
However if I display the points, or if I convert the chart into a line graph then the tooltips appear.
As the following snippet show, I'm practically using the flot example code. What could be causing the tooltips to fail to display when plotted as a bar chart? Editable JSFiddle is available here.
var people_count_data = [
[moment("2015-05-26T09:15:00+00:00"), 0],
[moment("2015-05-26T09:30:00+00:00"), 0],
[moment("2015-05-26T09:45:00+00:00"), 0],
[moment("2015-05-26T10:00:00+00:00"), 0],
[moment("2015-05-26T10:15:00+00:00"), 0],
[moment("2015-05-26T10:30:00+00:00"), 0],
[moment("2015-05-26T10:45:00+00:00"), 0],
[moment("2015-05-26T11:00:00+00:00"), 0],
[moment("2015-05-26T11:15:00+00:00"), 0],
[moment("2015-05-26T11:30:00+00:00"), 0],
[moment("2015-05-26T11:45:00+00:00"), 2],
[moment("2015-05-26T12:00:00+00:00"), 51],
[moment("2015-05-26T12:15:00+00:00"), 59],
[moment("2015-05-26T12:30:00+00:00"), 72],
[moment("2015-05-26T12:45:00+00:00"), 23],
[moment("2015-05-26T13:00:00+00:00"), 50],
[moment("2015-05-26T13:15:00+00:00"), 55],
[moment("2015-05-26T13:30:00+00:00"), 52],
[moment("2015-05-26T13:45:00+00:00"), 53],
[moment("2015-05-26T14:00:00+00:00"), 39],
[moment("2015-05-26T14:15:00+00:00"), 50],
[moment("2015-05-26T14:30:00+00:00"), 51],
[moment("2015-05-26T14:45:00+00:00"), 55],
[moment("2015-05-26T15:00:00+00:00"), 39],
[moment("2015-05-26T15:15:00+00:00"), 12],
[moment("2015-05-26T15:30:00+00:00"), 0],
[moment("2015-05-26T15:45:00+00:00"), 0],
[moment("2015-05-26T16:00:00+00:00"), 0],
[moment("2015-05-26T16:15:00+00:00"), 0],
[moment("2015-05-26T16:30:00+00:00"), 0],
[moment("2015-05-26T16:45:00+00:00"), 0],
[moment("2015-05-26T17:00:00+00:00"), 0],
[moment("2015-05-26T17:15:00+00:00"), 0],
];
var plotOptions = {
//Options go here
xaxis: {
mode: "time",
reserveSpace: true,
tickLength: 5,
autoscaleMargin: 0.01
},
yaxis: {
min: 0
},
grid: {
hoverable: true,
clickable: true
},
series: {
// If I comment out bars and turn the chart into a line graph, tooltips work(!)
bars: {
show: true
},
// If I show the points on the bar graph, tooltips work(!)
// points: {
// show: true
// }
},
};
var plot1 = $.plot(
'#store-people-count-plot', [{
label: "People Count",
color: "#FC8200",
data: people_count_data
}], plotOptions);
function showTooltip(x, y, contents) {
$("<div id='tooltip'>" + contents + "</div>").css({
position: "absolute",
display: "none",
top: y + 5,
left: x + 5,
border: "1px solid #fdd",
padding: "2px",
"background-color": "#fee",
opacity: 0.80
}).appendTo("body").fadeIn(200);
}
var previousPoint = null;
var hoverCallback = function(event, pos, item) {
if (item) {
if (previousPoint != item.dataIndex) {
previousPoint = item.dataIndex;
var x_moment = moment(item.datapoint[0]);
$("#tooltip").remove();
var y = item.datapoint[1];
var tooltipString = x_moment.format("HH:mm") + ", " + y;
showTooltip(item.pageX, item.pageY,
tooltipString);
}
} else {
$("#tooltip").remove();
previousPoint = null;
}
};
$('#store-people-count-plot').on("plothover", hoverCallback);
#store-people-count-plot {
width: 400px;
height: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.3/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.3.1/moment-timezone.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.time.js"></script>
<div id="store-people-count-plot"></div>
Your bars are too thin. If you zoom your browser window in and hover your cursor over a bar, the tooltip is displayed. Try widening your bars using the barwidth option:
"barWidth" is the width of the bars in units of the x axis (or the y axis if "horizontal" is true), contrary to most other measures that are specified in pixels. For instance, for time series the unit is milliseconds so 24 * 60 * 60 * 1000 produces bars with the width of a day.
I've modified your options and set the barWidth to 10 minutes, and the tooltip works.
var people_count_data = [
[moment("2015-05-26T09:15:00+00:00"), 0],
[moment("2015-05-26T09:30:00+00:00"), 0],
[moment("2015-05-26T09:45:00+00:00"), 0],
[moment("2015-05-26T10:00:00+00:00"), 0],
[moment("2015-05-26T10:15:00+00:00"), 0],
[moment("2015-05-26T10:30:00+00:00"), 0],
[moment("2015-05-26T10:45:00+00:00"), 0],
[moment("2015-05-26T11:00:00+00:00"), 0],
[moment("2015-05-26T11:15:00+00:00"), 0],
[moment("2015-05-26T11:30:00+00:00"), 0],
[moment("2015-05-26T11:45:00+00:00"), 2],
[moment("2015-05-26T12:00:00+00:00"), 51],
[moment("2015-05-26T12:15:00+00:00"), 59],
[moment("2015-05-26T12:30:00+00:00"), 72],
[moment("2015-05-26T12:45:00+00:00"), 23],
[moment("2015-05-26T13:00:00+00:00"), 50],
[moment("2015-05-26T13:15:00+00:00"), 55],
[moment("2015-05-26T13:30:00+00:00"), 52],
[moment("2015-05-26T13:45:00+00:00"), 53],
[moment("2015-05-26T14:00:00+00:00"), 39],
[moment("2015-05-26T14:15:00+00:00"), 50],
[moment("2015-05-26T14:30:00+00:00"), 51],
[moment("2015-05-26T14:45:00+00:00"), 55],
[moment("2015-05-26T15:00:00+00:00"), 39],
[moment("2015-05-26T15:15:00+00:00"), 12],
[moment("2015-05-26T15:30:00+00:00"), 0],
[moment("2015-05-26T15:45:00+00:00"), 0],
[moment("2015-05-26T16:00:00+00:00"), 0],
[moment("2015-05-26T16:15:00+00:00"), 0],
[moment("2015-05-26T16:30:00+00:00"), 0],
[moment("2015-05-26T16:45:00+00:00"), 0],
[moment("2015-05-26T17:00:00+00:00"), 0],
[moment("2015-05-26T17:15:00+00:00"), 0],
];
var plotOptions = {
//Options go here
xaxis: {
mode: "time",
reserveSpace: true,
tickLength: 5,
autoscaleMargin: 0.01
},
yaxis: {
min: 0
},
grid: {
hoverable: true,
clickable: true
},
series: {
// If I comment out bars and turn the chart into a line graph, tooltips work(!)
bars: {
show: true,
barWidth: 60*10*1000
},
// If I show the points on the bar graph, tooltips work(!)
// points: {
// show: true
// }
},
};
var plot1 = $.plot(
'#store-people-count-plot', [{
label: "People Count",
color: "#FC8200",
data: people_count_data
}], plotOptions);
function showTooltip(x, y, contents) {
$("<div id='tooltip'>" + contents + "</div>").css({
position: "absolute",
display: "none",
top: y + 5,
left: x + 5,
border: "1px solid #fdd",
padding: "2px",
"background-color": "#fee",
opacity: 0.80
}).appendTo("body").fadeIn(200);
}
var previousPoint = null;
var hoverCallback = function(event, pos, item) {
if (item) {
if (previousPoint != item.dataIndex) {
previousPoint = item.dataIndex;
var x_moment = moment(item.datapoint[0]);
$("#tooltip").remove();
var y = item.datapoint[1];
var tooltipString = x_moment.format("HH:mm") + ", " + y;
showTooltip(item.pageX, item.pageY,
tooltipString);
}
} else {
$("#tooltip").remove();
previousPoint = null;
}
};
$('#store-people-count-plot').on("plothover", hoverCallback);
#store-people-count-plot {
width: 400px;
height: 300px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.3/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.3.1/moment-timezone.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.time.js"></script>
<div id="store-people-count-plot"></div>

How can I use Flot to make a multiseries line graph with curved lines?

I'm trying to use Flot to make a line graph with multiple series, then smoothing the lines out using the CurvedLines plugin.
I can get my multiple series line chart using flot alone to get jagged lines. I can also use the CurvedLines plugin to make a single smooth line chart. But for some reason, I'm unable to make my multiple series line graph smooth.
Here is a link to the graph I'm working on: www.somanifamily.com/multiple/
I am positive that there is nothing wrong with my CSS or the external JS files.
Here is the (slightly abridged) Javascript from my page:
$(function() {
var datasets = {
"oak": {
label: "Oak (Querus)",
data: [[10, 30], [20, 0], [30, 23], [40, 54], [50, 45], [60, 2], [70, 0], [80, 0], [90, 0], [100, 0], [110, 0], [120, 0]]
},
"elm": {
label: "Elm (Ulmus)",
data: [[10, 0], [20, 0], [30, 0], [40, 45], [50, 23], [60, 0], [70, 0], [80, 0], [90, 0], [100, 0], [110, 0], [120, 0]]
},
"weeds": {
label: "Total Weeds",
data: [[10, 0], [20, 0], [30, 0], [40, 45], [50, 23], [60, 0], [70, 0], [80, 0], [90, 0], [100, 0], [110, 0], [120, 0]]
},
"grass": {
label: "Total Grass",
data: [[10, 0], [20, 0], [30, 0], [40, 45], [50, 23], [60, 0], [70, 0], [80, 0], [90, 0], [100, 0], [110, 0], [120, 0]]
}
};
// hard-code color indices to prevent them from shifting as
// pollens are turned on/off
var i = 0;
$.each(datasets, function(key, val) {
val.color = i;
++i;
});
// insert checkboxes
var choiceContainer = $("#choices");
$.each(datasets, function(key, val) {
var check = "checked='checked'";
if (key != "oak") check = "";
choiceContainer.append("<br/><input type='checkbox' name='" + key +
"' " + check + "id='id" + key + "'></input>" +
"<label for='id" + key + "'>"
+ val.label + "</label>");
})
choiceContainer.find("input").click(plotAccordingToChoices);
function plotAccordingToChoices() {
var d1 = [];
choiceContainer.find("input:checked").each(function () {
var key = $(this).attr("name");
if (key && datasets[key]) {
d1.push(datasets[key]);
}
});
if (d1.length > 0) {
// set options
var options = {
series: {
curvedLines: {
active: true
}
},
yaxis: {
min: 0
},
xaxis: {
tickDecimals: 0,
ticks: [[10,'Jan.'],[20,'Feb.'],[30,'March'],[40,'April'],[50,'May'],[60,'June'],
[70,'July'],[80,'Aug.'],[90,'Sep.'],[100,'Oct.'],[110,'Nov.'],[120,'Dec.']]
}
};
// plot
$.plot("#placeholder", [{data: d1, lines: { show: true }, curvedLines: {apply:true, fit: true, fitPointDist: 0.000001}}], options);
}
}
plotAccordingToChoices();
});
I'm suspecting that the error is with the line
$.plot("#placeholder", [{data: d1, lines: { show: true }, curvedLines: {apply:true, fit: true, fitPointDist: 0.000001}}], options);
How do I get the graph to plot the multiple series smoothly (and display the legend along with it)? Thanks in advance.
Your suspicion is correct. In that line, you are treating d1 as an individual series, when it is in fact an array of series. In your case, since you seem to want the same curvedLines parameters applied to all the series, you can just add them in the options (you already have active: true, you need to add the rest):
var options = {
series: {
curvedLines: {
active: true
apply: true,
fit: true,
fitPointDist: 0.000001
}
},
etc...
If you wanted different parameters for each series, you could add them there instead.
var datasets = {
"oak": {
label: "Oak (Querus)",
data: [[10, 30], [20, 0], [30, 23], [90, 0], [100, 0], [110, 0], [120, 0]]
curvedLines: {
apply: true,
fit: true,
fitPointDist: 0.000001
}
},
etc...
Then the plot line is just:
$.plot("#placeholder", d1, options);

Categories

Resources