I'm trying to add a slider to a google chart but I cannot set programmatic_chart_div to a height of 100% filling the full page. What am I doing wrong?
google.charts.load('current', {'packages':['corechart', 'controls']});
google.charts.setOnLoadCallback(drawStuff);
var dashboard = 0;
var data = 0;
function drawStuff() {
dashboard = new google.visualization.Dashboard(
document.getElementById('programmatic_dashboard_div'));
// We omit "var" so that programmaticSlider is visible to changeRange.
var programmaticSlider = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'programmatic_control_div',
'options': {
'filterColumnLabel': 'Donuts eaten',
'ui': {'labelStacking': 'vertical'}
}
});
var programmaticChart = new google.visualization.ChartWrapper({
'chartType': 'ColumnChart',
'containerId': 'programmatic_chart_div',
'options': {
'width': '100%',
'height': '100%',
'legend': 'none',
'chartArea': {
'width': '100%',
'height': '100%'
},
'pieSliceText': 'value'
}
});
data = google.visualization.arrayToDataTable([
['Name', 'Donuts eaten'],
['Michael' , 5],
['Elisa', 7],
['Robert', 3],
['John', 2],
['Jessica', 6],
['Aaron', 1],
['Margareth', 8]
]);
dashboard.bind(programmaticSlider, programmaticChart);
drawChart();
}
window.addEventListener('resize', drawChart, false);
function drawChart() {
dashboard.draw(data);
}
body {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
#topDiv {
padding: 10px;
height: 100%;
background-color: green;
width: calc (100% - 20px);
max-height: calc(100vh - 20px);
}
#programmatic_dashboard_div {
height: 100%;
width: calc (100% - 40px);
background-color: lightblue;
max-height: inherit;
overflow: scroll;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="topDiv">
<div id="programmatic_dashboard_div">
<div id="programmatic_control_div"></div>
<div id="programmatic_chart_div" ></div>
</div>
</div>
jsfiddle
need to add 100% height to the <html> element (use the same as <body>)
and to the chart's <div> element
add the following css...
html {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
#programmatic_chart_div {
height: 100%;
}
see following working snippet...
google.charts.load('current', {'packages':['corechart', 'controls']});
google.charts.setOnLoadCallback(drawStuff);
var dashboard = 0;
var data = 0;
function drawStuff() {
dashboard = new google.visualization.Dashboard(
document.getElementById('programmatic_dashboard_div'));
// We omit "var" so that programmaticSlider is visible to changeRange.
var programmaticSlider = new google.visualization.ControlWrapper({
'controlType': 'NumberRangeFilter',
'containerId': 'programmatic_control_div',
'options': {
'filterColumnLabel': 'Donuts eaten',
'ui': {'labelStacking': 'vertical'}
}
});
var programmaticChart = new google.visualization.ChartWrapper({
'chartType': 'ColumnChart',
'containerId': 'programmatic_chart_div',
'options': {
'width': '100%',
'height': '100%',
'legend': 'none',
'chartArea': {
'width': '100%',
'height': '100%'
},
'pieSliceText': 'value'
}
});
data = google.visualization.arrayToDataTable([
['Name', 'Donuts eaten'],
['Michael' , 5],
['Elisa', 7],
['Robert', 3],
['John', 2],
['Jessica', 6],
['Aaron', 1],
['Margareth', 8]
]);
dashboard.bind(programmaticSlider, programmaticChart);
drawChart();
}
window.addEventListener('resize', drawChart, false);
function drawChart() {
dashboard.draw(data);
}
body {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
html {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
#topDiv {
padding: 10px;
height: 100%;
background-color: green;
width: calc (100% - 20px);
max-height: calc(100vh - 20px);
}
#programmatic_dashboard_div {
height: 100%;
width: calc (100% - 40px);
background-color: lightblue;
max-height: inherit;
overflow: scroll;
}
#programmatic_chart_div {
height: 100%;
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="topDiv">
<div id="programmatic_dashboard_div">
<div id="programmatic_control_div"></div>
<div id="programmatic_chart_div" ></div>
</div>
</div>
Related
I'm working on customisable dashboard where (amongst other features) users can drag dashboard tiles (div elements) around and reposition those tiles anywhere in the dashboard.
HTML Structure
The html structure is similar to the snippet below
<div class="dashboard">
<div class="tile"><canvas/></div>
<div class="tile"><canvas/></div>
<div class="tile empty"></div>
</div>
Expected Behavior
The idea is that the .dashboard can contain multiple .tiles and each .tile contains a report (a graph/chart drawn on a canvas element). Some of these .tiles can be .empty, as in, not containing any report. Then .tile can be dragged and dropped into the .empty tiles.
So, div.tile.empty serves as "dropzone" while div.tile will be draggable elements. A fiddler snippet has been added below for a simplistic-but-fully-functional example.
Libraries used
jQuery
ChartJs. An open source js library to draw charts on a canvas
The problem
It all seems to work well, except that after dropping a .tile the canvas resets its width/height to zero!!! And I haven't found a way to reset it back to its original dimensions before the drag/drop events. Even if I set the width/height manually, nothing is drawn on the canvas.
Question
Is there any way I can preserve (or recover) the width/height of the canvas while also getting it to re-drawn the graph after drag/dropping?
I tried using chartjs's update, render and resize functions to no avail.
The documentation of these functions can be found in the link below (version 3.5.0)...
https://www.chartjs.org/docs/3.5.0/developers/api.html
Code Example
Here's a sample code snippet where you can reproduce the issue mentioned above. The buttons are my attempt to update/resize/re-render the graphs after drag/dropping.
var $sourceTile = null;
var charts = [];
$(() => {
$(".buttons-container a").on("click", btnClickHandler);
renderChart("canvas1", 'doughnut');
renderChart("canvas2", "line");
attachDropHandlers();
});
attachDropHandlers = () => {
$(".tile").off("dragstart").off("dragover").off("drop");
$(".tile .report").on("dragstart", dragStartHandler);
$(".tile.empty").on("dragover", dragOverHandler);
$(".tile.empty").on("drop", dropHandler);
}
dragStartHandler = (e) => {
const $target = $(e.target);
const $report = $target.is(".report") ? $target : $target.parents(".report");
$sourceTile = $report.parents(".tile");
e.originalEvent.dataTransfer.setData("application/dashboard", $report[0].id);
e.originalEvent.dataTransfer.effectAllowed = "move";
e.originalEvent.dataTransfer.dropEffect = "move";
}
dragOverHandler = (e) => {
e.preventDefault();
e.originalEvent.dataTransfer.dropEffect = "move";
}
dropHandler = (e) => {
e.preventDefault();
const id = e.originalEvent.dataTransfer.getData("application/dashboard");
if (id) {
$("#" + id).appendTo(".tile.empty");
$(".tile.empty").removeClass("empty");
if ($sourceTile) {
$sourceTile.addClass("empty");
attachDropHandlers();
}
}
}
renderChart = (canvasId, type) => {
const labels = ["Red", "Green", "Blue"];
const data = [30, 25, 42];
const colors = ['rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)'];
const canvas = document.getElementById(canvasId);
const ctx = canvas.getContext('2d');
const chart = new Chart(ctx, {
type: type,
data: {
labels: labels,
datasets: [{
data: data,
backgroundColor: colors,
borderColor: colors,
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: true,
aspectRatio: 1,
plugins: {
legend: {
display: false
},
htmlLegend: {
tile: this.$tile,
maxItems: 8
}
}
}
});
chart.update();
charts.push(chart);
}
btnClickHandler = (e) => {
const button = e.target.id;
switch (button) {
case "btn1":
charts.forEach((chart) => chart.update());
break;
case "btn2":
charts.forEach((chart) => chart.update('resize'));
break;
case "btn3":
charts.forEach((chart) => chart.render());
break;
case "btn4":
charts.forEach((chart) => chart.resize());
break;
case "btn5":
charts.forEach((chart) => chart.resize(120, 120));
break;
}
}
html,
body {
background-color: #eee;
}
h3 {
margin: 0;
padding: 10px;
}
.dashboard {}
.dashboard .tile {
display: inline-block;
vertical-align: top;
margin: 5px;
height: 250px;
width: 250px;
}
.tile.empty {
border: 2px dashed #ccc;
}
.report {
height: 250px;
width: 250px;
background-color: #fff;
border-radius: 3px;
box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}
.buttons-container {
display: flex;
justify-content: space-between;
margin: 20px 0;
}
.buttons-container a {
background-color: #673AB7;
color: #EDE7F6;
cursor: pointer;
padding: 10px 15px;
border-radius: 3px;
box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}
.buttons-container a:hover {
background-color: #7E57C2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.6.0/dist/chart.min.js"></script>
<div class="dashboard">
<div class="tile">
<div id="report1" class="report" draggable="true">
<h3>
Report 1
</h3>
<div style="padding:10px;height:180px;width:180px">
<canvas id="canvas1"></canvas>
</div>
</div>
</div>
<div class="tile">
<div id="report2" class="report" draggable="true">
<h3>
Report 2
</h3>
<div style="padding:10px;height:180px;width:180px">
<canvas id="canvas2"></canvas>
</div>
</div>
</div>
<div class="tile empty">
</div>
</div>
<div class="buttons-container">
<a id="btn1">update()</a>
<a id="btn2">update('resize')</a>
<a id="btn3">render()</a>
<a id="btn4">resize()</a>
<a id="btn5">resize(120,120)</a>
</div>
This is a Chart.js issue of version 3.6.0 and fixed in version 3.6.1. Example below:
var $sourceTile = null;
var charts = [];
$(() => {
$(".buttons-container a").on("click", btnClickHandler);
renderChart("canvas1", 'doughnut');
renderChart("canvas2", "line");
attachDropHandlers();
});
attachDropHandlers = () => {
$(".tile").off("dragstart").off("dragover").off("drop");
$(".tile .report").on("dragstart", dragStartHandler);
$(".tile.empty").on("dragover", dragOverHandler);
$(".tile.empty").on("drop", dropHandler);
}
dragStartHandler = (e) => {
const $target = $(e.target);
const $report = $target.is(".report") ? $target : $target.parents(".report");
$sourceTile = $report.parents(".tile");
e.originalEvent.dataTransfer.setData("application/dashboard", $report[0].id);
e.originalEvent.dataTransfer.effectAllowed = "move";
e.originalEvent.dataTransfer.dropEffect = "move";
}
dragOverHandler = (e) => {
e.preventDefault();
e.originalEvent.dataTransfer.dropEffect = "move";
}
dropHandler = (e) => {
e.preventDefault();
const id = e.originalEvent.dataTransfer.getData("application/dashboard");
if (id) {
$("#" + id).appendTo(".tile.empty");
$(".tile.empty").removeClass("empty");
if ($sourceTile) {
$sourceTile.addClass("empty");
attachDropHandlers();
}
}
}
renderChart = (canvasId, type) => {
const labels = ["Red", "Green", "Blue"];
const data = [30, 25, 42];
const colors = ['rgba(255, 99, 132, 1)', 'rgba(54, 162, 235, 1)', 'rgba(255, 206, 86, 1)'];
const canvas = document.getElementById(canvasId);
const ctx = canvas.getContext('2d');
const chart = new Chart(ctx, {
type: type,
data: {
labels: labels,
datasets: [{
data: data,
backgroundColor: colors,
borderColor: colors,
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: true,
aspectRatio: 1,
plugins: {
legend: {
display: false
},
htmlLegend: {
tile: this.$tile,
maxItems: 8
}
}
}
});
chart.update();
charts.push(chart);
}
btnClickHandler = (e) => {
const button = e.target.id;
switch (button) {
case "btn1":
charts.forEach((chart) => chart.update());
break;
case "btn2":
charts.forEach((chart) => chart.update('resize'));
break;
case "btn3":
charts.forEach((chart) => chart.render());
break;
case "btn4":
charts.forEach((chart) => chart.resize());
break;
case "btn5":
charts.forEach((chart) => chart.resize(120, 120));
break;
}
}
html,
body {
background-color: #eee;
}
h3 {
margin: 0;
padding: 10px;
}
.dashboard {}
.dashboard .tile {
display: inline-block;
vertical-align: top;
margin: 5px;
height: 250px;
width: 250px;
}
.tile.empty {
border: 2px dashed #ccc;
}
.report {
height: 250px;
width: 250px;
background-color: #fff;
border-radius: 3px;
box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}
.buttons-container {
display: flex;
justify-content: space-between;
margin: 20px 0;
}
.buttons-container a {
background-color: #673AB7;
color: #EDE7F6;
cursor: pointer;
padding: 10px 15px;
border-radius: 3px;
box-shadow: 0 1px 2px rgba(0, 0, 0, .18);
}
.buttons-container a:hover {
background-color: #7E57C2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.6.1/dist/chart.min.js"></script>
<div class="dashboard">
<div class="tile">
<div id="report1" class="report" draggable="true">
<h3>
Report 1
</h3>
<div style="padding:10px;height:180px;width:180px">
<canvas id="canvas1"></canvas>
</div>
</div>
</div>
<div class="tile">
<div id="report2" class="report" draggable="true">
<h3>
Report 2
</h3>
<div style="padding:10px;height:180px;width:180px">
<canvas id="canvas2"></canvas>
</div>
</div>
</div>
<div class="tile empty">
</div>
</div>
<div class="buttons-container">
<a id="btn1">update()</a>
<a id="btn2">update('resize')</a>
<a id="btn3">render()</a>
<a id="btn4">resize()</a>
<a id="btn5">resize(120,120)</a>
</div>
I have a canvas with various div elements serving as boxes that represent areas of the canvas to capture. When the capture takes place, it isn't exactly as displayed on the screen. How can I track and responsively capture the div sections as they appear?
As an example, attempting to capture the large purple section:
Here is the code from the component:
<template>
<div>
<div class="video-wrapper">
<canvas ref="the-canvas" class="canvas">
</canvas>
<video class="video" ref="video" autoplay />
<div :class="profileCenter.name" :style="profileToStyle(profileCenter)" />
<div :class="profileTopLeft.name" :style="profileToStyle(profileTopLeft)" />
<div :class="profileTopMiddle.name" :style="profileToStyle(profileTopMiddle)" />
<div :class="profileTopRight.name" :style="profileToStyle(profileTopRight)" />
</div>
</div>
</template>
<script lang="ts">
import { Vue, Component, Watch } from 'vue-property-decorator'
import Header from '#/components/Header.vue'
#Component({ components: { Header } })
export default class Test extends Vue {
private userMedia: MediaStream | null = null
private winHeight: number = window.innerHeight
private winWidth: number = window.innerWidth
private profileCenter: any = { name: 'profile-box', height: 350, width: 250, top: 40, left: 50, transform: [-50, -50] }
private profileTopLeft: any = { name: 'profile-box', height: 100, width: 100, top: 20, left: 20, transform: [-50, -50] }
private profileTopMiddle: any = { name: 'profile-box', height: 100, width: 100, top: 20, left: 50, transform: [-50, -50] }
private profileTopRight: any = { name: 'profile-box', height: 100, width: 100, top: 20, left: 80, transform: [-50, -50] }
async mounted () {
this.$nextTick(() => {
window.addEventListener('resize', () => {
this.updateSizes()
})
})
this.userMedia = await navigator.mediaDevices.getUserMedia({ video: true, audio: false })
setTimeout(() => {
const video: HTMLVideoElement = document.getElementsByClassName('video')[0] as HTMLVideoElement
const canvas: HTMLCanvasElement = document.getElementsByClassName('canvas')[0] as HTMLCanvasElement
const targetSquare: HTMLDivElement = document.getElementsByClassName('profile-box')[0] as HTMLDivElement
const targetDims = targetSquare.getBoundingClientRect()
canvas.height = targetDims.height
canvas.width = targetDims.width
console.log(canvas.width, canvas.height)
console.log(video.videoWidth, video.videoHeight)
const ctx = canvas.getContext('2d')
ctx!.drawImage(video, targetDims.left, targetDims.top, targetDims.width, targetDims.height, 0, 0, targetDims.width, targetDims.height)
window.open(canvas.toDataURL())
}, 3000)
}
private updateSizes (): void {
this.winHeight = window.innerHeight
this.winWidth = window.innerWidth
}
private profileToStyle (profile: { height: number, width: number, top: number, left: number, transform: number[] }): string {
return `height: ${profile.height}px; min-height: ${profile.height}px; width: ${profile.width}px; min-width: ${profile.width}px; top: ${profile.top}%; left: ${profile.left}%; transform: translate(${profile.transform[0]}%, ${profile.transform[1]}%)`
}
#Watch('userMedia')
private userMediaWatcher () {
this.$refs.video.srcObject = this.userMedia
}
}
</script>
<style>
.container--fluid {
height: 100%;
overflow: hidden;
}
.video-wrapper {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.video-wrapper video {
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.canvas {
position: absolute;
/* width: 480px; */
/* height: 640px; */
}
.profile-box{
position: absolute;
border: 2px solid purple;
}
</style>
There are a couple of complicating factors that make it a bit hard here.
The drawImage method takes its image data from the original source. Meaning, you are not drawing a part of the video that is presented to you. You are cutting out a piece from the original image/video capture. That means that you have to calculate the difference between the video dimensions presented to you and the dimensions of the original video.
Since the video 'overflows' out of the container on either the left and right or on the top and bottom side, you will have to account for that and add an offset to either the top or left.
Lastly, to get the image as presented on screen, you will have to stretch by providing the profile-box dimensions to drawImage.
To put it all together:
<template>
<section class="home">
<div>
<div class="video-wrapper">
<canvas ref="the-canvas" class="canvas">
</canvas>
<video class="video" ref="video" autoplay/>
<div :class="profileCenter.name" :style="profileToStyle(profileCenter)" />
<div :class="profileTopLeft.name" :style="profileToStyle(profileTopLeft)" />
<div :class="profileTopMiddle.name" :style="profileToStyle(profileTopMiddle)" />
<div :class="profileTopRight.name" :style="profileToStyle(profileTopRight)" />
</div>
</div>
</section>
</template>
<script lang="ts">
import { Vue, Component, Watch } from 'vue-property-decorator'
import Header from '#/pages/Header.vue'
#Component({components: Header})
export default class Test extends Vue {
$refs!: {
video: HTMLVideoElement
}
private userMedia: MediaStream | null = null
private winHeight: number = window.innerHeight
private winWidth: number = window.innerWidth
private profileCenter: any = { name: 'profile-box', height: 350, width: 250, top: 40, left: 50, transform: [-50, -50] }
private profileTopLeft: any = { name: 'profile-box', height: 100, width: 100, top: 20, left: 20, transform: [-50, -50] }
private profileTopMiddle: any = { name: 'profile-box', height: 100, width: 100, top: 20, left: 50, transform: [-50, -50] }
private profileTopRight: any = { name: 'profile-box', height: 100, width: 100, top: 20, left: 80, transform: [-50, -50] }
async mounted () {
this.$nextTick(() => {
window.addEventListener('resize', () => {
this.updateSizes()
})
})
this.userMedia = await navigator.mediaDevices.getUserMedia({ video: true, audio: false })
setTimeout(() => {
const video: HTMLVideoElement = document.getElementsByClassName('video')[0] as HTMLVideoElement
const canvas: HTMLCanvasElement = document.getElementsByClassName('canvas')[0] as HTMLCanvasElement
const targetSquare: HTMLDivElement = document.getElementsByClassName('profile-box')[0] as HTMLDivElement
const targetDims = targetSquare.getBoundingClientRect()
canvas.height = targetDims.height
canvas.width = targetDims.width
const ctx = canvas.getContext('2d')
const originalVideoWidth = video.videoWidth;
const originalVideoHeigth = video.videoHeight;
const videoActualWidth: number = video.getBoundingClientRect().width;
const videoActualHeight: number = video.getBoundingClientRect().height;
const videoContainer: HTMLDivElement = document.getElementsByClassName('video-wrapper')[0] as HTMLDivElement;
const containerWidth: number = videoContainer.getBoundingClientRect().width;
const containerHeight: number = videoContainer.getBoundingClientRect().height;
let videoOffsetLeft = 0;
let videoOffsetTop = 0;
if(containerWidth === videoActualWidth){
videoOffsetTop = ((videoActualHeight - containerHeight) / 2) * (originalVideoHeigth / videoActualHeight)
}
else{
videoOffsetLeft = ((videoActualWidth - containerWidth) / 2) * (originalVideoWidth / videoActualWidth)
}
const left = videoOffsetLeft + ((originalVideoWidth / videoActualWidth) * targetDims.left);
const top = videoOffsetTop + ((originalVideoHeigth / videoActualHeight) * targetDims.top);
const width = (originalVideoWidth / videoActualWidth ) * targetDims.width;
const height = (originalVideoHeigth / videoActualHeight ) * targetDims.height;
ctx!.drawImage(video,
left, top, width, height, 0, 0, targetDims.width,targetDims.height)
//window.open(canvas.toDataURL())
}, 3000)
}
private updateSizes (): void {
this.winHeight = window.innerHeight
this.winWidth = window.innerWidth
}
private profileToStyle (profile: { height: number, width: number, top: number, left: number, transform: number[] }): string {
return `height: ${profile.height}px; min-height: ${profile.height}px; width: ${profile.width}px; min-width: ${profile.width}px; top: ${profile.top}%; left: ${profile.left}%; transform: translate(${profile.transform[0]}%, ${profile.transform[1]}%)`
}
#Watch('userMedia')
private userMediaWatcher () {
this.$refs.video.srcObject = this.userMedia
}
}
</script>
<style>
.container--fluid {
height: 100%;
overflow: hidden;
}
.video-wrapper {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.video-wrapper video {
min-width: 100%;
min-height: 100%;
width: auto;
height: auto;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
img{
height: 100%;
width: 100%;
}
.canvas {
position: absolute;
/* width: 480px; */
/* height: 640px; */
}
.profile-box{
position: absolute;
border: 2px solid purple;
}
</style>
How can we add tinymce editor in the place of editor present in the cell of ag-grid?
In order to customize ag-grid's cell's you need to create a custom Cell Renderer component.
You can pretty much put anything you want in that custom component, including tinyMCE.
More info: https://www.ag-grid.com/javascript-grid-cell-rendering-components/
Please see Cell Renderer
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script>var __basePath = './';</script>
<style media="only screen">
html, body {
height: 100%;
width: 100%;
margin: 0;
box-sizing: border-box;
-webkit-overflow-scrolling: touch;
}
html {
position: absolute;
top: 0;
left: 0;
padding: 0;
overflow: auto;
}
body {
padding: 1rem;
overflow: auto;
}
</style>
<script src="https://unpkg.com/#ag-grid-community/all-modules#24.1.0/dist/ag-grid-community.min.js"></script>
</head>
<body>
<div id="myGrid" style="height: 100%;width: 100%" class="ag-theme-alpine"></div>
<script src="main.js"></script>
</body>
</html>
main.js
var columnDefs = [
{ field: 'athlete' },
{ field: 'country' },
{ field: 'year', width: 100 },
{ field: 'gold', width: 100, cellRenderer: 'medalCellRenderer' },
{ field: 'silver', width: 100, cellRenderer: 'medalCellRenderer' },
{ field: 'bronze', width: 100, cellRenderer: 'medalCellRenderer' },
{ field: 'total', width: 100 }
];
var gridOptions = {
columnDefs: columnDefs,
components: {
'medalCellRenderer': MedalCellRenderer
},
defaultColDef: {
editable: true,
sortable: true,
flex: 1,
minWidth: 100,
filter: true,
resizable: true
}
};
// cell renderer class
function MedalCellRenderer() {
}
// init method gets the details of the cell to be renderer
MedalCellRenderer.prototype.init = function(params) {
this.eGui = document.createElement('span');
var text = '';
// one star for each medal
for (var i = 0; i < params.value; i++) {
text += '#';
}
this.eGui.innerHTML = text;
};
MedalCellRenderer.prototype.getGui = function() {
return this.eGui;
};
// setup the grid after the page has finished loading
document.addEventListener('DOMContentLoaded', function() {
var gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
agGrid.simpleHttpRequest({ url: 'https://raw.githubusercontent.com/ag-grid/ag-grid/master/grid-packages/ag-grid-docs/src/olympicWinnersSmall.json' })
.then(function(data) {
gridOptions.api.setRowData(data);
});
});
I have this Google Chart (Line Graph) code:
<html>
<head>
<style>
.chart {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
min-height: 500px;
}
#chart {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
min-height: 500px;
}
</style>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['line']});
google.charts.setOnLoadCallback(drawChart);
window.addEventListener('resize', function (event) {
drawChart();
});
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'Day');
data.addColumn('number', 'Guardians of the Galaxy');
data.addColumn('number', 'The Avengers');
data.addColumn('number', 'Transformers: Age of Extinction');
data.addRows([
[1, 37.8, 80.8, 41.8],
[2, 30.9, 69.5, 32.4],
[3, 25.4, 57, 25.7],
[4, 11.7, 18.8, 10.5],
[5, 11.9, 17.6, 10.4],
[6, 8.8, 13.6, 7.7],
[7, 7.6, 12.3, 9.6],
[8, 12.3, 29.2, 10.6],
[9, 16.9, 42.9, 14.8],
[10, 12.8, 30.9, 11.6],
[11, 5.3, 7.9, 4.7],
[12, 6.6, 8.4, 5.2],
[13, 4.8, 6.3, 3.6],
[14, 4.2, 6.2, 3.4]
]);
var options = {
chart: {
title: 'Box Office Earnings in First Two Weeks of Opening',
subtitle: 'in millions of dollars (USD)'
},
// width: 1800,
// height: 1000,
axes: {
x: {
0: {side: 'top'}
}
}
};
var chart = new google.charts.Line(document.getElementById('line_top_x'));
chart.draw(data, google.charts.Line.convertOptions(options));
}
</script>
</head>
<body>
<div id="line_top_x"></div>
</body>
</html>
you can write that to a file and just open it with a browser - it renders fine, but I cannot get the height of the graph to increase no matter what I add to the css (the style tag).
Anyone know how to get the height to be 100% of the page?
As you can see from the screenshot, the graph is squashed where the height is only about 100px.
I added the following CSS:
body {
width:80%;
height:80%;
margin:10% auto;
background:#e6e6e6;
}
#chart_wrap {
border:1px solid gray;
position: relative;
padding-bottom: 100%;
height: 0;
overflow:hidden;
}
#chart {
position: absolute;
top: 0;
left: 0;
width:100%;
height:100%;
}
and I still cannot get the height to increase:
I think I need to use this to alter the width/height
var options = {
chart: {
title: 'Node.js memory usage (RSS, Heap Used, Heap Total)',
subtitle: '(In megabytes.)'
},
// width: 1800,
// height: 1000,
axes: {
x: {
0: {side: 'top'}
}
}
};
var chart = new google.charts.Line(document.getElementById('line_top_x'));
chart.draw(data, google.charts.Line.convertOptions(options));
but I don't know what to use for height/width to make it 100% of the window/container.
add this css
#line_top_x {
height: 100vh;
}
I have a main div, inside it are two div's each having a canvass. My problem is the canvass is not responsive, it overlaps when I resize the browser. please see below image.
Here is my HTML code:
<div id="mainContainer">
<div id="leftcolumn">
<h2>
Canvass Graph1
</h2>
<canvas id="Canvass_One"></canvas>
</div>
<div id="rightcolumn">
<h2>Canvass Graph2</h2>
<canvas id="Canvass_Two"></canvas>
</div>
</div>
CSS Code:
#mainContainer
{
width:100%;
height: 100%;
}
#leftcolumn
{
float:left;
display:inline-block;
width: -moz-calc(100% - 50%);
width: -webkit-calc(100% - 50%);
width: calc(100% - 50%);
height: 100%;
background: blue;
}
#rightcolumn {
float:left;
display:inline-block;
width: -moz-calc(100% - 50%);
width: -webkit-calc(100% - 50%);
width: calc(100% - 50%);
height: 100%;
background-color : red;
}
JS to set height and width of Canvass
var ctx2 = $("#Canvass_One").get(0).getContext('2d');
ctx2.canvas.height = 300; // setting height of canvas
ctx2.canvas.width = 560; // setting width of canvas
var ctx1 = $("#Canvass_Two").get(0).getContext('2d');
ctx1.canvas.height = 300; // setting height of canvas
ctx1.canvas.width = 560; // setting width of canvas
Canvas:
Again, my problem is when I minimized/resize the browser window , the canvass overlaps. thank you for any help. My case is that I'm not using image within my div, it's just a pure canvass with chart js framework to create a graph.
Sample data:
var barData = {
labels: ['CityA', 'CityB', 'CityC', 'CityD', 'CityF', 'CityG'],
datasets: [
{
label: '2010 customers #',
fillColor: '#382765',
data: [2500, 1902, 1041, 610, 1245, 952]
},
{
label: '2014 customers #',
fillColor: '#7BC225',
data: [3104, 1689, 1318, 589, 1199, 1436]
}
]
};
The trick is to set the style width/height in combination with the attribute width/height, as the style controls display and attribute controls image.
#Canvass_One, #Canvass_Two
{
width: 100%;
height: 100%;
}
Note: Chart.js appears to have its own setting do deal with responsiveness like this, Chart.defaults.global.responsive = true;, so one might need to combine the two.
Here is a sample to show how it works.
Chart.defaults.global.responsive = true;
var barData = {
labels: ['CityA', 'CityB', 'CityC', 'CityD', 'CityF', 'CityG'],
datasets: [
{
label: '2010 customers #',
fillColor: '#382765',
data: [2500, 1902, 1041, 610, 1245, 952]
},
{
label: '2014 customers #',
fillColor: '#7BC225',
data: [3104, 1689, 1318, 589, 1199, 1436]
}
]
};
var ctx2 = $("#Canvass_One").get(0).getContext('2d');
ctx2.canvas.height = 300; // setting height of canvas
ctx2.canvas.width = 560; // setting width of canvas
//ctx2.fillStyle = "#FF0000";
//ctx2.fillRect(10,0,450,75);
var clientsChart = new Chart(ctx2).Bar(barData);
var ctx1 = $("#Canvass_Two").get(0).getContext('2d');
ctx1.canvas.height = 300; // setting height of canvas
ctx1.canvas.width = 560; // setting width of canvas
ctx1.fillStyle = "#0000FF";
ctx1.fillRect(10,0,450,75);
#mainContainer
{
width:100%;
height: 100%;
}
#leftcolumn
{
float:left;
display:inline-block;
width: 50%;
height: 100%;
background: blue;
}
#rightcolumn
{
float:left;
display:inline-block;
width: 50%;
height: 100%;
background-color : red;
}
#Canvass_One, #Canvass_Two
{
width: 100%;
height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>
<div id="mainContainer">
<div id="leftcolumn">
<h2>Canvass Graph1</h2>
<canvas id="Canvass_One"></canvas>
</div>
<div id="rightcolumn">
<h2>Canvass Graph2</h2>
<canvas id="Canvass_Two"></canvas>
</div>
</div>