this code is showing error in jade - javascript

This Jade code isn't working.
head
script(src='http://d3js.org/d3.v3.min.js')
script(src='http://dimplejs.org/dist/dimple.v2.1.0.min.js')
body
script(type='text/javascript')
var svg = dimple.newSvg("body", 800, 600);
var data = [
{ "Word":"Hello", "Awesomeness":2000 },
{ "Word":"World", "Awesomeness":3000 }
];
var chart = new dimple.chart(svg, data);
chart.addCategoryAxis("x", "Word");
chart.addMeasureAxis("y", "Awesomeness");
chart.addSeries(null, dimple.plot.bar);
chart.draw();

As of version 1.0.0 of Jade, you must include a . to make script tags be text:
body
script(type='text/javascript').
// above here
var svg = dimple.newSvg("body", 800, 600);
var data = [
{ "Word":"Hello", "Awesomeness":2000 },
{ "Word":"World", "Awesomeness":3000 }
];
var chart = new dimple.chart(svg, data);
chart.addCategoryAxis("x", "Word");
chart.addMeasureAxis("y", "Awesomeness");
chart.addSeries(null, dimple.plot.bar);
chart.draw();

Related

Javascript / amcharts - dynamically control property value of amcharts

I am trying to mildly replicate what amcharts has done to their demo chart in this link ie. adding controls to change the graph's property. But I can't figure out how the value updating works in javascript. Here is my code:
HTML:
<body>
...
<div id="chartdiv" style="width=100%; height:400px;"></div>
<input type="range" min="0.1" max="1.0" value="0.5" step="0.01" id="mySlider">
...
</body>
Javascript/amCharts:
<script>
// data for amCharts
var chartData = [ {
"country": "USA",
"visits": 4252
}, {
"country": "China",
"visits": 1882
}];
// drawing amCharts using object-based method
AmCharts.ready( function() {
//var chart = AmCharts.makeChart("chartdiv");
var chart = new AmCharts.AmSerialChart();
chart.dataProvider = chartData;
chart.categoryField = "country";
var graph = new AmCharts.AmGraph();
graph.valueField = "visits";
graph.type = "column";
graph.fillAlphas = updateValue();
chart.addGraph( graph );
chart.write("chartdiv")
});
// here is my function to update value dynamically
function updateValue() {
val = document.getElementById("mySlider").value;
return val;
}
</script>
I want to update the opacity of the graph dynamically. How do I do that? This should be simple but I am quite new in javascript development.
EDIT: Updating with the final code which works
Javascript/amCharts:
<script>
...
// drawing amCharts using object-based method
AmCharts.ready( function() {
//var chart = AmCharts.makeChart("chartdiv");
var chart = new AmCharts.AmSerialChart();
chart.dataProvider = chartData;
chart.categoryField = "country";
var graph = new AmCharts.AmGraph();
graph.valueField = "visits";
graph.type = "column";
graph.fillAlphas = updateValue();
chart.addGraph( graph );
chart.write("chartdiv");
//add this code to add dynamic opacity control
//** "jquery.js" script needs to be linked **//
$('#mySlider').on('input change', function() {
//var target = chart;
//chart.startDuration = 0;
var target = chart.graphs[0]
target['fillAlphas'] = this.value;
chart.validateNow();
});
});
...
</script>
Try this code on change event of your input
jQuery('#mySlider').off().on('input change', function() {
var target = chart;
chart.startDuration = 0;
target = chart.graphs[0];
target['fillAlphas'] = this.value;
chart.validateNow();
});

Adding annotations to Google candlestick chart (Posted solution triggers TypeError)

