window.onload = function() {
var chart = new CanvasJS.Chart("chartContainer", {
zoomEnabled: false,
animationEnabled: true,
title: {
text: "Mobile Phone Subscriptions"
},
axisY2: {
valueFormatString: "0.0 bn",
maximum: 1.2,
interval: .2,
interlacedColor: "#F5F5F5",
gridColor: "#D7D7D7",
tickColor: "#D7D7D7"
},
theme: "theme2",
toolTip: {
shared: true
},
legend: {
verticalAlign: "bottom",
horizontalAlign: "center",
fontSize: 15,
fontFamily: "Lucida Sans Unicode"
},
data: [{
type: "line",
lineThickness: 3,
axisYType: "secondary",
showInLegend: true,
name: "India",
dataPoints: [{
x: new Date(2001, 0),
y: 0
}, {
x: new Date(2002, 0),
y: 0.001
}, {
x: new Date(2003, 0),
y: 0.01
}, {
x: new Date(2004, 0),
y: 0.05
}, {
x: new Date(2005, 0),
y: 0.1
}, {
x: new Date(2006, 0),
y: 0.15
}, {
x: new Date(2007, 0),
y: 0.22
}, {
x: new Date(2008, 0),
y: 0.38
}, {
x: new Date(2009, 0),
y: 0.56
}, {
x: new Date(2010, 0),
y: 0.77
}, {
x: new Date(2011, 0),
y: 0.91
}, {
x: new Date(2012, 0),
y: 0.94
}
]
}, {
type: "line",
lineThickness: 3,
showInLegend: true,
name: "China",
axisYType: "secondary",
dataPoints: [{
x: new Date(2001, 00),
y: 0.18
}, {
x: new Date(2002, 00),
y: 0.2
}, {
x: new Date(2003, 0),
y: 0.25
}, {
x: new Date(2004, 0),
y: 0.35
}, {
x: new Date(2005, 0),
y: 0.42
}, {
x: new Date(2006, 0),
y: 0.5
}, {
x: new Date(2007, 0),
y: 0.58
}, {
x: new Date(2008, 0),
y: 0.67
}, {
x: new Date(2009, 0),
y: 0.78
}, {
x: new Date(2010, 0),
y: 0.88
}, {
x: new Date(2011, 0),
y: 0.98
}, {
x: new Date(2012, 0),
y: 1.04
}
]
}, {
type: "line",
lineThickness: 3,
showInLegend: true,
name: "USA",
axisYType: "secondary",
dataPoints: [{
x: new Date(2001, 00),
y: 0.16
}, {
x: new Date(2002, 0),
y: 0.17
}, {
x: new Date(2003, 0),
y: 0.18
}, {
x: new Date(2004, 0),
y: 0.19
}, {
x: new Date(2005, 0),
y: 0.20
}, {
x: new Date(2006, 0),
y: 0.23
}, {
x: new Date(2007, 0),
y: 0.261
}, {
x: new Date(2008, 0),
y: 0.289
}, {
x: new Date(2009, 0),
y: 0.3
}, {
x: new Date(2010, 0),
y: 0.31
}, {
x: new Date(2011, 0),
y: 0.32
}, {
x: new Date(2012, 0),
y: 0.33
}
]
}
],
legend: {
cursor: "pointer",
itemclick: function(e) {
if (typeof(e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
chart.render();
}
}
});
chart.render();
}
#control_panel_container {
text-align: center;
}
.cp_content_container {
padding-top: 12px;
text-align: left;
color: #373737;
}
.cp_content_container > div {
display: none;
}
input.control_panel_tabs {
display: none;
}
label.control_panel_tabs {
font-family: Verdana, Tahoma, sans-serif;
font-weight: 600;
background-color: #C0B9C7;
color: white;
display: inline-block;
padding: 15px 25px;
text-align: center;
border: 2px solid black;
border-radius: 15px;
}
label.control_panel_tabs:hover {
background-color: #AA95B9;
color: #fff;
cursor: pointer;
}
input:checked + label.control_panel_tabs {
background: #9471AB;
color: #fff;
}
#cp_tab1:checked ~ .cp_content_container #cp_content1,
#cp_tab2:checked ~ .cp_content_container #cp_content2 {
display: block;
}
<script src="http://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="control_panel_container">
<input class="control_panel_tabs" id="cp_tab1" type="radio" name="cp_tabs" checked>
<label class="control_panel_tabs" for="cp_tab1">tab 1</label>
<input class="control_panel_tabs" id="cp_tab2" type="radio" name="cp_tabs">
<label class="control_panel_tabs" for="cp_tab2">tab 2</label>
<div class="cp_content_container">
<div id="cp_content1"></div>
<div id="cp_content2">
<div id="chartContainer" style="height: 300px; width: 100%;"></div>
</div>
</div>
</div>
I have a chart in a tab that's by default hidden. When a user clicks on that tab, they appear. However, they're skewed a bit, smooshed horizontally and stretched vertically. See the Fiddle for what I mean, it's under "tab 2".
Changing the browser's zoom level (in Firefox at least) seems to make it correct itself.
I noticed if I put it inside tab 1, however, on page load it displays correctly. It's only when it's not the default tab does it warp around and requires zoom change to display correctly.
What's going on here? It looks like the graph is only rendered when I open the tab (judging by the animation). I was thinking maybe it's because of the display property in CSS but maybe it's because it needs to be rendered at page load?
Here's an editable fiddle:
http://jsfiddle.net/ryfy8j9s/1/
The problem is that the chart's default width is set to 500, and even though you are calling chart.render() in window.onload, since its container is not visible it creates the chart at the default width and it's stuck there until chart.render() is called again (e.g., for a window resize). This isn't the only issue. For example, if you resize the window to fix the chart, but then click back on tab1, resize the window again, and click back to tab2, once again the chart is the wrong size.
You could set an explicit width when the chart is created, but that would make the chart non-responsive to resize, which probably isn't what you want.
I would suggest a click handler on tab2 to check for this exact situation and call chart.render() only if the chart is visible and not the same size as its container:
window.onload = function () {
$("#cp_tab2").on("click", function() {
if ($("#chartContainer").is(":visible") && $("#chartContainer canvas").width() !== $("#chartContainer").width()) {
chart.render();
}
});
var chart = new CanvasJS.Chart("chartContainer", {
zoomEnabled: false,
// etc.
I tried this on your fiddle and it fixes the issue. See my fork of your jsFiddle. with this working.
Possible solution is to call resize method on window just after the load of graph , i managed to correct it like that
$(window).resize();
Related
I'm trying to make a choropleth map, but how can I set the size of the map?
Now I've this map:
I would like expand the map to all the space, I read the documentations but I didn't find a solution.
This is my code:
var data = [{
type: 'choropleth',
locationmode: 'country names',
locations: unpack(output, 'label'),
z: unpack(output, 'nres'),
text: unpack(output, 'nres')
}];
var layout = {
geo: {
projection: {
type: 'equirectangular'
}
}
};
Plotly.plot(mapChoropleth, data, layout, {
showLink: false
});
Plotly tries to take all the available space without changing the image ratio. If you have a very wide div there will be a lot of empty space to left and right due but it will be filled from the top to the bottom.
You could change height and width in layout, change the margins and fine tune the color bar to get the desired result.
Plotly.d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/2014_world_gdp_with_codes.csv', function(err, rows) {
function unpack(rows, key) {
return rows.map(function(row) {
return row[key];
});
}
var data = [{
type: 'choropleth',
locations: unpack(rows, 'CODE'),
z: unpack(rows, 'GDP (BILLIONS)'),
text: unpack(rows, 'COUNTRY'),
colorscale: [
[0, 'rgb(5, 10, 172)'],
[0.35, 'rgb(40, 60, 190)'],
[0.5, 'rgb(70, 100, 245)'],
[0.6, 'rgb(90, 120, 245)'],
[0.7, 'rgb(106, 137, 247)'],
[1, 'rgb(220, 220, 220)']
],
autocolorscale: false,
reversescale: true,
marker: {
line: {
color: 'rgb(180,180,180)',
width: 0.5
}
},
tick0: 0,
zmin: 0,
dtick: 1000,
colorbar: {
autotic: false,
tickprefix: '$',
len: 0.8,
x: 1,
y: 0.6
}
}];
var layout = {
width: 300,
height: 300,
geo: {
showframe: false,
showcoastlines: false,
scope: 'europe',
projection: {
type: 'mercator',
},
},
margin: {
l: 0,
r: 0,
b: 0,
t: 0,
pad: 2
}
};
Plotly.plot(myDiv, data, layout, {
showLink: false
});
});
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myDiv"></div>
You can also change the ratio of the map directly, an ugly but working possibility.
var c = document.getElementsByClassName('countries')[0];
c.setAttribute('transform', 'translate(-300), scale(3, 1)');
c = document.getElementsByClassName('choropleth')[0];
c.setAttribute('transform', 'translate(-300), scale(3, 1)');
c = document.getElementsByClassName('clips')[0].firstChild.firstChild;
c.setAttribute('x', -300);
c.setAttribute('width', 900);
The map is first drawn normally and then resized when clicked on.
var myPlot = document.getElementById('myDiv');
var data = [];
var layout = {};
Plotly.d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/2014_world_gdp_with_codes.csv', function(err, rows) {
function unpack(rows, key) {
return rows.map(function(row) {
return row[key];
});
}
data = [{
type: 'choropleth',
locations: unpack(rows, 'CODE'),
z: unpack(rows, 'GDP (BILLIONS)'),
text: unpack(rows, 'COUNTRY'),
colorscale: [
[0, 'rgb(5, 10, 172)'],
[0.35, 'rgb(40, 60, 190)'],
[0.5, 'rgb(70, 100, 245)'],
[0.6, 'rgb(90, 120, 245)'],
[0.7, 'rgb(106, 137, 247)'],
[1, 'rgb(220, 220, 220)']
],
autocolorscale: false,
reversescale: true,
marker: {
line: {
color: 'rgb(180,180,180)',
width: 0.5
}
},
tick0: 0,
zmin: 0,
dtick: 1000,
colorbar: {
autotic: false,
tickprefix: '$',
len: 0.8,
x: 1,
y: 0.6
}
}];
layout = {
width: 1200,
height: 400,
geo: {
showframe: false,
showcoastlines: false,
scope: 'europe',
projection: {
type: 'mercator',
scale: 1
},
},
margin: {
l: 0,
r: 0,
b: 0,
t: 0,
pad: 2
}
};
Plotly.plot(myPlot, data, layout, {
showLink: false
});
myPlot.on('plotly_click', function(){
var c = document.getElementsByClassName('countries')[0];
c.setAttribute('transform', 'translate(-300), scale(3, 1)');
c = document.getElementsByClassName('choropleth')[0];
c.setAttribute('transform', 'translate(-300), scale(3, 1)');
c = document.getElementsByClassName('clips')[0].firstChild.firstChild;
c.setAttribute('x', -300);
c.setAttribute('width', 900);
})
});
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myDiv" style="x: 0"></div>
I have a 3d scatterplot of which i want to change its zoom level and pan around it programmatically. I have tried setting the range in the layout from the beggining but it does not change the actual zoom level, just the points in the range:
"layout":
{
margin: {
l: 0,
r: 0,
b: 0,
t: 0,
pad: 1
},
scene:{
xaxis: {range:[-13,13.5]},
yaxis: {range:[-15.5,13.5]},
zaxis: {range:[-14.5,13.5]},
}
},
Also i've tried invoking it with the relayout function, but it is also not working
var update = {
scene:{
xaxis: {range:[-13,13.5]},
yaxis: {range:[-15.5,13.5]},
zaxis: {range:[-14.5,13.5]},
},
};
Plotly.relayout(gd, update);
Finally i found the property to change the camera position:
var update = {
scene:{
camera: {
center: { x: 0, y: 0, z: 0 },
eye: { x: 2, y: 2, z: 0.1 },
up: { x: 0, y: 0, z: 1 }
}
},
};
Plotly.relayout(gd, update);
I'm trying to add text to awe.js project, using this tutorial I have came up with an attempt, https://www.sitepoint.com/augmented-reality-in-the-browser-with-awe-js/.
awe.projections.add({
id: 'text',
geometry: {shape: 'text', text: 'Hello World', font: 'times new roman', weight: 'normal', style: 'normal'},
rotation: {y: 45},
position: {x: -5, y: -31, z: -5},
material: {
type: 'phong',
color: 0xFF0000
}
}, {poi_id: 'marker'});
Then I have done some more research on the subject and tried in different way yet still not succeeded.
awe.pois.add({ id:'fixed_poi', position: { x:70, y:0, z:-250 }, visible: true });
awe.projections.add({
id:'fixed_projection',
geometry: { shape: 'text', text: "My Text", parameters:{font: 'optimer', size: 50}},
position: { x:0, y:0, z:0 },
rotation: { x:0, y:0, z:0 },
material:{ type: 'phong', color: 0xFFFFFF },
}, { poi_id: 'fixed_poi' });
You could create text model separately (an .obj 3D model) for example in 3D builder in Windows 10, and then add that to awe.js in following way:
awe.pois.add({ id:'jsartoolkit_marker_64', position: { x:0, y:0, z:0 }, scale: { x: 1, y: 1, z: 1 } });
awe.projections.add({
id:'marker_projection',
geometry: { path: 'models/obj/example.obj' }, // path to your model
position: { x: 0, y: 0, z: 0 },
rotation: { x: 0, y: 180, z: 0 },
material:{ path: 'models/obj/example.mtl' }, // path to material if you're using one
visible: false,
}, { poi_id: 'jsartoolkit_marker_64' }); // common point of interest, in this case the marker
Hope this helps
So I'm using the Rickshaw graphing library and I was wondering how to dynamically add points to a graph.
I have a graph instantiated like this:
#seriesData = [ [], [], [] ]
random = new Rickshaw.Fixtures.RandomData(150)
for (var i = 0; i < 50; i++) {
random.addData(self.seriesData)
}
#graph = new Rickshaw.Graph(
element: document.getElementById("chart")
width: 550
height: 300
renderer: 'area'
series: [
{
color: "#c05020"
data: self.seriesData[0]
name: 'One'
}, {
color: "#30c020"
data: self.seriesData[1]
name: 'Two'
}, {
color: "#2791d7"
data: self.seriesData[2]
name: 'Three'
}
]
)
#graph.render()
hoverDetail = new Rickshaw.Graph.HoverDetail(
graph: self.graph
)
legend = new Rickshaw.Graph.Legend(
graph: self.graph
element: document.getElementById('legend')
)
shelving = new Rickshaw.Graph.Behavior.Series.Toggle(
graph: self.graph
legend: legend
)
axes = new Rickshaw.Graph.Axis.Time(
graph: self.graph
)
axes.render()
And I have data coming in through socket.io like this:
app.on('data',
(one, two, three) =>
// Dynamically add data points to graph
)
And I was wondering how to append these three points to the graph. I can't find any good documentation for this library. I know it's built on top of d3.js, but I'm not sure how to incorporate these methods into my graph.
Any help would be appreciated.
I envision two scenario that could solve your question:
Using the fixed Window Series for Streaming Data
leveraging the fact that arrays in javascript are passed by reference. A demo is available here
.
var data = [
{
data: [ { x: 0, y: 120 }, { x: 1, y: 890 }, { x: 2, y: 38 }, { x: 3, y: 70 }, { x: 4, y: 32 } ],
color: "#c05020"
}, {
data: [ { x: 0, y: 80 }, { x: 1, y: 200 }, { x: 2, y: 100 }, { x: 3, y: 520 }, { x: 4, y: 133 } ],
color: "#30c020"
}
];
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
renderer: 'line',
height: 300,
width: 800,
series: data
} );
var y_ticks = new Rickshaw.Graph.Axis.Y( {
graph: graph,
orientation: 'left',
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
element: document.getElementById('y_axis'),
} );
graph.render();
$('button#add').click(function() {
data.push({
data: [ { x: 0, y: 200 }, { x: 1, y: 390 }, { x: 2, y: 1000 }, { x: 3, y: 200 }, { x: 4, y: 230 } ],
color: "#6060c0"
});
graph.update();
});
I am charting different data with RickshawJS. But I need a way to update the chart when a user clicks the #search button. Right now it just creates a new chart below the old one, and that is pretty messy.
The user enters the page and enters some details and clicks the button to chart it. So ideally I'd like to start with an empty chart that isn't shown, but I can't really figure out how to remove the data from the chart and axes and then update it.
I could call $('#chart svg').remove(); on the chart and axes but it seems messy.
$('#search').click(function(event){
event.preventDefault();
var data = utils.malletData();
var graph = new Rickshaw.Graph( {
element: document.querySelector("#chart"),
width: 800,
height: 250,
series: [ {
name: data['name'],
color: 'steelblue',
data: data['series']
} ]
} );
graph.render();
var hoverDetail = new Rickshaw.Graph.HoverDetail( {
graph: graph,
xFormatter: function(x) {
var date = new Date(x).getTime();
return moment(x).format('MMMM Do YYYY, h:mm:ss a');
},
yFormatter: function(y) { return Math.floor(y) + " users" }
} );
var xAxis = new Rickshaw.Graph.Axis.X( {
graph: graph,
orientation: 'bottom',
element: document.getElementById('x_axis'),
tickFormat: function(x) { return moment(x).fromNow(); },
ticks: 7,
tickSize: 1,
} );
xAxis.render();
var ticksTreatment = 'glow';
var yAxis = new Rickshaw.Graph.Axis.Y( {
graph: graph,
orientation: 'left',
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
ticksTreatment: ticksTreatment,
element: document.getElementById('y_axis'),
} );
yAxis.render();
});
There's no official way to do so. However, you could leverage the fact that arrays in javascript are passed by reference and then update the graph.
Have a look at this demo on fiddle
var data = [
{
data: [ { x: 0, y: 120 }, { x: 1, y: 890 }, { x: 2, y: 38 }, { x: 3, y: 70 }, { x: 4, y: 32 } ],
color: "#c05020"
}, {
data: [ { x: 0, y: 80 }, { x: 1, y: 200 }, { x: 2, y: 100 }, { x: 3, y: 520 }, { x: 4, y: 133 } ],
color: "#30c020"
}
];
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
renderer: 'line',
height: 300,
width: 800,
series: data
} );
var y_ticks = new Rickshaw.Graph.Axis.Y( {
graph: graph,
orientation: 'left',
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
element: document.getElementById('y_axis'),
} );
graph.render();
$('button#add').click(function() {
data.push({
data: [ { x: 0, y: 200 }, { x: 1, y: 390 }, { x: 2, y: 1000 }, { x: 3, y: 200 }, { x: 4, y: 230 } ],
color: "#6060c0"
});
graph.update();
});