- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
目前我正在从事 FCC 的一个项目,基本上我已经完成了整个项目。
但是,我很难制作一个简单的图例,尤其是当我使用 scaleQuantile
作为我的 colorScale 时
这是我的代码笔链接:http://codepen.io/neotriz/pen/PGOLBb
本质上,我想创建一个水平图例来输出所有颜色(在数组 color
内)并根据数据附加其文本。
我可以对图例的文本进行硬编码,但我更愿意抽象地进行(文本基于数据本身)如果有人能指出正确的方向,我将不胜感激。
let toolTip = d3.select("#canvas")
.append("div")
.classed("toolTip",true)
.style("opacity",0)
const colors = ["#5e4fa2", "#3288bd", "#66c2a5", "#abdda4",
"#e6f598", "#ffffbf", "#fee08b", "#fdae61",
"#f46d43", "#d53e4f", "#9e0142"];
const width = w - (margin.left + margin.right);
const height = h - (margin.top + margin.bottom);
const yOffset = 40;
//lets create new object to add degree key and its value
data = rawData.map( oneData => {
let degree = base + oneData.variance
return Object.assign({}, oneData, {degree: degree})
})
const svg = d3.select("#canvas")
.append("svg")
.attr("id","chart")
.attr("width", w)
.attr("height", h)
const chart = svg.append("g")
.classed("display", true)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const yearParser = d3.timeParse("%Y")
const monthParser = d3.timeParse("%m")
const x = d3.scaleTime()
.domain(d3.extent(data,function(d){
let year = yearParser(d.year)
return year
}))
.range([0,width]);
const y = d3.scaleTime()
.domain([monthParser(data[0].month),monthParser(data[11].month)])
.range([0,height-yOffset])
const xAxis = d3.axisBottom(x)
.tickFormat(d3.timeFormat("%Y")).tickSize(9)
const yAxis = d3.axisLeft(y)
.tickFormat(d3.timeFormat("%B")).tickSize(0).tickPadding(6);
const colorScale = d3.scaleQuantile()
.domain(d3.extent(data,function(d){
return d.degree
}))
.range(colors)
function toolTipText(d){
const rawMonth = monthParser(d.month);
const monthFormat = d3.timeFormat("%B");
const month = monthFormat(rawMonth)
let text = '<strong>' + month + " " + d.year + '</strong>'+ '<br>';
text += d.degree.toFixed(3) +' °C'+ '<br>';
text += 'Variance: '+d.variance +' °C'+ '<br>';
return text
}
function drawAxis(params){
//draw xAxis
this.append("g")
.call(params.axis.x)
.classed("x axis", true)
.attr("transform", "translate(0,"+ height +")")
.selectAll("text")
.style("font-size",16)
//draw yAxis
this.append("g")
.call(params.axis.y)
.classed("y axis",true)
.attr("transform","translate(0,0)")
.selectAll("text")
.attr("dy",25)
.style("font-size",14)
//label x axis
this.select(".x.axis")
.append("text")
.classed("x axis-label",true)
.attr("transform","translate(-60,"+ -height/2 +") rotate(-90)")
.style("fill","black")
.text("Months")
this.select(".y.axis")
.append("text")
.classed("y axis-label",true)
.attr("transform","translate("+ width/2 +","+ (height+60) +")")
.style("fill","black")
.text("Years")
}
function plot(params){
if (params.initialize){
drawAxis.call(this,params)
}
//enter()
this.selectAll(".degree")
.data(params.data)
.enter()
.append("rect")
.classed("degree", true)
//update
this.selectAll(".degree")
.transition()
.delay(100)
.attr("x",function(d,i){
let year = yearParser(d.year)
return x(year)
})
this.selectAll(".degree")
.attr("y",function(d,i){
let month = monthParser(d.month)
return y(month)
})
this.selectAll(".degree")
.attr("width", 4)
this.selectAll(".degree")
.attr("height", yOffset)
this.selectAll(".degree")
.style("fill", function(d,i){
return colorScale(d.degree)
})
.on("mouseover",function(d,i){
let text = toolTipText(d)
toolTip.transition()
.style("opacity",.9)
toolTip.html(text)
.style("left", (d3.event.pageX + 15) + "px")
.style("top", (d3.event.pageY - 28) + "px")
d3.select(this)
.style("stroke","gray")
.style("stroke-width", 3)
})
.on("mouseout",function(d,i){
toolTip.transition()
.style("opacity",0)
d3.select(this)
.style("stroke","none")
})
//exit()
this.selectAll(".degree")
.data(params.data)
.exit()
.remove()
}
plot.call(chart,{
base: base,
data: data,
axis: {
x: xAxis,
y: yAxis
},
initialize: true
})
最佳答案
这是一个快速实现:
function drawLegend(){
var legend = this.select(".x.axis").append("g"),
legW = 40;
legend.selectAll('rect')
.data(colorScale.range())
.enter()
.append('rect')
.attr('width', legW)
.attr('x', function(d,i){
return i * legW;
})
.attr('y', 50)
.attr('height', 20)
.style('fill', function(d){
return d;
});
legend.selectAll('text')
.data(colorScale.quantiles())
.enter()
.append('text')
.attr('x', function(d,i){
return (i + 1) * legW;
})
.attr('y', 80)
.text(function(d,i){
var rv = Math.round(d*10)/10;
if (i === 0) rv = '<' + rv;
else if (i === (colorScale.quantiles().length - 1)) rv = '>' + rv;
return rv;
})
.style('fill', 'black')
.style('stroke', 'none');
}
完整运行代码:
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charset="UTF-8" />
<title>FCC Heat-Map</title>
<style>
body,
html {
text-align: center;
background: #e2e2e2;
}
#canvas {
margin: 65px auto;
width: 1300px;
height: 600;
background: white;
-webkit-box-shadow: 0px 0px 31px -5px rgba(0, 0, 0, 0.5);
-moz-box-shadow: 0px 0px 31px -5px rgba(0, 0, 0, 0.5);
box-shadow: 0px 0px 31px -5px rgba(0, 0, 0, 0.5);
}
#chart {}
.title {
padding-top: 11px;
font-size: 2em;
font-weight: bold;
}
.year {
font-size: 1.7em;
}
.description {
font-size: 0.9em;
margin-bottom: -35px;
}
.axis-label {
font-size: 25px;
}
.toolTip {
color: white;
position: absolute;
text-align: center;
max-width: 250px;
max-height: 98px;
padding: 7px;
font: 15px sans-serif;
background: black;
border: 25px;
border-radius: 12px;
line-height: 18px;
pointer-events: none;
box-shadow: 0px 0px 12px -10px;
}
</style>
</head>
<body>
<div id="canvas"></div>
<script src="//d3js.org/d3.v4.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
var colorScale = null;
$(document).ready(function() {
const w = 1300;
const h = 600;
const margin = {
top: 50,
bottom: 80,
left: 100,
right: 20
}
function title() {
const mainTitle = document.createElement("div");
mainTitle.innerHTML = "Monthly Global Land-Surface Temperature"
mainTitle.className = "title";
const year = document.createElement("div");
year.innerHTML = "1753 - 2015";
year.className = "year";
const description = document.createElement("div")
description.innerHTML = 'Temperatures are in Celsius and reported as anomalies relative to the Jan 1951-Dec 1980 average.<br>' +
'Estimated Jan 1951-Dec 1980 absolute temperature ℃: 8.66 +/- 0.07';
description.className = "description"
let chart = document.getElementById("canvas")
chart.appendChild(mainTitle)
chart.appendChild(year)
chart.appendChild(description)
}
function render(base, rawData) {
let toolTip = d3.select("#canvas")
.append("div")
.classed("toolTip", true)
.style("opacity", 0)
const colors = ["#5e4fa2", "#3288bd", "#66c2a5", "#abdda4",
"#e6f598", "#ffffbf", "#fee08b", "#fdae61",
"#f46d43", "#d53e4f", "#9e0142"
];
const width = w - (margin.left + margin.right);
const height = h - (margin.top + margin.bottom);
const yOffset = 40;
//lets create new object to add degree key and its value
data = rawData.map(oneData => {
let degree = base + oneData.variance
return Object.assign({}, oneData, {
degree: degree
})
})
const svg = d3.select("#canvas")
.append("svg")
.attr("id", "chart")
.attr("width", w)
.attr("height", h)
const chart = svg.append("g")
.classed("display", true)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const yearParser = d3.timeParse("%Y")
const monthParser = d3.timeParse("%m")
const x = d3.scaleTime()
.domain(d3.extent(data, function(d) {
let year = yearParser(d.year)
return year
}))
.range([0, width]);
const y = d3.scaleTime()
.domain([monthParser(data[0].month), monthParser(data[11].month)])
.range([0, height - yOffset])
const xAxis = d3.axisBottom(x)
.tickFormat(d3.timeFormat("%Y")).tickSize(9)
const yAxis = d3.axisLeft(y)
.tickFormat(d3.timeFormat("%B")).tickSize(0).tickPadding(6);
colorScale = d3.scaleQuantile()
.domain(d3.extent(data, function(d) {
return d.degree
}))
.range(colors)
function toolTipText(d) {
const rawMonth = monthParser(d.month);
const monthFormat = d3.timeFormat("%B");
const month = monthFormat(rawMonth)
let text = '<strong>' + month + " " + d.year + '</strong>' + '<br>';
text += d.degree.toFixed(3) + ' °C' + '<br>';
text += 'Variance: ' + d.variance + ' °C' + '<br>';
return text
}
function drawAxis(params) {
//draw xAxis
this.append("g")
.call(params.axis.x)
.classed("x axis", true)
.attr("transform", "translate(0," + height + ")")
.selectAll("text")
.style("font-size", 16)
//draw yAxis
this.append("g")
.call(params.axis.y)
.classed("y axis", true)
.attr("transform", "translate(0,0)")
.selectAll("text")
.attr("dy", 25)
.style("font-size", 14)
//label x axis
this.select(".x.axis")
.append("text")
.classed("x axis-label", true)
.attr("transform", "translate(-60," + -height / 2 + ") rotate(-90)")
.style("fill", "black")
.text("Months")
this.select(".y.axis")
.append("text")
.classed("y axis-label", true)
.attr("transform", "translate(" + width / 2 + "," + (height + 60) + ")")
.style("fill", "black")
.text("Years")
}
function drawLegend(){
var legend = this.select(".x.axis").append("g"),
legW = 40;
legend.selectAll('rect')
.data(colorScale.range())
.enter()
.append('rect')
.attr('width', legW)
.attr('x', function(d,i){
return i * legW;
})
.attr('y', 40)
.attr('height', 20)
.style('fill', function(d){
return d;
});
legend.selectAll('text')
.data(colorScale.quantiles())
.enter()
.append('text')
.attr('x', function(d,i){
return (i + 1) * legW;
})
.attr('y', 70)
.text(function(d,i){
var rv = Math.round(d*10)/10;
if (i === 0) rv = '<' + rv;
else if (i === (colorScale.quantiles().length - 1)) rv = '>' + rv;
return rv;
})
.style('fill', 'black')
.style('stroke', 'none');
}
function plot(params) {
if (params.initialize) {
drawAxis.call(this, params)
}
//enter()
this.selectAll(".degree")
.data(params.data)
.enter()
.append("rect")
.classed("degree", true)
//update
this.selectAll(".degree")
.transition()
.delay(100)
.attr("x", function(d, i) {
let year = yearParser(d.year)
return x(year)
})
this.selectAll(".degree")
.attr("y", function(d, i) {
let month = monthParser(d.month)
return y(month)
})
this.selectAll(".degree")
.attr("width", 4)
this.selectAll(".degree")
.attr("height", yOffset)
this.selectAll(".degree")
.style("fill", function(d, i) {
return colorScale(d.degree)
})
.on("mouseover", function(d, i) {
let text = toolTipText(d)
toolTip.transition()
.style("opacity", .9)
toolTip.html(text)
.style("left", (d3.event.pageX + 15) + "px")
.style("top", (d3.event.pageY - 28) + "px")
d3.select(this)
.style("stroke", "gray")
.style("stroke-width", 3)
})
.on("mouseout", function(d, i) {
toolTip.transition()
.style("opacity", 0)
d3.select(this)
.style("stroke", "none")
})
//exit()
this.selectAll(".degree")
.data(params.data)
.exit()
.remove()
drawLegend.call(this);
}
plot.call(chart, {
base: base,
data: data,
axis: {
x: xAxis,
y: yAxis
},
initialize: true
})
}
const url = 'https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/global-temperature.json';
$.ajax({
type: "GET",
dataType: "json",
url: url,
beforeSend: () => {},
complete: () => {},
success: data => {
title()
const baseTemperature = data.baseTemperature;
const dataAPI = data.monthlyVariance;
render(baseTemperature, dataAPI);
},
fail: () => {
console.log('failure!')
},
error: () => {
let chart = document.getElementById('card');
chart.style.display = "table"
let errorMessage = document.createElement("h1");
errorMessage.innerHTML = "ERROR 404: File Not Found!"
errorMessage.className = "errorMessage";
chart.appendChild(errorMessage)
}
});
});
</script>
</body>
</html>
关于javascript - 使用 d3.js (v4) 创建水平图例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39860008/
我目前正在研究一个项目欧拉问题(www.projecteuler.net),但遇到了一个绊脚石。其中一个问题提供了一个 20x20 的数字网格,并要求直线上 4 个数字的最大乘积。这条线可以是水平的、
我有两个表,我需要从每个表中选择一列。 这必须在单个查询中完成。 好消息是这两列以正确的方式排序,并且它们都包含相同数量的行。 现在,我知道我可以通过 rowid 加入两个表,但它很慢,因为它必须进行
我想在我的 iPad 应用程序中实现一个布局,该布局具有一个可左右滚动而不是上下滚动的合适 View : 所以而不是 第 1 行第 2 行第 3 行(垂直滚动)这将是 :第 1 行、第 2 行、第 3
我有五个尺寸的图像:600x30、600x30、600x30、600x30、810x30。它们的名称分别是:0.png、1.png、2.png、3.png、4.png。 如何使用 ImageMagic
我正在寻找一个选项来滚动多个列表(水平),如附件中的图片所示。您可以向左或向右滑动以进入下一个 ListView 。顶部应该有一些按钮可以单击或滚动 我尝试将 ListViews 放入类似此代码的内容
这些值之间是否存在数学关系?如果我知道 hFOV 和 vFOV,我可以计算对角 FOV 而不涉及焦距等其他值吗? 我的第一个想法是使用毕达哥拉斯定理,但也许这是错误的。 最佳答案 感兴趣的物理量是传感
我正在尝试在 game_width=640 和 game_height=480 的窗口内绘制网格。网格单元的数量是预定义的。我想在水平和垂直方向上均匀分布单元格。 void GamePaint(HDC
你好,我已经发布了我的 iphone 应用程序 Micro-Pitch,现在正在将它移植到 android 上。我不知道如何在 ScrollView 中画线,想知道我做错了什么。 这是我的 Scrol
如果您访问我的网站:www.ryancoughlin.com - 如果您在页面右侧看到 Google、Yahoo 等 RSS 按钮。我试图让它们均匀对齐,它们的图像高度都相同,我一直试图让它们均匀对齐
我想将此 Material 水平居中: 最佳答案 将 text-align:center 添加到您的 anchor 。我假设您的 zoom1 具有 display
我正在努力做到这一点,以便我的旋转木马可以与其他文本共享一个水平行,但由于某种原因它无法正常工作,当它设置为 40% 时它占据了 100% 的宽度。 我将在下面发布代码和屏幕截图。 在上图中,它显示了
问题来了。我正在尝试放置一些 彼此相邻的元素。 div 的宽度s 未指定,取决于它们的内容。我正在使用下面的 CSS 代码来定位 彼此相邻: #div{ height: 50px; f
我正在尝试使用这样的 Bootstrap 并排打印表格 但是当我尝试打印预览时,我得到了这个 我的代码如下。我尝试了所有可能的解决方案,但我不知道为什么我无法打印我看到的页面。请指导我解决这个问题。
我想知道是否可以在背景中使用两种不同的颜色,并通过 Bootstrap 在每一侧扩展 100%。 这是我的意思的截图, 左侧为红色,右侧为深色,为更大的屏幕放大 100%。有什么简单的解决方案吗? 最
我正在尝试制作一个包含所有事件的滚动触发的整个网站。我只需要帮助来实现这种效果: 我有一个网站,其中包含一些填满所有视口(viewport)的 div,我希望用户能够向下滚动到一个命名的 div,然后
我的代码是 Show All Show Valid Show Pending Save Clear Download As CSV 我希望那些输入日期和按钮在 class="buttons" di
我在玩这个想法: 在这个 block 中我有 2 作为按钮和 并尝试了 float荷兰国际集团他们让他们粘在一起。实现这种效果的主要思想是操纵 ul 的宽度/显示状态。或者只是菜单部分。 Log
这个问题在这里已经有了答案: How can I horizontally center an element? (134 个回答) 关闭 4 年前。
我遇到了一个 CSS 问题,需要帮助。我在目录中有许多不同大小的图像,我正在动态列出它们以显示以下 View :(我仅显示两个图像作为示例) 这是我的 HTML:
这个问题在这里已经有了答案: 关闭 9 年前。 Possible Duplicate: How can I make a horizontal ListView in Android? 我已经多次使
我是一名优秀的程序员,十分优秀!