I am trying to add some annotations to a Google Candlestick chart. I noticed someone had already asked this same question (Adding annotations to Google Candlestick chart). The user Aperçu replied with a detailed solution to extend the chart and add annotations since the chart doesn't have any such feature built in. However, when I try this solution I get an error "TypeError: document.querySelectorAll(...)[0] is undefined"
Here is my code:
chartPoints = [
['Budget', 0, 0, 9999, 9999, 'foo1'],
['Sales', 0, 0, 123, 123, 'foo2'],
['Backlog', 123, 123, 456, 456, 'foo3'],
['Hard Forecast', 456, 456, 789, 789, 'foo4'],
['Sales to Budget', 789, 789, 1000, 1000, 'foo5']
];
var data = google.visualization.arrayToDataTable(chartPoints, true);
data.setColumnProperty(5, 'role', 'annotation');
var options = {
legend: 'none',
bar: { groupWidth: '40%', width: '100%' },
candlestick: {
fallingColor: { strokeWidth: 0, fill: '#a52714' },
risingColor: { strokeWidth: 0, fill: '#0f9d58' }
}
};
var chart = new google.visualization.CandlestickChart(document.getElementById('chart_div'));
chart.draw(data, options);
// attempt to use Aperçu's solution
const bars = document.querySelectorAll('#chart_div svg > g:nth-child(5) > g')[0].lastChild.children // this triggers a TypeError
for (var i = 0 ; i < bars.length ; i++) {
const bar = bars[i]
const { top, left, width } = bar.getBoundingClientRect()
const hint = document.createElement('div')
hint.style.top = top + 'px'
hint.style.left = left + width + 5 + 'px'
hint.classList.add('hint')
hint.innerText = rawData.filter(t => t[1])[i][0]
document.getElementById('chart_div').append(hint)
}
I want the chart to show the last piece of data next to the bars (i.e. "foo1", "foo2", etc)
each candle or bar will be represented by a <rect> element
we can use the rise and fall colors to separate the bars from other <rect> elements in the chart
there will be the same number of bars as rows in the data table
once we find the first bar, we can use rowIndex of zero to pull values from the data
we need to find the value of the rise / fall, to know where to place the annotation
then use chart methods to find the location for the annotation
getChartLayoutInterface() - Returns an object containing information about the onscreen placement of the chart and its elements.
getYLocation(position, optional_axis_index) - Returns the screen y-coordinate of position relative to the chart's container.
see following working snippet
two annotations are added
one for the difference in rise and fall
and the other for the value in the column with annotation role
google.charts.load('current', {
callback: drawChart,
packages: ['corechart']
});
function drawChart() {
var chartPoints = [
['Budget', 0, 0, 9999, 9999, 'foo1'],
['Sales', 0, 0, 123, 123, 'foo2'],
['Backlog', 123, 123, 456, 456, 'foo3'],
['Hard Forecast', 456, 456, 789, 789, 'foo4'],
['Sales to Budget', 789, 789, 1000, 1000, 'foo5']
];
var data = google.visualization.arrayToDataTable(chartPoints, true);
data.setColumnProperty(5, 'role', 'annotation');
var options = {
legend: 'none',
bar: { groupWidth: '40%', width: '100%' },
candlestick: {
fallingColor: { strokeWidth: 0, fill: '#a52714' },
risingColor: { strokeWidth: 0, fill: '#0f9d58' }
}
};
var container = document.getElementById('chart_div');
var chart = new google.visualization.CandlestickChart(container);
google.visualization.events.addListener(chart, 'ready', function () {
var annotation;
var bars;
var chartLayout;
var formatNumber;
var positionY;
var positionX;
var rowBalance;
var rowBottom;
var rowIndex;
var rowTop;
var rowValue;
var rowWidth;
chartLayout = chart.getChartLayoutInterface();
rowIndex = 0;
formatNumber = new google.visualization.NumberFormat({
pattern: '#,##0'
});
bars = container.getElementsByTagName('rect');
for (var i = 0; i < bars.length; i++) {
switch (bars[i].getAttribute('fill')) {
case '#a52714':
case '#0f9d58':
rowWidth = parseFloat(bars[i].getAttribute('width'));
if (rowWidth > 2) {
rowBottom = data.getValue(rowIndex, 1);
rowTop = data.getValue(rowIndex, 3);
rowValue = rowTop - rowBottom;
rowBalance = Math.max(rowBottom, rowTop);
positionY = chartLayout.getYLocation(rowBalance) - 6;
positionX = parseFloat(bars[i].getAttribute('x'));
// row value
annotation = container.getElementsByTagName('svg')[0].appendChild(container.getElementsByTagName('text')[0].cloneNode(true));
annotation.textContent = formatNumber.formatValue(rowValue);
annotation.setAttribute('x', (positionX + (rowWidth / 2)));
annotation.setAttribute('y', positionY);
annotation.setAttribute('font-weight', 'bold');
// annotation column
annotation = container.getElementsByTagName('svg')[0].appendChild(container.getElementsByTagName('text')[0].cloneNode(true));
annotation.textContent = data.getValue(rowIndex, 5);
annotation.setAttribute('x', (positionX + (rowWidth / 2)));
annotation.setAttribute('y', positionY - 18);
annotation.setAttribute('font-weight', 'bold');
rowIndex++;
}
break;
}
}
});
chart.draw(data, options);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Representing 2 or more dimple.js charts

Im a noob and currently I'm practicing with dimple.js.
The problem I'm facing is that I can't represent 2 charts side by side on the same page, it just appears one chart. How can I fix this?
I named each div with two different ID and also considered this on the script.
<body>
<section>
<div id="chartContainer1" class="container">
<script type="text/javascript">
var svg = dimple.newSvg("#chartContainer1", 590, 400);
d3.tsv("/data/example_data.tsv", function (data) {
data = dimple.filterData(data, "Owner", ["Aperture", "Black Mesa"])
var myChart = new dimple.chart(svg, data);
myChart.setBounds(60, 30, 505, 305);
var x = myChart.addCategoryAxis("x", "Month");
x.addOrderRule("Date");
myChart.addMeasureAxis("y", "Unit Sales");
var s = myChart.addSeries("Channel", dimple.plot.line);
s.interpolation = "cardinal";
myChart.addLegend(60, 10, 500, 20, "right");
myChart.draw();
});
</script>
</div>
<div id="chartContainer2" class="container">
<script type="text/javascript">
var svg = dimple.newSvg("#chartContainer2", 590, 400);
d3.tsv("/data/example_data.tsv", function (data) {
data = dimple.filterData(data, "Owner", ["Aperture", "Black Mesa"])
var myChart = new dimple.chart(svg, data);
myChart.setBounds(60, 30, 505, 305);
var x = myChart.addCategoryAxis("x", "Month");
x.addOrderRule("Date");
myChart.addMeasureAxis("y", "Unit Sales");
var s = myChart.addSeries("Channel", dimple.plot.line);
s.interpolation = "cardinal";
myChart.addLegend(60, 10, 500, 20, "right");
myChart.draw();
});
</script>
</div>
</section>
EDIT: I cleaned up the code to help make it more maintainable for you going down the road.
http://jsfiddle.net/gv615hcL/
--
So the problem is in the variable naming. You're overriding your variables. In the second declaration you want to change the names of the new dimple svg, for example instead of naming it:
var svg = dimple.newSvg("#chartContainer2", 590, 400);
name it:
var svg2 = dimple.newSvg("#chartContainer2", 590, 400);
Also, make sure you continue to reference the variables properly.
I made a quick JsFiddle for you here: http://jsfiddle.net/fq4p7t2x/

How to make axis ticks clickable in d3.js/dimple.js

I'm very new to d3js. I wish to know how to make axis tick labels to clickable so that clicking on the labels I can load new charts( yes I need to get the axis value, ie month name here in my case)
Below is the code. X axis are months and once I click on a month, I need to load chart of that month, which is another HTML page.
d3.csv("data/data_1.CSV", function (data) {
var myChart = new dimple.chart(svg, data);
myChart.setBounds(90, 70, 490, 320);
var x = myChart.addTimeAxis("x", "Month", "%d-%b-%Y %H:%M:%S", “%b-%Y");
var y = myChart.addMeasureAxis("y","Value");
x.overrideMin = new Date("2013-11-30");
var s = myChart.addSeries("Value type", dimple.plot.line);
s.lineMarkers = true;
myChart.addLegend(180, 30, 360, 20, "left");
myChart.draw();
});
I don't know anything about dimple.js, but in d3 you can just select all of the tick marks and attach a click handler to them.
svg.selectAll('.tick')
.on('click', function(d) { console.log(d); });
This will write the Date object that the tick represents to the console.
This will autoplay all months, and log x-Axis value on click.
d3.csv("data/data_1.CSV", function (data) {
var myChart = new dimple.chart(svg, data);
myChart.setBounds(90, 70, 490, 320);
var x = myChart.addTimeAxis("x", "Month", "%d-%b-%Y %H:%M:%S", "%b-%Y");
x.overrideMin = new Date("2013-01-01");
x.addOrderRule("Date");
var y = myChart.addMeasureAxis("y","Value");
var s = myChart.addSeries("Value type", dimple.plot.line);
s.lineMarkers = true;
myChart.addLegend(180, 30, 360, 20, "left");
s.addEventHandler("click", function (e) {
console.log(e.xValue);
});
var myStoryboard = myChart.setStoryboard("Month");
myStoryboard.frameDuration = 15000;
myStoryboard.autoplay = true;
myChart.draw();
});

dimple js straight line y-axis over bar chart

I am trying to draw Average, High and Low value straight line on a dimple js bar chart. I have no clue how they can be drawn on y-axis (cost) as straight line that will cut through the bars. Here is the fiddle that has high, low and average values saved into corresponding variable that needed to be drawnon the chart. Any solution? jsfiddle link: http://jsfiddle.net/Ra2xS/14/
var dim = {"width":590,"height":450}; //chart container width
var data = [{"date":"01-02-2010","cost":"11.415679194952766"},{"date":"01-03-2010","cost":"10.81875691467018"},{"date":"01-04-2010","cost":"12.710197879070897"}];
//y- axis (cost) values to plot as straight line over bar chart in different colours
var avg = "11.65";
var high= "12.71";
var low = "10.82";
function barplot(id,dim,data)
{
keys = Object.keys(data[0]);
var xcord = keys[0];
var ycord = keys[1];
var svg = dimple.newSvg(id, dim.width, dim.height);
var myChart = new dimple.chart(svg,data);
myChart.setBounds(60, 30, 505, 305);
var x = myChart.addCategoryAxis("x", xcord);
x.addOrderRule(xcord);
x.showGridlines = true;
var y = myChart.addMeasureAxis("y", ycord);
y.showGridlines = true;
y.tickFormat = ',.1f';
var s = myChart.addSeries(null, dimple.plot.bar);
var s1 = myChart.addSeries(null, dimple.plot.line);
s1.lineWeight = 3;
s1.lineMarkers = true;
myChart.draw(1500);
}
barplot("body",dim,data);
You can do it by adding a separate series with it's own data, unfortunately there's a bug with multiple line series in version 1.1.5 which means line markers go haywire (so I've removed them from the code below). The good news is I've just finished rewriting all the line chart code and this problem will be fixed in the next version (coming in a week or so), also the line will animate properly by rising from the x axis instead of fading in from black.
var dim = {"width":590,"height":450}; //chart container width
var data = [{"date":"01-02-2010","cost":"11.415679194952766"},{"date":"01-03-2010","cost":"10.81875691467018"},{"date":"01-04-2010","cost":"12.710197879070897"}];
function barplot(id,dim,data)
{
keys = Object.keys(data[0]);
var xcord = keys[0];
var ycord = keys[1];
var svg = dimple.newSvg(id, dim.width, dim.height);
var parser = d3.time.format("%d-%m-%Y")
var dateReader = function (d) { return parser.parse(d[xcord]); }
var start = d3.time.month.offset(d3.min(data, dateReader), -1);
var end = d3.time.month.offset(d3.max(data, dateReader), 1);
var myChart = new dimple.chart(svg,data);
myChart.setBounds(60, 30, 505, 305);
//var x = myChart.addCategoryAxis("x", xcord);
var x = myChart.addTimeAxis("x", xcord, "%d-%m-%Y","%b %Y");
x.overrideMin = start;
x.overrideMax = end;
x.addOrderRule(xcord);
x.showGridlines = true;
x.timePeriod = d3.time.months;
x.floatingBarWidth = 100;
var y = myChart.addMeasureAxis("y", ycord);
y.showGridlines = true;
y.tickFormat = ',.1f';
var s1 = myChart.addSeries(null, dimple.plot.bar);
var s2 = myChart.addSeries(null, dimple.plot.line);
s2.lineWeight = 3;
var s3 = myChart.addSeries("Price Break", dimple.plot.line);
s3.data = [
{ "Price Break" : "high", "cost" : 12.71, "date" : parser(start) },
{ "Price Break" : "high", "cost" : 12.71, "date" : parser(end) },
{ "Price Break" : "avg", "cost" : 11.65, "date" : parser(start) },
{ "Price Break" : "avg", "cost" : 11.65, "date" : parser(end) },
{ "Price Break" : "low", "cost" : 10.82, "date" : parser(start) },
{ "Price Break" : "low", "cost" : 10.82, "date" : parser(end) }
];
myChart.draw(1500);
}
barplot("body",dim,data);
http://jsfiddle.net/Ra2xS/28/

Categories