Too much code to paste here so....
Please see JS Fiddle at http://jsfiddle.net/1a2s35m2/ for current code.
I am attempting to create a horizontal bar chart using flot. As you will see from the Fiddle, this works fine but I want to display the values of the bars within the bars themselves and not as labels in the Y Axis, as in the picture below...
I have attempted to use the "labels" plugin and also the barnumbers plugin but these don't seem to work. (Barnumbers comes close but displays 0 1 2 3 as the values.
Any ideas?
I'm really starting to sound like a broken record on here, but as your charts become really complicated forget the plugins and do it yourself.
Here's modified code from my links above catered for how you drew your plots:
// after initial plot draw, then loop the data, add the labels
// I'm drawing these directly on the canvas, NO HTML DIVS!
// code is un-necessarily verbose for demonstration purposes
var ctx = somePlot.getCanvas().getContext("2d"); // get the context
var allSeries = somePlot.getData(); // get your series data
var xaxis = somePlot.getXAxes()[0]; // xAxis
var yaxis = somePlot.getYAxes()[0]; // yAxis
var offset = somePlot.getPlotOffset(); // plots offset
ctx.font = "12px 'Segoe UI'"; // set a pretty label font
ctx.fillStyle = "black";
for (var i = 0; i < allSeries.length; i++){
var series = allSeries[i];
var dataPoint = series.datapoints.points; // one point per series
var x = dataPoint[0];
var y = dataPoint[1];
var text = x + '%';
var metrics = ctx.measureText(text);
var xPos = xaxis.p2c(x)+offset.left - metrics.width; // place at end of bar
var yPos = yaxis.p2c(y) + offset.top - 2;
ctx.fillText(text, xPos, yPos);
}
Updated fiddle.
Related
To visualize your data in Data Studio you can use Java Script (beta): https://codelabs.developers.google.com/codelabs/community-visualization/#0
There is a how to which works, you need the following files to create diagrams:
myViz is created by command, which put together the myVizSource.js and the visualization helper library (dscc.min.js)
To create a simple bar chart you put in the myVizSource.js the following code:
// create and add the canvas
var canvasElement = document.createElement('canvas');
var ctx = canvasElement.getContext('2d');
canvasElement.id = 'myViz';
document.body.appendChild(canvasElement);
function transformStyleById(vizData){
// parse the style object
var styleById = {};
for (let styleSection of vizData.config.style) {
for (let styleElement of styleSection.elements) {
styleById[styleElement.id] = {
value: styleElement.value,
defaultValue: styleElement.defaultValue
};
}
}
return styleById;
}
function drawViz(vizData) {
// parse the data into a row of rows format
var data = dscc.rowsByConfigId(vizData).DEFAULT;
var ctx = canvasElement.getContext('2d');
// clear the canvas.
ctx.clearRect(0, 0, canvasElement.width, canvasElement.height);
// set the canvas width and height
ctx.canvas.width = dscc.getWidth() - 20;
ctx.canvas.height = dscc.getHeight() - 100;
var styleById = transformStyleById(vizData);
// scale the bar width and max bar height to the canvas
var barWidth = ctx.canvas.width / (data.length * 2);
var maxBarHeight = ctx.canvas.height - 20;
// vertical offset for bar text
var textYOffset = 20;
// fill the bars using the user-selected bar color or the default
ctx.fillStyle = styleById.barColor.value.color || styleById.barColor.defaultValue;
// obtain the maximum bar metric value for scaling purposes
var metricMax = 0;
data.forEach(function(row){
metricMax = Math.max(metricMax, row['barMetric'][0]);
})
// draw bars
// add dimension labels below bars
// 'barDimension' and 'barMetric' come from the id defined in myViz.json
data.forEach(function(row, i) {
// calculates the height of the bar using the row value, maximum bar
// height, and the maximum metric value calculated earlier
var barHeight = Math.round(
-1 * ((row['barMetric'][0] * maxBarHeight) / metricMax)
);
// calculates the x coordinate of the bar based on the width of the convas
// and the width of the bar
var barX = (ctx.canvas.width / data.length) * i + barWidth / 2;
ctx.fillRect(barX, maxBarHeight, barWidth, barHeight);
var barText = row['barDimension'][0];
var textX = barX + barWidth / 4;
var textY = maxBarHeight + textYOffset;
ctx.fillText(barText, textX, textY);
});
}
// subscribe to data and style changes.
dscc.subscribeToData(drawViz);
What I would like to do is to use Java Script examples of diagrams, sun burst diagrams e.g. Unfortunately i have no experience in Java Script. Is it possible to implement code like this: https://github.com/vasturiano/sunburst-chart/blob/master/src/sunburst.js into my myVizSource.js in a easy way?
It is possible to implement a wide variety of charts, including sunburst charts, using community visualizations. However, the feature as it stands right now is intended to help those who are familiar with JavaScript and visualization code to integrate that code into a Data Studio dashboard. The ease of implementing the visualization will depend a lot on the visualization library you choose to use.
For a project I made something in chartjs that looked something to this: https://jsfiddle.net/ethernetz/e50fn31m/2/
I had to do some digging around on the internet to get a number to show up in the middle of the doughnut graph, but that was exactly what I wanted. Then I wanted to make a second doughnut graph, which made the project looks something like this: https://jsfiddle.net/ethernetz/4uw1ksu1/
As you can see, the "60" from the completion graph shows up on top of the "40" from the incompletion graph and vice versa.
I suspect it has to do with me never specifying what graph I want to edit here:
Chart.pluginService.register({
beforeDraw: function(chart) {
var width = chart.chart.width,
height = chart.chart.height,
ctx = chart.chart.ctx;
...but I don't know how to fix it. Any help would be appreciated.
Change the following line of code in your plugin :
var text = 60;
to this :
var text = chart.id == 0 ? 60 : 40;
basically, when a chart is created, it is assigned an id (0 based). so you need to set the text based on that chart-id.
also, thereĀ's no need to add two separate plugins, as you are creating a global plugin, which will be applied to all of your charts.
Here is the working example on JSFiddle
use only one "chart.pluginService.register" for all charts, because it subscribes to the chart class, so mychart and mychart2 belong to chart class, then don't use the callback "chart"... use mychart and mychart2 instead of callback to recognize each chart registered.
new code:
var charts = [{
current: myChart
, text: 60
}, {
current: myChart2
, text: 40
}];
Chart.pluginService.register({
beforeDraw: function(chart) {
for (var iterator of charts) {
var width = iterator.current.chart.width,
height = iterator.current.chart.height,
ctx = iterator.current.chart.ctx;
//ctx.clearRect(0, 0, width, height);
//ctx.restore(); dont clear, this delete the previous chart, drawing only text
var fontSize = (height / 114).toFixed(2);
ctx.font = fontSize + "em lato";
ctx.fillStyle = "rgba(0,0,0, 0.85)"
ctx.textBaseline = "middle";
var text = iterator.text,
textX = Math.round((width - ctx.measureText(text).width) / 2),
textY = height / 2.5;
ctx.fillText(text, textX, textY);
ctx.save();
}
}
});
updated jsfiddle: https://jsfiddle.net/4uw1ksu1/2/
I'm trying to make a data visualization through a circular diagram. The data is being pulled out of my database and in to an associative array. The Object keys in this case are addresses and the values are numbers (how many times they exist in my database). This is the short version of my code:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var s = 0;
//var t = total sum of values
var l = Object.keys(arr);
for (var i=0;i<l.length;i++){
var e = Object.values(arr)[i]/t;
var perc = 2*Math.PI*e;
ctx.beginPath();
ctx.moveTo(canvas.width / 2, canvas.height / 2);
ctx.arc(canvas.width/2,canvas.height/2,canvas.height/2,s,s + perc,false);
ctx.lineTo(canvas.width/2,canvas.height/2);
ctx.stroke();
s += perc;
}
This is the current result:
picture
As you can see it's not a round circle as it's supposed to be.
I hope someone can help me.
UPDATE
So the strangest thing happened. Apparently there is a difference between the height and width on the canvas set by css and those who's set by javascript. I just gave my canvas canvas.width=400 and canvas.height=400 in javascript and deleted my css height=400px and width=400px. All of a sudden the circle is how it's supposed to be. Very, very strange.
I want to draw vertical lines at points on the x axis in dygraphs.
They should:
Span the entire y axis automatically, but not prevent other series from being automatically zoomed in on the y axis when manually zoomed to a range of the x axis
Be completely vertical
have no horizontal lines joining them
In that sense, a lot like having multiple extra axis lines drawn at random points.
But it would be helpful if they have the same features of regular series plots in that when it is hovered over, a label displays its value along the x axis.
In case it matters, they will be plotted on the same graph as other series lines, and may or may not have common x axis values with those series.
How might it be achieved?
A way to draw vertical lines, is to use the underlayCallback. It allows you to draw the background of the graph.
Here is a sample that draw 3 vertical lines at X=100, X=200 and X=500 :
<script src="https://cdnjs.cloudflare.com/ajax/libs/dygraph/1.1.1/dygraph-combined.js"></script>
<div id="div_g" style="width:400px; height:200px;"></div>
<script>
// A basic sinusoidal data series.
var data = [];
for (var i = 0; i < 1000; i++) {
var base = 10 * Math.sin(i / 90.0);
data.push([i, base]);
}
new Dygraph(
document.getElementById("div_g"),
data, {
labels: ['X', 'Y'],
underlayCallback: function(canvas, area, g) {
canvas.strokeStyle = 'red';
var lines = [100, 200, 500];
for (var idx = 0; idx < lines.length; idx++) {
var canvasx = g.toDomXCoord(lines[idx]);
var range = g.yAxisRange();
canvas.beginPath();
canvas.moveTo(canvasx, g.toDomYCoord(range[0]));
canvas.lineTo(canvasx, g.toDomYCoord(range[1]));
canvas.stroke();
canvas.closePath();
}
}
}
);
</script>
We are using Chartjs to plot the charts ,However there is no to give the x-axis titles,There is a solution for y-Axis title in here , But for x-Axis I could add the x axis name but could not create the space below the chart to properly place it , using y as this.chart.height overlapped the text with x axis title.
I have looked the chartjs v2.0 but it also does not have support for x-Axis title.
We set the height of the chart depending on how much height we want for the x axis label and then write in that space.
We don't have to do anything in the draw override because the canvas clearing too happens based on the height (that we adjusted)
Preview
Script
Chart.types.Line.extend({
name: "LineAlt",
initialize: function (data) {
this.chart.height -= 30;
Chart.types.Line.prototype.initialize.apply(this, arguments);
var ctx = this.chart.ctx;
ctx.save();
// text alignment and color
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
ctx.fillStyle = this.options.scaleFontColor;
// position
var x = this.chart.width / 2;
var y = this.chart.height + 15 + 5;
// change origin
ctx.translate(x, y)
ctx.fillText("My x axis label", 0, 0);
ctx.restore();
}
});
and then
...
new Chart(ctx).LineAlt(data);
Fiddle - http://jsfiddle.net/ct2h2wde/