javascript - D3 json() 函数适用于本地文件,但不适用于将本地 var 设置为 json
问题描述
Script.js 在我引用本地 json 文件时有效,但在我将该文件的内容放入变量时无效。
脚本.js:
function getDataset(value,label)
{
return{
label:value,
value:label
}
}
var json_obj = {
"1":
{
"1":
{
"labels": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "", "", "", "", "", "", "", ""],
"name": "Jacob",
"values": [86, 58, 58, 46, 48, 44, 0, 0, 0, 0, 0, 0, 340, 340, 340, 340, 340, 340, 340, 340]
},
"2":
{
"labels": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "", "", "", "", "", "", "", ""],
"name": "Janis",
"values": [276, 250, 248, 233, 149, 120, 112, 106, 125, 134, 96, 0, 1849, 1849, 1849, 1849, 1849, 1849, 1849, 1849]
},
"3":
{
"labels": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "", "", "", "", "", "", "", ""],
"name": "Mohammad",
"values": [111, 55, 74, 55, 42, 51, 60, 63, 60, 61, 48, 0, 680, 680, 680, 680, 680, 680, 680, 680]
}
},
"2":
{
"1":
{
"labels": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
"name": "2008",
"values": [11333.06, 12476.72, 10319.53, 10283.78, 9857.24, 9198.09, 9089.79, 8770.44, 8240.04, 6783.54, 6597.54, 9830.54]
},
"2":
{
"labels": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
"name": "2009",
"values": [7086.21, 8022.06, 2474.26, 14907.01, 9637.66, 11529.76, 11589.86, 11380.71, 8237.84, 10080.07, 8753.17, 8009.95]
},
"3":
{
"labels": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
"name": "2010",
"values": [9722.98, 10299.76, 10078.96, 10125.91, 10692.61, 8723.51, 8842.07, 13039.03, 17556.39, 19951.38, 24566.54, 23093.74]
}
}
};
var json_string = JSON.stringify(json_obj);
console.log(json_string);
function pieChart() {
d3.json("data.json",function (json) {
let years = [];
for (let i = 1; i <= Object.keys(json[2]).length; i++) {
years.push(getDataset(json[2][i].name, (json[2][i]['values'].reduce((a, b) => a + b, 0))));
}
var width = 1000;
var height = 800;
// a circle chart needs a radius
var radius = Math.min(width, height) / 2.5;
// legend dimensions
var legendRectSize = 25; // defines the size of the colored squares in legend
var legendSpacing = 6; // defines spacing between squares
// define color scale
var color = d3.scale.category20();
var svg = d3.select('#pie_chart') // select element in the DOM with id 'chart'
.append('svg').attr('filter','url(#f3)') // append an svg element to the element we've selected
.attr('width', width) // set the width of the svg element we just added
.attr('height', height) // set the height of the svg element we just added
.append('g') // append 'g' element to the svg element
.attr('transform', 'translate(' + ((width / 2)-180) + ',' + (height / 2) + ')'); // our reference is now to the 'g' element. centerting the 'g' element to the svg element
var arc = d3.svg.arc()
.innerRadius(0) // none for pie chart
.outerRadius(radius); // size of overall chart
var pie = d3.layout.pie() // start and end angles of the segments
.value(function(d) { return d.value; }) // how to extract the numerical data from each entry in our dataset
.sort(null); // by default, data sorts in oescending value. this will mess with our animation so we set it to null
var path = svg.selectAll('path') // select all path elements inside the svg. specifically the 'g' element. they don't exist yet but they will be created below
.data(pie(years)) //associate dataset wit he path elements we're about to create. must pass through the pie function. it magically knows how to extract values and bakes it into the pie
.enter() //creates placeholder nodes for each of the values
.append('path') // replace placeholders with path elements
.attr('d', arc) // define d attribute with arc function above
.attr('fill', function(d) { return color(d.data.label); }).style('stroke','white') // use color scale to define fill of each label in dataset
.each(function(d) { this._current - d; }); // creates a smooth animation for each track
var labelArc = d3.svg.arc()
.outerRadius(radius+151)
.innerRadius(0);
var labelArc1 = d3.svg.arc()
.outerRadius(radius+351)
.innerRadius(0);
svg
.selectAll('mySlices')
.data(pie(years))
.enter()
.append('text').attr('class',function(d){return d.value}).attr('class','textn')
.text(function(d){ return (Math.floor(d.data.value))})
.attr("transform", function(d) { return (d.data.value>0? "translate(" + labelArc.centroid(d) + ")" : "translate(" + labelArc1.centroid(d) + ")"); })
.style("text-anchor", "middle")
.style("font-size", 15).style('fill',function(d){return (d.data.value>0? "white" : "black")});
// define legend
var legend = svg.selectAll('.legend') // selecting elements with class 'legend'
.data(color.domain()) // refers to an array of labels from our dataset
.enter() // creates placeholder
.append('g') // replace placeholders with g elements
.attr('class', 'legend') // each g is given a legend class
.attr('transform', function(d, i) {
var height = legendRectSize + legendSpacing; // height of element is the height of the colored square plus the spacing
var offset = height * color.domain().length / 2; // vertical offset of the entire legend = height of a single element & half the total number of elements
var horz = 15 * legendRectSize; // the legend is shifted to the left to make room for the text
var vert = i * height - offset; // the top of the element is hifted up or down from the center using the offset defiend earlier and the index of the current element 'i'
return 'translate(' + horz + ',' + vert + ')'; //return translation
});
// adding colored squares to legend
legend.append('rect') // append rectangle squares to legend
.attr('width', legendRectSize) // width of rect size is defined above
.attr('height', legendRectSize) // height of rect size is defined above
.style('fill', color) // each fill is passed a color
.style('stroke', color); // each stroke is passed a color
// adding text to legend
legend.append('text')
.attr('x', legendRectSize + legendSpacing)
.attr('y', legendRectSize - legendSpacing)
.text(function(d) { return d; });
});
}
当我用 json_obj 或 json_string 替换“data.json”时,出现错误:
Uncaught TypeError: Cannot read property '2' of null
这是在不同的应用程序中使用 javascipt 的垫脚石,所以如果可能的话,我希望 json 直接位于 javascript 文件中。可能吗?如果是这样,我应该如何格式化它?
解决方案
推荐阅读
- python - 如何使用 OpenCV 同时从连接到 Raspberry Pi 3 的两个 USB 摄像头捕获和保存图像?
- flutter - 颤振中的问题。Firebase 上一个版本和上一个版本身份验证之间的冲突
- express - 无法在 Express 中使用 Mongoose 连接到 MongoDB Atlas
- angular - 提供角度构建时出现非法状态问题中的错误
- python - 如何显示另一个窗口
- python - 如何在字符串匹配期间捕获所有特殊字符?
- ios - 如何在 Cordova for iOS 中本地化应用程序名称?
- javascript - 如何设置自定义控件的样式以显示在原生 html5 视频控件旁边
- c++ - C ++计算树结构中的对象数量
- reactjs - 加载数据时显示加载程序图标