Recharge by clicking on tabs - javascript

I need to reload the contents of the tab by clicking on the link, because I'm trying rendering problems on the Google Chart.
I made a JsFiddle that represents the problem. Notice the rendering difference of the two tabs.
I put a delay, but when I access another tab. Incorrect rendering still happens.
setTimeout(function () {
chart.draw(data, options);
}, 2000);

need to wait until the chart's container is visible, before drawing for the first time
see following working snippet...
$(document).foundation();
$('#sac-tabs').on('change.zf.tabs', function() {
switch ($(this).children('.is-active').text().trim()) {
case 'Tab 1':
drawVisualization();
break;
case 'Tab 2':
drawVisualization2();
break;
}
});
google.charts.load('current', {
callback: drawVisualization,
packages: ['corechart']
});
function drawVisualization() {
var data = google.visualization.arrayToDataTable([
['Departamento', 'Concluídas', 'Andamento', 'Pendentes'],
['Vendas', 5, 6, 2],
['Peças', 3, 4, 6],
['Serviços', 1, 2, 3],
['Administrativo', 7, 5, 3]
]);
var options = {
title: 'Gráfico',
hAxis: {title: 'Departamento'},
seriesType: 'bars',
colors: ['#21BA45', '#F90', '#DC3912'],
series: {5: {type: 'line'}}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
function drawVisualization2() {
var data = google.visualization.arrayToDataTable([
['Departamento', 'Concluídas', 'Andamento', 'Pendentes'],
['Vendas', 5, 6, 2],
['Peças', 3, 4, 6],
['Serviços', 1, 2, 3],
['Administrativo', 7, 5, 3]
]);
var options = {
title: 'Gráfico',
hAxis: {title: 'Departamento'},
seriesType: 'bars',
colors: ['#21BA45', '#F90', '#DC3912'],
series: {5: {type: 'line'}}
};
var chart = new google.visualization.ComboChart(document.getElementById('chart_div2'));
chart.draw(data, options);
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.1.2/foundation.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.1.2/foundation.min.css">
<div class="row">
<div class="medium-12 columns">
<ul class="tabs" data-tabs id="sac-tabs">
<li class="tabs-title is-active">
Tab 1</li>
<li class="tabs-title">Tab 2</li>
</ul>
<div class="tabs-content" data-tabs-content="sac-tabs">
<div class="tabs-panel is-active" id="panel1">
<div class="row">
<div class="medium-12 columns">
<p>
Expected outcome
</p>
<div id="chart_div"></div>
</div>
</div>
</div>
<div class="tabs-panel" id="panel2">
<div class="row">
<div class="medium-12 columns">
<p>
Not a Problem
</p>
<div id="chart_div2"></div>
</div>
</div>
</div>
</div>
</div>
</div>

I got your problem,
Only active tab draw full width, draft.
For solution you want to make one think, when you draw second tab draft, that time active second tab using jQuery after that run "chart. draws" commnad.
I hope you understand. Enjoy :)

Related

Django creating radar chart with Json

I created a system with Django. I need some charts for my project and I am using chart.js library.
I get data from an API address, I can get the data correctly with Json and display it in a table, but I can not display it in the radar chart.
I think I cannot write Javascript code correctly because Radar chart does not show anything.
views.py
def Radar(request):
response = requests.get('https://api.f-rayscoring.com/company/ADESE/radar')
data = response.json()
return render(request, 'radar.html', {'data': data})
radar.html
<div class="content">
<div class="page-inner">
<h4 class="page-title">Radar Chart</h4>
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<div class="card-title">Radar Chart</div>
</div>
<div class="card-body">
<div class="chart-container">
<canvas id="radarChart"></canvas>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock content %}
{% block javascripts %}
<script src="/static/assets/js/setting-demo2.js"></script>
<script>
radarChart = document.getElementById('radarChart').getContext('2d')
{% for dt in data %}
var myRadarChart= new Chart(radarChart, {
type: 'radar',
data: {
labels: [{{ dt.title }}],
datasets: [{
data: [{{ dt.value }}],
borderColor: '#1d7af3',
backgroundColor : 'rgba(29, 122, 243, 0.25)',
pointBackgroundColor: "#1d7af3",
pointHoverRadius: 4,
pointRadius: 3,
label: 'Team 1'
}, {
data: [],
borderColor: '#716aca',
backgroundColor: 'rgba(113, 106, 202, 0.25)',
pointBackgroundColor: "#716aca",
pointHoverRadius: 4,
pointRadius: 3,
label: 'Team 2'
},
]
},
options : {
responsive: true,
maintainAspectRatio: false,
legend : {
position: 'bottom'
}
}
});
{% endfor %}
my api
[{"title":"Verimlilik","value":0.5},{"title":"Likidite","value":0.7},{"title":"Kaldıraç","value":2.7},{"title":"Karlılık","value":1.55},{"title":"Büyüme","value":1.5}]
All data in this api should display in 1 radar chart.

Determining which chart the user has clicked on

I'm using chart.js to draw multiple line charts. And when the user clicks on one of these charts, I need to know which chart it was. In order to catch the click of the user, I've added events: ['click'] in the options of the chart, as well as a onClick: clicked to call the function clicked when the user has clicked on the chart. Now I have this:
let chLine = document.getElementById("chLine");
let chartData = {
labels: ['l1', 'l2', 'l3', 'l4', 'l5', 'l6', 'l7', 'l8', 'l9'],
datasets: [
{
label: 'c1',
data: [0.3, 0.4, 0.5, 0.35, 0.2, 0.5, 0.4, 0.55, 0.6],
backgroundColor: 'transparent',
borderColor: '#e6194b',
borderWidth: 1,
pointBackgroundColor: '#e6194b'
},
{
label: 'c2',
data: [0.7, 0.5, 0.2, 0.4, 0.6, 0.1, 0.88, 0.35, 0.45],
backgroundColor: 'transparent',
borderColor: '#3cb44b',
borderWidth: 1,
pointBackgroundColor: '#3cb44b'
}
]
}
if (chLine) {
new Chart(chLine,{
type: 'line',
data: chartData,
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: false
}
}]
},
legend: {
position: 'top',
labels: {
boxWidth: 5
}
},
events: ['click'],
onClick: clicked
}
}
);
}
function clicked(c, i) {
console.log(c, i)
}
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<meta charset="UTF-8">
</head>
<body>
<div class="container">
<div class="row my-3">
<div class="col">
<h4>Chart</h4>
</div>
</div>
<div class="row my-2">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<canvas id="chLine" height="100"></canvas>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script>
<script src="test.js"></script>
</body>
</html>
And every time I click on a chart, it gives an array containing information about each chart and also an object containing information about the click event. But I can't seem to find information to conclude which chart was clicked. How can I do this?
Inside the clicked function you can use getElementAtEvent(c) & _datasetIndex; to get the index of the chart data.After that use that index to get the data which is used to draw that line chart. In this example another field is added to the data and on click that name field is consoled. In this case you need to click on the chart circle
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script>
<div class="container">
<div class="row my-3">
<div class="col">
<h4>Chart</h4>
</div>
</div>
<div class="row my-2">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<canvas id="chLine" height="100"></canvas>
</div>
</div>
</div>
</div>
</div>
let chLine = document.getElementById("chLine");
let chartData = {
labels: ['l1', 'l2', 'l3', 'l4', 'l5', 'l6', 'l7', 'l8', 'l9'],
datasets: [{
name: 'First Chart',
label: 'c1',
data: [0.3, 0.4, 0.5, 0.35, 0.2, 0.5, 0.4, 0.55, 0.6],
backgroundColor: 'transparent',
borderColor: '#e6194b',
borderWidth: 1,
pointBackgroundColor: '#e6194b'
},
{
name: 'Second Chart',
label: 'c2',
data: [0.7, 0.5, 0.2, 0.4, 0.6, 0.1, 0.88, 0.35, 0.45],
backgroundColor: 'transparent',
borderColor: '#3cb44b',
borderWidth: 1,
pointBackgroundColor: '#3cb44b',
id: '1',
}
]
}
if (chLine) {
var myLineChart = new Chart(chLine, {
type: 'line',
data: chartData,
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero: false
}
}]
},
legend: {
position: 'top',
labels: {
boxWidth: 5
}
},
events: ['click'],
onClick: clicked
}
});
}
function clicked(c, i, x) {
let getDataSetIndex = this.getElementAtEvent(c)[0]._datasetIndex;
console.log(chartData.datasets[getDataSetIndex].name)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js"></script>
<div class="container">
<div class="row my-3">
<div class="col">
<h4>Chart</h4>
</div>
</div>
<div class="row my-2">
<div class="col-md-12">
<div class="card">
<div class="card-body">
<canvas id="chLine" height="100"></canvas>
</div>
</div>
</div>
</div>
</div>

Responsive not working in D3 Funnel Chart

I tried to d3 funnel chart with responsive in all device.I used bootstrap panel and inside d3 funnel chart.Funnel chart created but not look in responsive device.Once i resized my device or responsive mobile in console is not look.
This is desktop image[enter image description here][1]
This is mobile device in console
[enter image description here][2]
[1]: https://i.stack.imgur.com/DPrGC.png
[2]: https://i.stack.imgur.com/RJEu8.png
Bootstrap coding
<div class="col-lg-3 col-md-3 col-sm-3">
<div class="panel panel-primary ">
<div class="panel-heading ">
<h3 class="panel-title text-uppercase">Candidate By Status</h3>
</div>
<div class="panel-body ">
<div class="funnelPanel">
<div id="funnelContainer"></div>
</div>
</div>
</div>
</div>
D3 Funnel coding...
var data1 = [
['I', 12],
['T', 4],
['L', 25],
['C', 15],
['A', 12],
['T', 4]
];
const options1 = {
chart: {
width: 200,
height: 450,
bottomWidth: 1 / 2,
bottomPinch: 1,
curve: {
enabled: true,
height: 20,
shade: -0.4
}
},
block: {
dynamicSlope: true,
dynamicHeight: true,
highlight: true,
minHeight: 50,
fill: {
type: 'gradient',
}
}
}
const funnel = new D3Funnel("#funnelContainer");
funnel.draw(data1, options1);
d3.select('#funnelContainer svg')
.attr('transform', 'translate(0)rotate(270)')
How to fixed funnel chart width and height for responsive with all device.

Vue.js breaking Google Map functionality

Currently the code uses Vue.js to manage the inputs and post requests and is using JavaScript to handle things like Google Map functionality.
The issue is that when we wrap a div id around all the current HTML on a page so the Vue.js functionality works, it results in the Google Map code in a JavaScript file to run incorrectly and loads the page with no map. As soon as the Vue.js id (adminVenueVue) is removed the map works fine.
When trying to debug the issue it seems that the function that is responsible for updating the map doesn't run all the way through and stops when a listener function is created as no following code would run after. Below shows this function if you need more code please tell me.
function initCreateUpdateVenue() {
var mapCenter = new google.maps.LatLng({
lat: 54.445886,
lng: -3.435974
});
var marker, london = {
lat: 52.41,
lng: -1.69
};
var ZoomLevel = 5;
map = new google.maps.Map(document.getElementsByName('googleMap')[0], {
zoom: ZoomLevel,
center: mapCenter,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
map.setZoom(5);
var input = (document.getElementsByName("autocomplete")[0]);
var options = {
componentRestrictions: {
country: "uk"
}
};
var autocomplete = new google.maps.places.Autocomplete(input, options);
autocomplete.bindTo('bounds', map);
autocomplete.addListener('place_changed', function() {
var element = document.getElementsByName("autocomplete")[0];
//remove any errors
element.classList.remove("is-invalid");
var place = autocomplete.getPlace();
if (!place.geometry) {
return;
}
populate_hidden_fields(place);
set_venue_detail_fields(place);
populate_fields(place.address_components);
set_map_location();
});
}
Here is the HTML code (the Google Map code is at the bottom)
<div id="adminVenueVue">
<div class="row">
<div class="col-lg-12 ">
<div class="row">
<div class="col-lg-12 ui-sortable-disabled">
<div class="panel">
<div class="panel-heading disable-draggable">Administrator Controls</div>
<div class="panel-body">
#include('venue.components.admin_controls', ['submitButtonText' => 'Add Type'])
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12 ui-sortable-disabled">
<div class="panel">
<div class="panel-heading disable-draggable">Start by finding your address</div>
<div class="panel-body">
#include('venue.components.autocomplete-form', ['submitButtonText' => 'Add Type'])
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-6 ui-sortable-disabled">
<div class="panel">
<div class="panel-heading disable-draggable">Venue Details</div>
<div class="panel-body" style="padding-bottom: 16px;">
#include('venue.components.venue-details', ['submitButtonText' => 'Add Type'])
</div>
</div>
</div>
<div class="col-lg-6 ui-sortable-disabled">
<div class="panel">
<div class="panel-heading disable-draggable ">Address Details</div>
<div class="panel-body">
#include('venue.components.form', ['submitButtonText' => 'Submit Venue'])
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-lg-12 ui-sortable-disabled">
<div class="panel">
<div class="panel-heading disable-draggable">Map</div>
<div class="panel-body">
<div id="googleMap" name="googleMap" class="width-full" style="height: 500px;"></div>
</div>
</div>
</div>
</div>
</div>
I recommend using the Vue google map component (vue2-google-maps).
Follow this example code:
<body>
<div id="root">
<google-map :center="{lat: 1.38, lng: 103.8}" :zoom="12" style="width: 100%; height: 500px">
<ground-overlay source="./overlay.png" :bounds="{
north: 1.502,
south: 1.185,
east: 104.0262,
west: 103.5998,
}" :opacity="0.5">
</ground-overlay>
</google-map>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.0/vue.js"></script>
<script src="vue-google-maps.js"></script>
<script>
Vue.use(VueGoogleMaps, {
load: {
key: 'AIzaSyBzlLYISGjL_ovJwAehh6ydhB56fCCpPQw',
v: '3.26',
},
// Demonstrating how we can customize the name of the components
installComponents: false,
});
document.addEventListener('DOMContentLoaded', function() {
Vue.component('google-map', VueGoogleMaps.Map);
Vue.component('ground-overlay', VueGoogleMaps.MapElementFactory({
mappedProps: {
'opacity': {}
},
props: {
'source': {type: String},
'bounds': {type: Object},
},
events: ['click', 'dblclick'],
name: 'groundOverlay',
ctr: () => google.maps.GroundOverlay,
ctrArgs: (options, {source, bounds}) => [source, bounds, options],
}));
new Vue({
el: '#root',
data: {
place: '',
},
});
});
</script>
</body>
Or, if you're using webpack and Vue file components, follow the instructions bellow.
First install it : npm install vue2-google-maps
Then register it in main.js file
import Vue from 'vue'
import * as VueGoogleMaps from 'vue2-google-maps'
Vue.use(VueGoogleMaps, {
load: {
key: 'YOUR_API_TOKEN',
libraries: 'places', // This is required if you use the Autocomplete plugin
}
})
So, you can use it like a component:
<GmapMap
:center="{lat:10, lng:10}"
:zoom="7"
map-type-id="terrain"
style="width: 500px; height: 300px"
>
<GmapMarker
:key="index"
v-for="(m, index) in markers"
:position="m.position"
:clickable="true"
:draggable="true"
#click="center=m.position"
/>
</GmapMap>
More at:
https://www.npmjs.com/package/vue2-google-maps
https://github.com/xkjyeah/vue-google-maps/blob/no-deferred-ready/examples/overlay.html
https://alligator.io/vuejs/vue-google-maps/ (tutorial)

MeteorJs and Masonry

I am using MeteorJS (So great :) ), to develop simple app. I want to use masonry, so I am using sjors:meteor-masonry package.
When I use this code everything works fine:
var itemsData = [
{
title: 'First item',
description: 'Lorem 1',
price: 20
},
{
title: 'Secounde item',
description: 'Lorem 2',
price: 40
},
{
title: 'Third item',
description: 'Lorem 3',
price: 10
},
{
title: 'Fourth item',
description: 'Lorem 4',
price: 10
},
{
title: 'Five item',
description: 'sit 4',
price: 10
}
];
Template.itemsList.helpers({
items: itemsData
});
Template.itemsList.rendered = function() {
var container = document.querySelector('#main');
var msnry = new Masonry( container, {
// options
columnWidth: 200,
itemSelector: '.item'
});
};
But when I change part (code) for Template.itemsList.rendered to masonry don't work:
Template.itemsList.helpers({
items: function() {
return Items.find();
}
});
Any ideas ?
EDIT
myapp/lib/collections/items.js
Items = new Mongo.Collection('items');
And it is populated whit data from mongoshell. Data is ok, but masonry dont work.
EDIT 2
Masonry stops animating on screen resize and grid is not working as it should. No errors.
myapp/client/templates
<template name="itemSingle">
<div id="profile-widget" class="panel item">
<div class="panel-heading">
</div>
<div class="panel-body">
<div class="media">
<div class="media-body">
<h2 class="media-heading">{{title}}</h2>
{{description}}
</div>
</div>
</div>
<div class="panel-footer">
<div class="btn-group btn-group-justified">
<a class="btn btn-default" role="button"><i class="fa fa-eye"></i> 172</a>
<a class="btn btn-default" role="button"><i class="fa fa-comment"></i> 34</a>
<a class="btn btn-default highlight" role="button"><i class="fa fa-heart"></i> 210</a>
</div>
</div>
</div>
</template>
<template name="itemsList">
<div id="main">
{{#each items}}
{{> itemSingle}}
{{/each}}
</div>
</template>
I encountered the same problem, without never finding the perfect solution.
I tried to resolve with the setTimout() workaround :
Template.main.rendered = function() {
setTimeout(function() {
$('#container').masonry({
columnWidth: 35,
itemSelector: '.thumb',
gutter: 10,
isFitWidth: false
});
}, 1);
}

Categories

Resources