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/
Related
I generate a map with echarts.
I'm able to pickup 0 values to colorize them in gray using visualMap property combined with inRange min, max, outOfRange options.
The wanted result is almost there (see the screenshots) !
But I'd like to display elements with 0 values with stripes / pattern - now in gray on the screenshot. How can I achieve this with echarts ?
Example of wanted pattern :
I had a look on following documentation - and tried some code with no success :
https://echarts.apache.org/en/option.html#visualMap
https://echarts.apache.org/en/option.html#aria.decal
https://echarts.apache.org/examples/en/editor.html?c=pie-pattern
My visualMap configuration part is as follow :
visualMap : {
type: 'continuous',
left : 'right',
top : 'center',
min : 469,
max : 144464,
inRange : {
color : colors
},
outOfRange: {
color:'#f4f4f4'
},
text : [ 'Haute', 'Faible' ],
calculable : true
},
Additional need : I'd also be happy to be able to see outOfRange in legend.
(also reported here : https://github.com/apache/echarts/issues/14874)
In order to use a pattern fill you need to use a canvas object as a color source. Here is a code example I use to create dynamic, two-colored, striped patterns:
function DashedPattern(color1, color2, canvasId) {
var c = document.createElement('canvas');
c.id = canvasId;
c.width = 120;
c.height = 120;
c.style.border = "0px none";
c.hidden = "true";
var body = document.getElementsByTagName("body")[0];
body.appendChild(c);
var ctx = c.getContext("2d");
ctx.strokeStyle = color1;
ctx.fillStyle = color2;
ctx.lineWidth = "2";
var patternSpread = 5;
ctx.beginPath();
for (i = 1; i <= c.width / patternSpread; i++) {
ctx.moveTo(i * patternSpread, 0);
ctx.lineTo(0, i * patternSpread);
}
for (i = 1; i < c.height / patternSpread; i++) {
ctx.moveTo(c.width, i * patternSpread);
ctx.lineTo(i * patternSpread, c.height);
}
ctx.fillRect(0, 0, c.width, c.height);
ctx.stroke();
return c;
}
var c = DashedPattern(p.itemStyle.areaColor, p.itemStyle.secondColor, patternId);
var newColor = { image: c, repeat: 'repeat' };
p.itemStyle.areaColor = newColor;
Of course, if you only use pre-defined static patterns you can just create pattern images and load them into canvas instead of dynamic generation.
The drawback of patterns in echarts is that they are bitmaps and don't look as nice as the rest of the map.
Here is the example of the map I have using patterns:
As you can see the stripes align nicely between areas but when zoomed in the bitmap edginess is clearly visible. Probably this can be reduced by playing with pattern size.
Actually version 5.0+ of echart implement decal feature.
We borrowed the concept of decal from computer graphics to avoid confusing with pattern, which ECharts already used. The difference between a decal and a pattern in ECharts is that, a decal is a parametric configuration that generates repeating images while a pattern takes an image to repeat.
More information and samples regarding this new feature on following links :
https://github.com/apache/echarts/issues/13263
https://echarts.apache.org/examples/en/editor.html?c=doc-example/aria-decal
https://echarts.apache.org/en/option.html#series-bar.itemStyle.decal
Because decal feature does not rely on image there is no pixel effect, unlike using pattern !
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.
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/
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.
I need to draw vertical and horizontal rectangle / bands (like in Gantt charts) on the HTML 5 / JavaScript Tee charts.
I could draw a rectangle using the Bar series as below but I want the rectangle to float on a particular XY cor-ordinate rather standing from the x axis.
var series1 = new Tee.Bar();
series1.data.values = [30000];
//alert(" openValues[y] "+ openValues[y] + " closeValues[y] "+ closeValues[y] );
series1.data.x = [ (openValues[y] + closeValues[y]) /2 ];
series1.format.shadow.visible = false;
series1.format.lineCap = "round";
series1.format.stroke.fill = "#D3D3D3";
series1.format.stroke.size = .5;
series1.colorEach = "auto";
series1.format.join = "round";
series1.format.cap = "square";
series1.format.fill="#F8F8FF";
series1.barSize=100000;
//series1.format.transparent =1;
series1.color = "silver";
series1.marks.visible = false;
//series1.hover.shadow =false;
series1.hover.stroke.size =.01;
Chart1.addSeries(series1);
Is it possible to just draw a rectangle using HTML 5 / Javascript Teecharts. I want to to draw rectangles like in gantt chart with specific x1,y1,x2 and y2 values.
I tried using the Format Object in Teecharts but it didn't help
Chart1.panel.format.rectPath(20,20,30,40);
To draw simple rectangle using html5...
window.onload = function() {
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.beginPath();
context.rect(188, 50, 200, 100);
context.fillStyle = '#8ED6FF';
context.fill();
context.lineWidth = 5;
context.strokeStyle = 'black';
context.stroke();
};
here is example link for gantt chart using html5
http://www.eecg.toronto.edu/~brousse1/Libraries/RGraph/docs/gantt.html
The next TeeChart Javascript v1.1 will incude the Gantt Series. Here it is the demo:
http://www.steema.us/files/jscript/demos/series/gantt/gantt.htm
We'll be glad to hear any comment about it.
Steema Support Central