所以首先我有一个带有html的index.php加载d3液位计。我可以在浏览器中加载它,并在代码中放置一个静态整数,它可以工作。我有一个名为Tdata.php的第二个文件,用于查询MySQL并返回Json echo中的表。这可以在浏览器中显示为 [{" temperature":" 70"," Tdate":" 2017-05-29 05:04:56"}]。 每个和平分开工作,但当我输入我的D3.json,以便当前读数显示在仪表中时,页面变为空白。任何有关这方面的帮助都会非常感激,因为在D3方面我觉得自己像个菜鸟。即使在http://www.d3noob.org/2012/12/getting-data.html上度过了一天。 我甚至试图使用具有相同结果的tsv文件。
的index.php
<?php
$username = "root";
$password = "1cookie";
$server = "localhost";
$database = "environment";
$server = mysql_connect($server, $username, $password);
$connection = mysql_select_db($database, $server);
$myHquery = "SELECT * FROM `AirHumidity` WHERE `Hdate` ORDER BY Hdate DESC LIMIT 1";
$Hquery = mysql_query($myHquery);
if ( ! $Hquery ) {
echo mysql_error();
die; }
$Hdata = array();
for ($x = 0; $x < mysql_num_rows($Hquery); $x++) {
$Hdata[] = mysql_fetch_assoc($Hquery);
}
echo $json_data = json_encode($Hdata);
mysql_close($server);
?>
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.liquidFillGaugeText { font-family: Helvetica; font-weight: bold; }
</style>
</head>
<body>
<svg id="fillgauge1" width="97%" height="250"></svg>
<script src="http://d3js.org/d3.v3.min.js" type="text/javascript"></script>
<script src="liquidFillGauge.js" type="text/javascript"></script>
<script type="text/javascript">
<?php echo "data=".$json_data.";"?>
d3.json("data=", function(data, error) {
data.forEach(function(d)
{d.Hdate = parseDate(d.Hdate);
d.humidity = +d.humidity;}
)});
d3.select("#fillgauge1").call(d3.liquidfillgauge, 69);
</script>
</body>
</html>
&#13;
LiquidFillGuage.js
/*!
* @license Open source under BSD 2-clause (http://choosealicense.com/licenses/bsd-2-clause/)
* Copyright (c) 2015, Curtis Bratton
* All rights reserved.
*/
(function(d3) {
var idGenerator = (function() {
var count = 0;
return function(prefix) {
return prefix + "-" + count++;
};
})();
var defaultConfig = {
// Values
minValue: 0, // The gauge minimum value.
maxValue: 100, // The gauge maximum value.
// Styles
circleThickness: 0.05, // The outer circle thickness as a percentage of it's radius.
circleFillGap: 0.05, // The size of the gap between the outer circle and wave circle as a percentage of the outer circles radius.
circleColor: "#178BCA", // The color of the outer circle.
backgroundColor: null, // The color of the background
waveColor: "#178BCA", // The color of the fill wave.
width: 0, // You might want to set the width and height if it is not detected properly by the plugin
height: 0,
// Waves
waveHeight: 0.05, // The wave height as a percentage of the radius of the wave circle.
waveCount: 1, // The number of full waves per width of the wave circle.
waveOffset: 0, // The amount to initially offset the wave. 0 = no offset. 1 = offset of one full wave.
// Animations
waveRise: true, // Control if the wave should rise from 0 to it's full height, or start at it's full height.
waveRiseTime: 1000, // The amount of time in milliseconds for the wave to rise from 0 to it's final height.
waveRiseAtStart: true, // If set to false and waveRise at true, will disable only the initial animation
waveAnimate: true, // Controls if the wave scrolls or is static.
waveAnimateTime: 18000, // The amount of time in milliseconds for a full wave to enter the wave circle.
waveHeightScaling: true, // Controls wave size scaling at low and high fill percentages. When true, wave height reaches it's maximum at 50% fill, and minimum at 0% and 100% fill. This helps to prevent the wave from making the wave circle from appear totally full or empty when near it's minimum or maximum fill.
valueCountUp: true, // If true, the displayed value counts up from 0 to it's final value upon loading and updating. If false, the final value is displayed.
valueCountUpAtStart: true, // If set to false and valueCountUp at true, will disable only the initial animation
// Text
textVertPosition: 0.5, // The height at which to display the percentage text withing the wave circle. 0 = bottom, 1 = top.
textSize: 1, // The relative height of the text to display in the wave circle. 1 = 50%
displayPercent: true, // If true, a % symbol is displayed after the value.
textColor: "#045681", // The color of the value text when the wave does not overlap it.
waveTextColor: "#A4DBf8", // The color of the value text when the wave overlaps it.
};
d3.liquidfillgauge = function(g, value, settings) {
// Handle configuration
var config = d3.map(defaultConfig);
d3.map(settings).forEach(function(key, val) {
config.set(key, val);
});
g.each(function(d) {
var gauge = d3.select(this);
var width = config.get("width") !== 0 ? config.get("width") : parseInt(gauge.style("width"));
var height = config.get("height") !== 0 ? config.get("height") : parseInt(gauge.style("height"));
var radius = Math.min(width, height) / 2;
var locationX = width / 2 - radius;
var locationY = height / 2 - radius;
var fillPercent = Math.max(config.get("minValue"), Math.min(config.get("maxValue"), value)) / config.get("maxValue");
var waveHeightScale;
if (config.get("waveHeightScaling")) {
waveHeightScale = d3.scale.linear()
.range([0, config.get("waveHeight"), 0])
.domain([0, 50, 100]);
} else {
waveHeightScale = d3.scale.linear()
.range([config.get("waveHeight"), config.get("waveHeight")])
.domain([0, 100]);
}
var textPixels = (config.get("textSize") * radius / 2);
var textFinalValue = parseFloat(value).toFixed(2);
var textStartValue = config.get("valueCountUp") ? config.get("minValue") : textFinalValue;
var percentText = config.get("displayPercent") ? "%" : "";
var circleThickness = config.get("circleThickness") * radius;
var circleFillGap = config.get("circleFillGap") * radius;
var fillCircleMargin = circleThickness + circleFillGap;
var fillCircleRadius = radius - fillCircleMargin;
var waveHeight = fillCircleRadius * waveHeightScale(fillPercent * 100);
var waveLength = fillCircleRadius * 2 / config.get("waveCount");
var waveClipCount = 1 + config.get("waveCount");
var waveClipWidth = waveLength * waveClipCount;
// Rounding functions so that the correct number of decimal places is always displayed as the value counts up.
var textRounder = function(value) {
return Math.round(value);
};
if (parseFloat(textFinalValue) != parseFloat(textRounder(textFinalValue))) {
textRounder = function(value) {
return parseFloat(value).toFixed(1);
};
}
if (parseFloat(textFinalValue) != parseFloat(textRounder(textFinalValue))) {
textRounder = function(value) {
return parseFloat(value).toFixed(2);
};
}
// Data for building the clip wave area.
var data = [];
for (var i = 0; i <= 40 * waveClipCount; i++) {
data.push({
x: i / (40 * waveClipCount),
y: (i / (40))
});
}
// Scales for drawing the outer circle.
var gaugeCircleX = d3.scale.linear().range([0, 2 * Math.PI]).domain([0, 1]);
var gaugeCircleY = d3.scale.linear().range([0, radius]).domain([0, radius]);
// Scales for controlling the size of the clipping path.
var waveScaleX = d3.scale.linear().range([0, waveClipWidth]).domain([0, 1]);
var waveScaleY = d3.scale.linear().range([0, waveHeight]).domain([0, 1]);
// Scales for controlling the position of the clipping path.
var waveRiseScale = d3.scale.linear()
// The clipping area size is the height of the fill circle + the wave height, so we position the clip wave
// such that the it will won't overlap the fill circle at all when at 0%, and will totally cover the fill
// circle at 100%.
.range([(fillCircleMargin + fillCircleRadius * 2 + waveHeight), (fillCircleMargin - waveHeight)])
.domain([0, 1]);
var waveAnimateScale = d3.scale.linear()
.range([0, waveClipWidth - fillCircleRadius * 2]) // Push the clip area one full wave then snap back.
.domain([0, 1]);
// Scale for controlling the position of the text within the gauge.
var textRiseScaleY = d3.scale.linear()
.range([fillCircleMargin + fillCircleRadius * 2, (fillCircleMargin + textPixels * 0.7)])
.domain([0, 1]);
// Center the gauge within the parent SVG.
var gaugeGroup = gauge.append("g")
.attr('transform', 'translate(' + locationX + ',' + locationY + ')');
// Draw the background circle
if (config.get("backgroundColor")) {
gaugeGroup.append("circle")
.attr("r", radius)
.style("fill", config.get("backgroundColor"))
.attr('transform', 'translate(' + radius + ',' + radius + ')');
}
// Draw the outer circle.
var gaugeCircleArc = d3.svg.arc()
.startAngle(gaugeCircleX(0))
.endAngle(gaugeCircleX(1))
.outerRadius(gaugeCircleY(radius))
.innerRadius(gaugeCircleY(radius - circleThickness));
gaugeGroup.append("path")
.attr("d", gaugeCircleArc)
.style("fill", config.get("circleColor"))
.attr('transform', 'translate(' + radius + ',' + radius + ')');
// Text where the wave does not overlap.
var text1 = gaugeGroup.append("text")
.attr("class", "liquidFillGaugeText")
.attr("text-anchor", "middle")
.attr("font-size", textPixels + "px")
.style("fill", config.get("textColor"))
.attr('transform', 'translate(' + radius + ',' + textRiseScaleY(config.get("textVertPosition")) + ')');
// The clipping wave area.
var clipArea = d3.svg.area()
.x(function(d) {
return waveScaleX(d.x);
})
.y0(function(d) {
return waveScaleY(Math.sin(Math.PI * 2 * config.get("waveOffset") * -1 + Math.PI * 2 * (1 - config.get("waveCount")) + d.y * 2 * Math.PI));
})
.y1(function(d) {
return (fillCircleRadius * 2 + waveHeight);
});
var clipId = idGenerator("clipWave");
var waveGroup = gaugeGroup.append("defs")
.append("clipPath")
.attr("id", clipId);
var wave = waveGroup.append("path")
.datum(data)
.attr("d", clipArea);
// The inner circle with the clipping wave attached.
var fillCircleGroup = gaugeGroup.append("g")
.attr("clip-path", "url(#" + clipId + ")");
fillCircleGroup.append("circle")
.attr("cx", radius)
.attr("cy", radius)
.attr("r", fillCircleRadius)
.style("fill", config.get("waveColor"));
// Text where the wave does overlap.
var text2 = fillCircleGroup.append("text")
.attr("class", "liquidFillGaugeText")
.attr("text-anchor", "middle")
.attr("font-size", textPixels + "px")
.style("fill", config.get("waveTextColor"))
.attr('transform', 'translate(' + radius + ',' + textRiseScaleY(config.get("textVertPosition")) + ')');
// Make the wave rise. wave and waveGroup are separate so that horizontal and vertical movement can be controlled independently.
var waveGroupXPosition = fillCircleMargin + fillCircleRadius * 2 - waveClipWidth;
if (config.get("waveAnimate")) {
var animateWave = function() {
wave.transition()
.duration(config.get("waveAnimateTime"))
.ease("linear")
.attr('transform', 'translate(' + waveAnimateScale(1) + ',0)')
.each("end", function() {
wave.attr('transform', 'translate(' + waveAnimateScale(0) + ',0)');
animateWave();
});
};
animateWave();
}
var transition = function(from, to, riseWave, animateText) {
// Update texts and animate
if (animateText) {
var textTween = function() {
var i = d3.interpolate(from, to);
return function(t) {
this.textContent = textRounder(i(t)) + percentText;
};
};
text1.transition()
.duration(config.get("waveRiseTime"))
.tween("text", textTween);
text2.transition()
.duration(config.get("waveRiseTime"))
.tween("text", textTween);
} else {
text1.text(textRounder(to) + percentText);
text2.text(textRounder(to) + percentText);
}
// Update the wave
toPercent = Math.max(config.get("minValue"), Math.min(config.get("maxValue"), to)) / config.get("maxValue");
fromPercent = Math.max(config.get("minValue"), Math.min(config.get("maxValue"), from)) / config.get("maxValue");
if (riseWave) {
waveGroup.attr('transform', 'translate(' + waveGroupXPosition + ',' + waveRiseScale(fromPercent) + ')')
.transition()
.duration(config.get("waveRiseTime"))
.attr('transform', 'translate(' + waveGroupXPosition + ',' + waveRiseScale(toPercent) + ')');
} else {
waveGroup.attr('transform', 'translate(' + waveGroupXPosition + ',' + waveRiseScale(toPercent) + ')');
}
};
transition(
textStartValue,
textFinalValue,
config.get("waveRise") && config.get("waveRiseAtStart"),
config.get("valueCountUp") && config.get("valueCountUpAtStart")
);
// Event to update the value
gauge.on("valueChanged", function(newValue) {
transition(value, newValue, config.get("waveRise"), config.get("valueCountUp"));
value = newValue;
});
gauge.on("destroy", function() {
// Stop all the transitions
text1.interrupt().transition();
text2.interrupt().transition();
waveGroup.interrupt().transition();
wave.interrupt().transition();
// Unattach events
gauge.on("valueChanged", null);
gauge.on("destroy", null);
});
});
};
})(d3);
&#13;
答案 0 :(得分:0)
所以我能够通过在php echo之后添加以下内容来解决问题。
var parseDate = d3.time.format("%Y/%m/%d %H:%M:%S").parse;
d3.json("data=", function(Hdata, error) {
d3.json("data=", function(data, error) { data.forEach(function(d) {
data.forEach(function(d) d.humidity = +d.humidity;
{d.Hdate = parseDate(d.Hdate); d.Hdate = parseDate(d.Hdate);
d.humidity = +d.humidity;}
)});
d3.select("#fillgauge1").call(d3.liquidfillgauge, d.humidity,{
circleThickness: 0.15,
circleColor: "#0b4cc4",
textColor: "#ef980b",
waveTextColor: "#e05611",
waveColor: "#5d27db",
textVertPosition: 0.5,
waveAnimateTime: 1000,
waveHeight: 0.05,
waveAnimate: true,
waveRise: false,
waveOffset: 0.25,
textSize: 0.75,
waveCount: 3
});
d3.select("#fillgauge1").call(d3.liquidfillgauge, 69);
})});
&#13;
现在,如果我只能隐藏在网页正文中显示的回声,并且只在d3指标中显示并自动刷新,则可以创建新表。 任何有关如何做到这一点的建议将不胜感激。