I'd like to get this Google LineChart to look a little more like this chart from GitHub. I'm recreating GitHub's chart because I want a version of it in high quality (vector) and not a highly compressed JPEG (who in their right mind saves charts as JPEGs anyway!).
I'd like to move the legend into the graph and add vertical gridlines (on the horizontal axis "Year"). Does anyone know how to accomplish this?
Here's the code, but please feel free to edit my JSFiddle:
google.load('visualization', '1', {packages: ['corechart', 'line']});
google.setOnLoadCallback(function() {
var data = google.visualization.arrayToDataTable([
['Year', 'JavaScript', 'Java', 'Ruby', 'PHP', 'Python', 'CSS', 'C++', 'Objective C', 'C', 'C#', 'Perl', 'Emacs Lisp', 'VimL', 'Shell','HTML'],
['2008', 2, 7, 1, 4, 3, null, 8, 9, 5, null, 6, null, null, null, null],
['2009', 2, 7, 1, 4, 3, null, 8, 9, 6, null, 5, 10, null, null, null],
['2010', 2, 5, 1, 4, 3, null, 8, 9, 6, null, 7, null, 10, null, null],
['2011', 2, 5, 1, 4, 3, null, 7, 8, 6, 10, 9, null, null, null, null],
['2012', 2, 3, 1, 4, 5, null, 7, 8, 6, 9, null, null, null, 10, null],
['2013', 1, 3, 2, 4, 5, 10, 7, 8, 6, 9, null, null, null, null, null],
['2014', 1, 2, 3, 4, 5, 6, 7, 9, 8, 10, null, null, null, null, null],
['2015', 1, 2, 3, 4, 5, 6, 7, null, 9, 8, null, null, null, null, 10]
]);
var options = {
title: 'Rank of top languages on GitHub over time',
width: '100%',
height: 600,
hAxis: {
title: 'Time',
},
vAxis: {
title: 'Rank',
viewWindow: {
min: 1
},
direction: -1,
gridlines: {
count: 11
}
}
};
var chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(data, options);
});
Change data type -> type: 'date'
google.load('visualization', '1.1', {packages: ['corechart', 'line']});
google.setOnLoadCallback(function() {
var data = google.visualization.arrayToDataTable([
[{label: 'Year', type: 'date'}, 'JavaScript', 'Java', 'Ruby', 'PHP', 'Python', 'CSS', 'C++', 'Objective C', 'C', 'C#', 'Perl', 'Emacs Lisp', 'VimL', 'Shell','HTML'],
[new Date(2008, 0, 0), 2, 7, 1, 4, 3, null, 8, 9, 5, null, 6, null, null, null, null],
[new Date(2009, 0, 0), 2, 7, 1, 4, 3, null, 8, 9, 6, null, 5, 10, null, null, null],
[new Date(2010, 0, 0), 2, 5, 1, 4, 3, null, 8, 9, 6, null, 7, null, 10, null, null],
[new Date(2011, 0, 0), 2, 5, 1, 4, 3, null, 7, 8, 6, 10, 9, null, null, null, null],
[new Date(2012, 0, 0), 2, 3, 1, 4, 5, null, 7, 8, 6, 9, null, null, null, 10, null],
[new Date(2013, 0, 0), 1, 3, 2, 4, 5, 10, 7, 8, 6, 9, null, null, null, null, null],
[new Date(2014, 0, 0), 1, 2, 3, 4, 5, 6, 7, 9, 8, 10, null, null, null, null, null],
[new Date(2015, 0, 0), 1, 2, 3, 4, 5, 6, 7, null, 9, 8, null, null, null, null, 10]
]);
var options = {
title: 'Rank of top languages on GitHub over time',
width: '100%',
height: 800,
hAxis: {
title: 'Time',
gridlines: {
count: -1
},
},
vAxis: {
title: 'Rank',
viewWindow: {
min: 1
},
direction: -1,
gridlines: {
count: -1
}
}
};
var chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(data, options);
});
https://jsfiddle.net/mblenton/x00omtxL/15/
Related
So I am trying to create a function that will list all the stats of a specific player in below object. I am simply trying to return the nested object associated with the playerName itself. I'm guessing map isn't working for me here. Instead I am returning an array of the individual letters of the name "Jeff Adrien". Can someone help me understand where I am going wrong?
//Code in question
function playerStats(playerName) {
let specificPlayer = allPlayers().players
if (playerName === specificPlayer) {
return specificPlayer
}
const stats = Object.values(playerName).map((nums) => {
return [nums]
})
return stats.flat()
}
console.log(playerStats('Jeff Adrien'))
// details
function allPlayers() {
const everyPlayer = Object.assign(homePlayers, awayPlayers)
return everyPlayer
}
const gameObject = () => {
return {
home: {
teamName: 'Brooklyn Nets',
colors: ['black', 'white'],
players: {
'Alan Anderson': {
number: 0,
shoe: 16,
points: 22,
rebounds: 12,
assists: 12,
steals: 3,
blocks: 1,
slamDunks: 1,
},
'Reggie Evans': {
number: 30,
shoe: 14,
points: 12,
rebounds: 12,
assists: 12,
steals: 12,
blocks: 12,
slamDunks: 7,
},
'Brook Lopez': {
number: 11,
shoe: 17,
points: 17,
rebounds: 19,
assists: 10,
steals: 3,
blocks: 1,
slamDunks: 15,
},
'Mason Plumlee': {
number: 1,
shoe: 19,
points: 26,
rebounds: 12,
assists: 6,
steals: 3,
blocks: 8,
slamDunks: 5,
},
'Jason Terry': {
number: 31,
shoe: 15,
points: 19,
rebounds: 2,
assists: 2,
steals: 4,
blocks: 11,
slamDunks: 1,
},
},
},
away: {
teamName: 'Charlotte Hornets',
colors: ['turquoise', 'purple'],
players: {
'Jeff Adrien': {
number: 4,
shoe: 18,
points: 10,
rebounds: 1,
assists: 1,
steals: 2,
blocks: 7,
slamDunks: 2,
},
'Bismak Biyombo': {
number: 0,
shoe: 16,
points: 12,
rebounds: 4,
assists: 7,
steals: 7,
blocks: 15,
slamDunks: 10,
},
'DeSagna Diop': {
number: 4,
shoe: 14,
points: 24,
rebounds: 12,
assists: 12,
steals: 4,
blocks: 5,
slamDunks: 5,
},
'Ben Gordon': {
number: 8,
shoe: 15,
points: 33,
rebounds: 3,
assists: 2,
steals: 1,
blocks: 1,
slamDunks: 0,
},
'Brendan Haywood': {
number: 33,
shoe: 15,
points: 6,
rebounds: 12,
assists: 12,
steals: 22,
blocks: 5,
slamDunks: 12,
},
},
},
}
}
wow I was trying to work with an array and turn it into an object somehow.. it just clicked for me
function playerStats(playerName) {
for (const player in allPlayers()) {
if (player === playerName) {
return allPlayers()[player]
}
}
}
This is my data and I'd like to calculate total sales.
let order = [
{ id: 'A441', sales: [10, 12, 13, 10, 16, 22, 30] },
{ id: 'B234', sales: [2, 4, 3, 4, 2, 6, 8, 10] },
{ id: 'A617', sales: [5, 5, 5, 5, 5] },
{ id: 'C229', sales: [9, 7, 6, 8, 8, 10, 9, 3, 4, 5, 6] },
{ id: 'D412', sales: [25, 25, 23, 21] },
{ id: 'A054', sales: [2, 2, 3, 1, 5, 6, 7, 11, 2] },
{ id: 'B955', sales: [1, 1, 1, 1, 1, 1] },
{ id: 'M341', sales: [4, 5, 4, 5, 4] },
{ id: 'H103', sales: [3, 2, 2, 3, 1, 1] },
{ id: 'B199', sales: [6, 5, 4] },
{ id: 'D388', sales: [7, 8, 9, 8, 4, 4, 4, 3, 2, 1] }
];
If you want the total by sale type:
let orders = [
{ id: 'A441', sales: [10, 12, 13, 10, 16, 22, 30] },
{ id: 'B234', sales: [2, 4, 3, 4, 2, 6, 8, 10] },
{ id: 'A617', sales: [5, 5, 5, 5, 5] },
{ id: 'C229', sales: [9, 7, 6, 8, 8, 10, 9, 3, 4, 5, 6] },
{ id: 'D412', sales: [25, 25, 23, 21] },
{ id: 'A054', sales: [2, 2, 3, 1, 5, 6, 7, 11, 2] },
{ id: 'B955', sales: [1, 1, 1, 1, 1, 1] },
{ id: 'M341', sales: [4, 5, 4, 5, 4] },
{ id: 'H103', sales: [3, 2, 2, 3, 1, 1] },
{ id: 'B199', sales: [6, 5, 4] },
{ id: 'D388', sales: [7, 8, 9, 8, 4, 4, 4, 3, 2, 1] }
];
function getTotalSales(orders){
return orders.map(order=> ({...order, totalSales: order.sales.reduce((acc, cur)=> acc+=cur, 0)}))
}
console.log(getTotalSales(orders))
If you want the total of all sales:
let orders = [
{ id: 'A441', sales: [10, 12, 13, 10, 16, 22, 30] },
{ id: 'B234', sales: [2, 4, 3, 4, 2, 6, 8, 10] },
{ id: 'A617', sales: [5, 5, 5, 5, 5] },
{ id: 'C229', sales: [9, 7, 6, 8, 8, 10, 9, 3, 4, 5, 6] },
{ id: 'D412', sales: [25, 25, 23, 21] },
{ id: 'A054', sales: [2, 2, 3, 1, 5, 6, 7, 11, 2] },
{ id: 'B955', sales: [1, 1, 1, 1, 1, 1] },
{ id: 'M341', sales: [4, 5, 4, 5, 4] },
{ id: 'H103', sales: [3, 2, 2, 3, 1, 1] },
{ id: 'B199', sales: [6, 5, 4] },
{ id: 'D388', sales: [7, 8, 9, 8, 4, 4, 4, 3, 2, 1] }
];
function getTotalSales(orders){
return orders.map(({sales})=> sales).flat().reduce((acc, cur)=> acc+=cur, 0)
}
console.log(getTotalSales(orders))
I am trying to manually set the length of a category axis. In detail I want the length of the x axis equal to the length of the y axis. So far I tried diverse layout settings from plotly manual without results.
var layout = {
width: 400,
height: 300,
plot_bgcolor: '#98ff6d',
};
var data = [{
z: [
[1, 20, 10, 12, 1, 1, 20, 10, 12, 1],
[24, 1, 12, 19, 0, 1, 20, 10, 12, 1],
[8, 1, 4, 12, 16, 1, 20, 20, 12, 0],
[1, 20, 10, 12, 1, 13, 20, 0, 12, 21],
[24, 1, 12, 19, 0, 1, 20, 10, 12, 1],
[8, 1, 4, 12, 16, 1, 20, 10, 1, 12],
[1, 20, 10, 12, 1, 1, 20, 10, 12, 14],
[24, 1, 12, 19, 0, 1, 20, 10, 12, 1],
[8, 13, 4, 12, 16, 1, 21, 20, 0, 18],
[1, 20, 0, 12, 1, 21, 65, 10, 12, 1],
[24, 1, 12, 19, 0, 1, 20, 10, 12, 1],
[8, 1, 4, 12, 16, 1, 20, 10, 15, 0],
[1, 20, 10, 12, 1, 1, 30, 10, 12, 14],
[24, 13, 12, 19, 0, 1, 20, 10, 12, 1],
[8, 1, 4, 12, 16, 1, 29, 1, 19, 31],
[1, 20, 10, 12, 1, 31, 0, 10, 12, 19],
[24, 1, 12, 19, 0, 1, 20, 10, 12, 1],
[8, 1, 4, 12, 16, 1, 20, 10, 11, 21],
[1, 0, 10, 12, 1, 1, 10, 10, 12, 21],
[24, 1, 0, 19, 0, 1, 20, 10, 12, 1],
[8, 1, 4, 12, 16, 1, 20, 1, 19, 36],
[1, 20, 10, 12, 1, 21, 21, 10, 12, 31],
[24, 1, 12, 19, 0, 1, 20, 10, 12, 1],
[8, 12, 4, 12, 16, 1, 21, 43, 12, 18],
[1, 20, 10, 12, 1, 1, 39, 10, 12, 13],
[24, 1, 12, 19, 0, 1, 20, 12, 2, 1],
[8, 1, 4, 12, 16, 1, 20, 10, 1, 11],
[1, 20, 10, 12, 1, 19, 38, 10, 12, 16],
[24, 12, 12, 19, 0, 1, 20, 10, 12, 1],
[8, 1, 4, 12, 16, 1, 29, 4, 12, 3],
[1, 20, 0, 12, 1, 1, 23, 10, 12, 11],
[24, 1, 12, 19, 0, 1, 20, 10, 12, 1],
[8, 19, 4, 12, 16, 1, 20, 10, 12, 19],
[1, 20, 10, 12, 1, 1, 24, 10, 12, 0],
[24, 1, 12, 19, 023, 1, 22, 10, 12, 1],
[8, 1, 41, 12, 16, 1, 20, 10, 12, 11]
],
x: ['T1', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7', 'T8', 'T9', 'T10'],
y: ['Messung 1', 'Messung 2', 'Messung 3',
'Messung 4', 'Messung 5', 'Messung 6',
'Messung 7', 'Messung 8', 'Messung 9',
'Messung 10', 'Messung 11', 'Messung 12',
'Messung 13', 'Messung 14', 'Messung 15',
'Messung 16', 'Messung 17', 'Messung 18',
'Messung 19', 'Messung 20', 'Messung 21',
'Messung 22', 'Messung 23', 'Messung 24',
'Messung 25', 'Messung 26', 'Messung 27',
'Messung 28', 'Messung 29', 'Messung 30',
'Messung 31', 'Messung 32', 'Messung 33',
'Messung 34', 'Messung 35', 'Messung 36'
],
type: 'surface'
}];
Plotly.newPlot('plot', data, layout, {
displayModeBar: true,
displaylogo: false
});
#plot {
height: 100vh, width:100vw;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified plotly.js JavaScript -->
<script type="text/javascript" src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="plot"></div>
Give your layout Object a scene, and set your desired range on its axis, yaxis, and (if you like) zaxis properties. E.g.
var MIN_VAL = -100, MAX_VAL = 100;
var layout = {
scene:{
axis: {
nticks: 10,
range: [ MIN_VAL, MAX_VAL ]
},
yaxis: {
nticks: 10,
range: [ MIN_VAL, MAX_VAL ]
},
zaxis: {
nticks: 7,
range: [ MIN_VAL, MAX_VAL ]
},
aspectmode: "manual",
aspectratio: { x: 1, y: 1, z: 0.7 },
bgcolor : '#98ff6d'
},
autosize: false,
width: 400,
height: 300,
margin: { l: 0, r: 0, b: 50, t: 50, pad: 4 }
};
Plotly.newPlot('plot', data, layout);
Plotly has a working example (that shows the use of even more layout options) on CodePen.
How to make use of flot.js to create a attendance chart with it? something similar to the image linked.attendance chart
The date axis shows perfectly. the problem lies in the time axis! how do I format the time, to pass it to the flot?
function gd(year, month, day) {
return new Date(year, month - 1, day).getTime();
}
function gt(year, month, day, hour, minute){
return new Date(year, month - 1, day, hour, minute).getTime();
}
function init_attendace_chart(){
if( typeof ($.plot) === 'undefined'){ return; }
console.log('attendance plotting');
var attendance_data = [
[gd(2017, 3, 1), gt(2017, 3, 1, 8, 45)], [gd(2017, 3, 2), gt(2017, 3, 1, 7, 48)], [gd(2017, 3, 3), gt(2017, 3, 1, 7, 50)],
[gd(2017, 3, 4), gt(2017, 3, 1, 7, 45)], [gd(2017, 3, 5), gt(2017, 3, 1, 7, 55)], [gd(2017, 3, 6), gt(2017, 3, 1, 7, 45)],
[gd(2017, 3, 7), gt(2017, 3, 1, 7, 45)], [gd(2017, 3, 8), gt(2017, 3, 1, 7, 45)], [gd(2017, 3, 9), gt(2017, 3, 1, 7, 45)]
];
var attendance_chart_settings = {
series: {
curvedLines: {
apply: true,
active: true,
monotonicFit: true
},
shadowSize: 5
},
xaxes: [{ //Edit this
mode: "time",
tickSize: [1, "day"]
}],
yaxes:[{
mode:"time",
tickSize: [1, "hour"]
}],
colors: ["#26B99A"],
lines: { show: true },
grid: {
borderWidth: {
top: 0,
right: 0,
bottom: 1,
left: 1,
hoverable: true
},
borderColor: {
bottom: "#7F8790",
left: "#7F8790"
}
}
};
if ($("#attendance_chart").length){
$.plot($("#attendance_chart"), [{
label: " Your Clock-In Times",
data: attendance_data,
lines: {
fillColor: "rgba(150, 202, 89, 0.12)"
},
points: {
fillColor: "#fff"
}
}], attendance_chart_settings);
// $.plot($("#attendance_chart"), dataset, options);
$("#attendance_chart").UseTooltip();
}
}
I have a chart (image bellow), where the green line has a reference to the year 2014, and the purple line will be 2013.
var data1 = [
[gd(2014, 1, 1), 4], [gd(2014, 2, 1), 8], [gd(2014, 3, 1), 4], [gd(2014, 4, 1), 10],
[gd(2014, 5, 1), 4], [gd(2014, 6, 1), 16], [gd(2014, 7, 1), 5]];
var data2 = [
[gd(2014, 1, 1), 1], [gd(2014, 2, 1), 0], [gd(2014, 3, 1), 2], [gd(2014, 4, 1), 0],
[gd(2014, 5, 1), 1], [gd(2014, 6, 1), 3], [gd(2014, 7, 1), 1], [gd(2014, 8, 1), 5],
[gd(2014, 9, 1), 2], [gd(2014, 10, 1), 3], [gd(2014, 11, 1), 2], [gd(2014, 12, 1), 1]];
This is the dataset, but look that I put both dataset in 2014 year because if I put 2014 in one dataset and 2013 in another, I miss the overlap effect and I need that effect for comparsion.
This is what happens if a put the 2013 year in one dataset and 2014 in another (image below)
How can I do the same chart, but with this overlap effect, using the 2013 year in one dataset?
This also will fix my hover functionallity.
Code
var data1 = [
[gd(2014, 1, 1), 4], [gd(2014, 2, 1), 8], [gd(2014, 3, 1), 4], [gd(2014, 4, 1), 10],
[gd(2014, 5, 1), 4], [gd(2014, 6, 1), 16], [gd(2014, 7, 1), 5]];
var data2 = [
[gd(2014, 1, 1), 1], [gd(2014, 2, 1), 0], [gd(2014, 3, 1), 2], [gd(2014, 4, 1), 0],
[gd(2014, 5, 1), 1], [gd(2014, 6, 1), 3], [gd(2014, 7, 1), 1], [gd(2014, 8, 1), 5],
[gd(2014, 9, 1), 2], [gd(2014, 10, 1), 3], [gd(2014, 11, 1), 2], [gd(2014, 12, 1), 1]];
$("#flot-dashboard-chart").length && $.plot($("#flot-dashboard-chart"), [
data1, data2
],
{
series: {
lines: {
show: false,
fill: true
},
splines: {
show: true,
tension: 0.4,
lineWidth: 1,
fill: 0.4
},
points: {
radius: 2,
show: true
},
shadowSize: 2
},
grid: {
hoverable: true,
clickable: true,
tickColor: "#d5d5d5",
borderWidth: 1,
color: '#d5d5d5'
},
colors: ["#1ab394", "#464f88"],
xaxis: {
mode: "time",
tickSize: [1, "month"],
tickLength: null,
axisLabel: "Date",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 12,
axisLabelFontFamily: 'Arial',
axisLabelPadding: 10,
color: "#838383",
timeformat: "%b/%y"
},
yaxis: {
ticks: 4
}
}
);
function gd(year, month, day) {
return new Date(year, month - 1, day).getTime();
}
You use the concept of multiple axes, but just hide the second axis.
To do this you create two data sets, each with their own axis:
var data2014 = {
label: "2014",
data: data1,
xaxis: 1
};
var data2013 = {
label: "2013",
data: data2,
xaxis: 2
};
and then in the axes option setting, set ticks to false to hide one axis.
The max setting for the 2014 data is important, otherwise the data set will scale to fill the whole graph:
xaxes: [{
mode: "time",
tickSize: [1, "month"],
tickLength: null,
color: "#838383",
timeformat: "%b",
max: (new Date("2014/12/1")).getTime()
},{
ticks: false
}],
JS Fiddle here.
Full code below:
var data1 = [
[gd(2014, 1, 1), 4], [gd(2014, 2, 1), 8], [gd(2014, 3, 1), 4], [gd(2014, 4, 1), 10],
[gd(2014, 5, 1), 4], [gd(2014, 6, 1), 16], [gd(2014, 7, 1), 5]];
var data2 = [
[gd(2013, 1, 1), 1], [gd(2013, 2, 1), 0], [gd(2013, 3, 1), 2], [gd(2013, 4, 1), 0],
[gd(2013, 5, 1), 1], [gd(2013, 6, 1), 3], [gd(2013, 7, 1), 1], [gd(2013, 8, 1), 5],
[gd(2013, 9, 1), 2], [gd(2013, 10, 1), 3], [gd(2013, 11, 1), 2], [gd(2013, 12, 1), 1]];
var data2014 = {
label: "2014",
data: data1,
xaxis: 1
};
var data2013 = {
label: "2013",
data: data2,
xaxis: 2
};
$("#flot-dashboard-chart").length && $.plot($("#flot-dashboard-chart"), [
data2014, data2013
],
{
series: {
lines: {
show: false,
fill: true
},
splines: {
show: true,
tension: 0.4,
lineWidth: 1,
fill: 0.4
},
points: {
radius: 2,
show: true
},
shadowSize: 2
},
grid: {
hoverable: true,
clickable: true,
tickColor: "#d5d5d5",
borderWidth: 1,
labelMargin: 17,
margin: {
top: 8,
bottom: 10,
left: 20
},
minBorderMargin: 25,
color: '#d5d5d5'
},
colors: ["#1ab394", "#464f88"],
xaxes: [{
mode: "time",
tickSize: [1, "month"],
color: "#838383",
timeformat: "%b",
max: (new Date("2014/12/1")).getTime()
},{
ticks: false,
}],
yaxis: {
ticks: 5
},
legend: {
backgroundOpacity: 0.5,
noColumns: 0,
position: "ne",
color: "#838383",
}
}
);
function gd(year, month, day) {
return new Date(year, month - 1, day).getTime();
}