我正在尝试将json加载到我的d3.js图表中。我首先尝试使用静态硬编码的虚拟json(freqData)工作正常,但是当我尝试从URL(freqData2)重现json时,图表不会被创建,因为它无法读取我的json。我看到结构或变量名称没有差异。
你可以看看这个jsfiddle(不要注意图表本身,它在我的jsfiddle中有点乱,但在我的真实代码中它可以正确使用正确的数据)。 https://jsfiddle.net/liostse/yfw3zgdL/2/
function dashboard(id, fData) { /*Creating dashboard for priorities*/
var barColor = 'steelblue';
function segColor(c) {
return {
P2: "#807dba",
P3: "#e08214",
P4: "#41ab5d",
P5: "#1dc609",
P6: "#f7f322"
}[c];
}
// compute total for each state.
fData.forEach(function(d) {
console.log(d.freq.P2);
d.total = d.freq.P2 + d.freq.P3 + d.freq.P4 + d.freq.P5 + d.freq.P6;
console.log(d.total);
});
// function to handle histogram.
function histoGram(fD) {
var hG = {},
hGDim = {
t: 30,
r: 30,
b: 20,
l: 50
};
hGDim.w = 600 - hGDim.l - hGDim.r,
hGDim.h = 300 - hGDim.t - hGDim.b;
//create svg for histogram.
var hGsvg = d3.select(id).append("svg")
.attr("width", hGDim.w + hGDim.l + hGDim.r)
.attr("height", hGDim.h + hGDim.t + hGDim.b).append("g")
.attr("transform", "translate(" + hGDim.l + "," + hGDim.t + ")");
// create function for x-axis mapping.
var x = d3.scale.ordinal().rangeRoundBands([0, hGDim.w], 0.1)
.domain(fD.map(function(d) {
return d[0];
}));
// Add x-axis to the histogram svg.
hGsvg.append("g").attr("class", "x axis")
.attr("transform", "translate(0," + hGDim.h + ")")
.call(d3.svg.axis().scale(x).orient("bottom"));
// Create function for y-axis map.
var y = d3.scale.linear().range([hGDim.h, 0])
.domain([0, d3.max(fD, function(d) {
return d[1];
})]);
// Create bars for histogram to contain rectangles and freq labels.
var bars = hGsvg.selectAll(".bar").data(fD).enter()
.append("g").attr("class", "bar");
//create the rectangles.
bars.append("rect")
.attr("x", function(d) {
return x(d[0]);
})
.attr("y", function(d) {
return y(d[1]);
})
.attr("width", x.rangeBand())
.attr("height", function(d) {
return hGDim.h - y(d[1]);
})
.attr('fill', barColor)
.on("mouseover", mouseover) // mouseover is defined below.
.on("mouseout", mouseout); // mouseout is defined below.
//Create the frequency labels above the rectangles.
bars.append("text").text(function(d) {
return d3.format(",")(d[1])
})
.attr("x", function(d) {
return x(d[0]) + x.rangeBand() / 2;
})
.attr("y", function(d) {
return y(d[1]) - 5;
})
.attr("text-anchor", "middle");
function mouseover(d) { // utility function to be called on mouseover.
// filter for selected state.
var st = fData.filter(function(s) {
return s.State == d[0];
})[0],
nD = d3.keys(st.freq).map(function(s) {
return {
type: s,
freq: st.freq[s]
};
});
// call update functions of pie-chart and legend.
pC.update(nD);
leg.update(nD);
}
function mouseout(d) { // utility function to be called on mouseout.
// reset the pie-chart and legend.
pC.update(tF);
leg.update(tF);
}
// create function to update the bars. This will be used by pie-chart.
hG.update = function(nD, color) {
// update the domain of the y-axis map to reflect change in frequencies.
y.domain([0, d3.max(nD, function(d) {
return d[1];
})]);
// Attach the new data to the bars.
var bars = hGsvg.selectAll(".bar").data(nD);
// transition the height and color of rectangles.
bars.select("rect").transition().duration(500)
.attr("y", function(d) {
return y(d[1]);
})
.attr("height", function(d) {
return hGDim.h - y(d[1]);
})
.attr("fill", color);
// transition the frequency labels location and change value.
bars.select("text").transition().duration(500)
.text(function(d) {
return d3.format(",")(d[1])
})
.attr("y", function(d) {
return y(d[1]) - 5;
});
}
return hG;
}
// function to handle pieChart.
function pieChart(pD) {
var pC = {},
pieDim = {
w: 250,
h: 250
};
pieDim.r = Math.min(pieDim.w, pieDim.h) / 2;
// create svg for pie chart.
var piesvg = d3.select(id).append("svg")
.attr("width", pieDim.w).attr("height", pieDim.h).append("g")
.attr("transform", "translate(" + pieDim.w / 2 + "," + pieDim.h / 2 + ")");
// create function to draw the arcs of the pie slices.
var arc = d3.svg.arc().outerRadius(pieDim.r - 10).innerRadius(0);
// create a function to compute the pie slice angles.
var pie = d3.layout.pie().sort(null).value(function(d) {
return d.freq;
});
// Draw the pie slices.
piesvg.selectAll("path").data(pie(pD)).enter().append("path").attr("d", arc)
.each(function(d) {
this._current = d;
})
.style("fill", function(d) {
return segColor(d.data.type);
})
.on("mouseover", mouseover).on("mouseout", mouseout);
// create function to update pie-chart. This will be used by histogram.
pC.update = function(nD) {
piesvg.selectAll("path").data(pie(nD)).transition().duration(500)
.attrTween("d", arcTween);
}
// Utility function to be called on mouseover a pie slice.
function mouseover(d) {
// call the update function of histogram with new data.
hG.update(fData.map(function(v) {
return [v.measure_code, v.freq[d.data.type]];
}), segColor(d.data.type));
}
//Utility function to be called on mouseout a pie slice.
function mouseout(d) {
// call the update function of histogram with all data.
hG.update(fData.map(function(v) {
return [v.measure_code, v.total];
}), barColor);
}
// Animating the pie-slice requiring a custom function which specifies
// how the intermediate paths should be drawn.
function arcTween(a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function(t) {
return arc(i(t));
};
}
return pC;
}
// function to handle legend.
function legend(lD) {
var leg = {};
// create table for legend.
var legend = d3.select(id).append("table").attr('class', 'legend');
// create one row per segment.
var tr = legend.append("tbody").selectAll("tr").data(lD).enter().append("tr");
// create the first column for each segment.
tr.append("td").append("svg").attr("width", '16').attr("height", '16').append("rect")
.attr("width", '16').attr("height", '16')
.attr("fill", function(d) {
return segColor(d.type);
});
// create the second column for each segment.
tr.append("td").text(function(d) {
return d.type;
});
// create the third column for each segment.
tr.append("td").attr("class", 'legendFreq')
.text(function(d) {
return d3.format(",")(d.freq);
});
// create the fourth column for each segment.
tr.append("td").attr("class", 'legendPerc')
.text(function(d) {
return getLegend(d, lD);
});
// Utility function to be used to update the legend.
leg.update = function(nD) {
// update the data attached to the row elements.
var l = legend.select("tbody").selectAll("tr").data(nD);
// update the frequencies.
l.select(".legendFreq").text(function(d) {
return d3.format(",")(d.freq);
});
// update the percentage column.
l.select(".legendPerc").text(function(d) {
return getLegend(d, nD);
});
}
function getLegend(d, aD) { // Utility function to compute percentage.
return d3.format("%")(d.freq / d3.sum(aD.map(function(v) {
return v.freq;
})));
}
return leg;
}
// calculate total frequency by segment for all state.
var tF = ['P2', 'P3', 'P4', 'P5', 'P6'].map(function(d) {
return {
type: d,
freq: d3.sum(fData.map(function(t) {
return t.freq[d];
}))
};
});
// calculate total frequency by state for all segment.
var sF = fData.map(function(d) {
return [d.measuer_code, d.total];
});
var hG = histoGram(sF), // create the histogram.
pC = pieChart(tF), // create the pie-chart.
leg = legend(tF); // create the legend.
}
freqData2 = [];
$.getJSON('http://88.99.13.199:3000/dashboarddata', function(mydata) {
mydata.forEach(function(val) {
var freqData1 = {};
freqData1["measure_code"] = val.measure_code;
freqData1["freq"] = {
P2: val.p2,
P3: val.p3,
P4: val.p4,
P5: val.p5,
P6: val.p6
};
freqData2.push(freqData1);
});
return freqData2;
});
var freqData = [{
measure_code: 'Μ1',
freq: {
P2: 47,
P3: 19,
P4: 29,
P5: 20,
P6: 100
}
}, {
measure_code: 'Μ2',
freq: {
P2: 11,
P3: 42,
P4: 74,
P5: 15,
P6: 10
}
}, {
measure_code: 'Μ3',
freq: {
P2: 93,
P3: 21,
P4: 48,
P5: 10,
P6: 10
}
}, {
measure_code: 'Μ4',
freq: {
P2: 82,
P3: 11,
P4: 12,
P5: 50,
P6: 20
}
}, {
measure_code: 'Μ5',
freq: {
P2: 44,
P3: 34,
P4: 98,
P5: 10,
P6: 14
}
}, {
measure_code: 'Μ6',
freq: {
P2: 19,
P3: 17,
P4: 13,
P5: 10,
P6: 10
}
}, {
measure_code: 'Μ7',
freq: {
P2: 18,
P3: 27,
P4: 12,
P5: 50,
P6: 18
}
}, {
measure_code: 'Μ8',
freq: {
P2: 48,
P3: 38,
P4: 42,
P5: 15,
P6: 17
}
}, {
measure_code: 'Μ9',
freq: {
P2: 77,
P3: 18,
P4: 15,
P5: 50,
P6: 14
}
}, {
measure_code: 'Μ10',
freq: {
P2: 162,
P3: 39,
P4: 41,
P5: 40,
P6: 10
}
}, {
measure_code: 'Μ11',
freq: {
P2: 62,
P3: 39,
P4: 41,
P5: 15,
P6: 20
}
}, {
measure_code: 'Μ12',
freq: {
P2: 12,
P3: 39,
P4: 41,
P5: 15,
P6: 12
}
}, {
measure_code: 'Μ13',
freq: {
P2: 162,
P3: 39,
P4: 71,
P5: 30,
P6: 10
}
}, {
measure_code: 'Μ14',
freq: {
P2: 62,
P3: 79,
P4: 41,
P5: 15,
P6: 12
}
}, {
measure_code: 'Μ16',
freq: {
P2: 12,
P3: 39,
P4: 41,
P5: 10,
P6: 10
}
}, {
measure_code: 'Μ19',
freq: {
P2: 16,
P3: 379,
P4: 41,
P5: 10,
P6: 10
}
}, {
measure_code: 'Μ20',
freq: {
P2: 16,
P3: 39,
P4: 41,
P5: 50,
P6: 32
}
}, {
measure_code: 'Μ97',
freq: {
P2: 62,
P3: 379,
P4: 47,
P5: 50,
P6: 10
}
}];
console.log(typeof freqData2);
console.log(typeof freqData2);
dashboard('#dashboard', freqData);
任何帮助都会很精彩!
答案 0 :(得分:0)
我可以看到$ .getJSON方法的问题,你试图从HTTP加载数据,所以你可能在jsfiddle控制台中得到混合内容错误,但尝试使用http服务器从本地机器运行它,你将得到数据。
答案 1 :(得分:0)
您的代码很好但是您遇到了一些问题。
以下是可行的代码。
查看评论以了解您做错了什么。
var freqData2 = []; //You didn't declared a var
//Use d3.json instead of jquery.getJSON
//As also suggested by @Alexandra in the comments
d3.json('http://88.99.13.199:3000/dashboarddata', function(err, mydata) {
console.log(err);
if(mydata && mydata.length > 0) {
//if mydata is defined and have data then loop
mydata.forEach(function(val) {
var freqData1 = {};
freqData1["measure_code"] = val.measure_code;
freqData1["freq"] = {
P2: val.p2,
P3: val.p3,
P4: val.p4,
P5: val.p5,
P6: val.p6
};
freqData2.push(freqData1);
});
}
return freqData2;
});
//Timeout? WHY? because it takes time for url to respond back
//and then all that data manipulation on it.
//So, we will wait 1 Second to get data back and then we will print it.
setTimeout(()=>{
dashboard('#dashboard', freqData2);
},1000);
其他问题是您在JSfiddle中遇到混合内容错误。为什么?因为你试图从HTTP获取数据,因为默认情况下JSFiddle会转到HTTPS。