这章节将完成我们的分时图,并使用真实的数据来进行展示分时图。

一天的交易时间段分为上午的09:30~11:30,下午的13:00~15:00两个时间段,因为分时间段的关系,数据是不连续的,所以会先分为2个grid,上午的grid跟下午的grid,又因为分时图是由折线图跟柱状图来组成的,所以又把上下午的grid再一分为二,变成了4个grid,这也是为什么会分解成4个grid的原因。

先看看分时图的数据。

现在我们再重新看一下雪球的分时图

根路径的last_price指的是昨日收盘价,这个数值很重要,我们需要这个数值来建立一条基准线;然后items里面就是今天的交易数据了,current表示这一分钟应该取的价格,一般是指一分钟内最后一笔成交的价格,也是折线图的数据;volume则是这一分钟的成交量,也就是下方柱状图的数据;timestamp表示这是哪个时间的数据,我们用来作为x轴的数据。

将x轴的type设置成“time”。为了方便我们也把坐标轴的最大最小值设置成随数据的最大最小值,把max设置成"dataMax",min设置成"dataMin"。

type: 'time',
max:'dataMax',
min:'dataMin'

y轴也是需要进行一些配置,已达到完全对称的效果,需要配置interval属性以及max,min属性。x轴的时间是已经固定了09:30~11:30,13:00~15:00,所以可以直接写死,但是y轴的价格是会波动的,所以这三个数值是要经过运算得来的。

我们先配置上方的折线图的y轴坐标轴线为9条,设置splitNumber属性为9即可,定义变量priceMax、priceMin、priceInterval(priceInterval表示价格的差值),以及左边的数据数组grid1Data,右边的数据数组grid3Data。(注:由于x轴的type修改成了'time'类型,所以去掉x轴的data属性)。下方的柱状图也是这样,下方的柱状图一共是3条坐标轴线,设置splitNumber属性为3即可,定义变量volumeMax,volumeMin,volumeInterval(volumeInterval表示价格的差值),以及左边的数据数组grid2Data,右边的数据数组grid4Data;柱状图每一条柱子的颜色设置方式为

color: function (params) {
   // params.dataIndex 柱子的下标
return "#000";
}

所以要新建两个数组volumeColor1,volumeColor2来存放柱子的颜色。接下来,我们要遍历我们拿到的分时图数据data,来组成我们需要的数据。

for(var i in data.data.items){
// 上午的数据
if(i < 121){
if(data.data.items[i].current > priceMax){
priceMax = data.data.items[i].current;
}
if(data.data.items[i].current < priceMin || priceMin == 0){
priceMin = data.data.items[i].current;
}
// 左上方折线图
grid1Data.push([data.data.items[i].timestamp,data.data.items[i].current]); if(data.data.items[i].volume > volumeMax){
volumeMax = data.data.items[i].volume;
}
if(data.data.items[i].volume < volumeMin ){
volumeMin = data.data.items[i].volume;
} if(i == 0){ if(data.data.items[i].current >= lastPrice){
volumeColor1.push(UP_COLOR);
}else{
volumeColor1.push(DOWN_COLOR);
} }else{
if(data.data.items[i].current >= data.data.items[i-1].current){
volumeColor1.push(UP_COLOR);
}else{
volumeColor1.push(DOWN_COLOR);
} } // 左下方柱状图
grid2Data.push([data.data.items[i].timestamp,data.data.items[i].volume]); }else{// 下午的数据 if(data.data.items[i].current > priceMax){
priceMax = data.data.items[i].current;
}
if(data.data.items[i].current < priceMin || priceMin == 0){
priceMin = data.data.items[i].current;
}
// 右上方折线图
grid3Data.push([data.data.items[i].timestamp,data.data.items[i].current]); if(data.data.items[i].volume > volumeMax){
volumeMax = data.data.items[i].volume;
}
if(data.data.items[i].volume < volumeMin){
volumeMin = data.data.items[i].volume;
} if(data.data.items[i].current >= data.data.items[i-1].current){
volumeColor2.push(UP_COLOR);
}else{
volumeColor2.push(DOWN_COLOR);
} // 右下方柱状图
grid4Data.push([data.data.items[i].timestamp,data.data.items[i].volume]); }
}

遍历完成后,得到了价格的最大最小值,成交量的最大值,接下来还要处理一下价格的最大最小值,以达到对称的效果。列入,昨日收盘价是1,今日最高价是上涨了0.5块,最高价是1+0.5 = 1.5块,那么为了达到对称的效果,下方的价格线应该是1-0.5=0.5块。

// 重新计算价格的最大最小值,以达到对称的效果
if((lastPrice - priceMax) * -1 > (lastPrice - priceMin)){
priceMin = (lastPrice - ((lastPrice - priceMax)* -1));
}else{
priceMax =(lastPrice + (lastPrice - priceMin));
} priceInterval = (priceMax - lastPrice) / 4;
volumeInterval = volumeMax / 2;

重新计算了最大最小价格,并得到了价格的差值,成交量的差值,把这些数值设置到对应的位置上。第一个跟第三个grid的y轴属性max,min,interval分别设置成priceMax,priceMin,priceInterval;第二个跟第四个grid的y轴属性max,min,interval分别设置成volumeMax,0,volumeInterval。然后我们会发现,y轴上的值的小数位非常大,x轴上显示的是月日时分的格式,所以还要对这些显示的数值进行格式化。首先对y轴的数据进行格式化,左上方的y轴设置:

axisLabel:{
fontSize:10,
margin:0,
// y轴的数值向内显示
align:"left",
formatter: function (value, index) {
return value.toFixed(2);
},
color: function (value, index) { // 中间基准线的数值为黑色
if(parseFloat(value).toFixed(2) == lastPrice){
return NORMAL_COLOR;
} // 上涨区域的数字为红色
if(value > lastPrice){
return UP_COLOR;
} // 下方下跌的数值为绿色
if(value < lastPrice){
return DOWN_COLOR;
} }
},

右上方的y轴的设置:

axisLabel:{
fontSize:10,
margin:0,
// y轴的数值向内显示
align:"right",
formatter: function (value, index) {
var persent = (value - lastPrice) / lastPrice;
persent = (persent < 0) ? persent * -1 : persent;
persent = persent * 100; return persent.toFixed(2) + '%';
},
color: function (value, index) { // 中间基准线的数值为黑色
if(parseFloat(value).toFixed(2) == lastPrice){
return NORMAL_COLOR;
} // 上涨区域的数字为红色
if(value > lastPrice){
return UP_COLOR;
} // 下方下跌的数值为绿色
if(value < lastPrice){
return DOWN_COLOR;
} }
},

下方的柱状图的y轴数值则隐藏不显示,只需要把第二个第四个grid的y轴的axisLabel.show设置成false即可

axisLabel:{
//设置显示坐标轴的数值为不显示
show:false
},

然后重新对x轴的时间进行格式化成HH:mm的格式,只需要对第二个跟第四个grid的x轴进行配置即可。

第二个grid的x轴的配置

axisLabel: {
fontSize:12,
show: true,
color:'#888',
formatter: function (value) {
var a = echarts.format.formatTime('hh:mm', value);
if(a == "11:30"){
return "";
}
if(a == "09:30"){
return " 09:30";
}
return a;
}
},

第四个grid的x轴的配置

axisLabel: {
fontSize:12,
show: true,
showMinLabel:false,
color:'#888',
formatter: function (value) {
var a = echarts.format.formatTime('hh:mm', value);
if(a == "13:00"){
return "11:30/13:00";
}
if(a == "15:00"){
return "15:00 ";
}
return a;
}
},

接下来配置一下柱状图的柱子颜色。在series里找到柱状图的配置,对itemStyle进行配置即可。

第一个柱状图的配置

itemStyle:{
normal: {
color: function (params) {
return volumeColor1[params.dataIndex];
}
}
}

第二个柱状图的配置

itemStyle:{
normal: {
color: function (params) {
return volumeColor2[params.dataIndex];
}
}
}

最后我们把各个坐标轴的小尖刺,就是刻度值旁边的短线去掉。把各个坐标轴的axisTick.show设置成false即可。

axisTick:{show:false}

做完这一步后,我们的代码就成了这样

// 雪球json数据 https://stock.xueqiu.com/v5/stock/chart/minute.json?symbol=SH000001&period=1d
var jsonData = '';
var data = JSON.parse(jsonData); // 第一个grid的数据(折线图)
var grid1Data = [];
// 第二个grid的数据(柱状图)
var grid2Data = [];
// 第三个grid数据(折线图)
var grid3Data = [];
// 第四个grid数据(柱状图)
var grid4Data = []; // 柱状图的颜色
// 柱状图的红绿规则比较麻烦,所以本次采用的规则则是根据价格的涨跌来区分
var volumeColor1 = [];
var volumeColor2 = []; var UP_COLOR = "#E24528";
var DOWN_COLOR = "#009933";
var NORMAL_COLOR = "#33353C"; var priceMax = 0,priceMin = 0,priceInterval = 0,volumeMax = 0,volumeMin = 0,volumeInterval = 0;
var lastPrice = data.data.last_close; initData(); function initData(){ for(var i in data.data.items){
// 上午的数据
if(i < 121){
if(data.data.items[i].current > priceMax){
priceMax = data.data.items[i].current;
}
if(data.data.items[i].current < priceMin || priceMin == 0){
priceMin = data.data.items[i].current;
}
// 左上方折线图
grid1Data.push([data.data.items[i].timestamp,data.data.items[i].current]); if(data.data.items[i].volume > volumeMax){
volumeMax = data.data.items[i].volume;
}
if(data.data.items[i].volume < volumeMin ){
volumeMin = data.data.items[i].volume;
} if(i == 0){ if(data.data.items[i].current >= lastPrice){
volumeColor1.push(UP_COLOR);
}else{
volumeColor1.push(DOWN_COLOR);
} }else{
if(data.data.items[i].current >= data.data.items[i-1].current){
volumeColor1.push(UP_COLOR);
}else{
volumeColor1.push(DOWN_COLOR);
} } // 左下方柱状图
grid2Data.push([data.data.items[i].timestamp,data.data.items[i].volume]); }else{// 下午的数据 if(data.data.items[i].current > priceMax){
priceMax = data.data.items[i].current;
}
if(data.data.items[i].current < priceMin || priceMin == 0){
priceMin = data.data.items[i].current;
}
// 右上方折线图
grid3Data.push([data.data.items[i].timestamp,data.data.items[i].current]); if(data.data.items[i].volume > volumeMax){
volumeMax = data.data.items[i].volume;
}
if(data.data.items[i].volume < volumeMin){
volumeMin = data.data.items[i].volume;
} if(data.data.items[i].current >= data.data.items[i-1].current){
volumeColor2.push(UP_COLOR);
}else{
volumeColor2.push(DOWN_COLOR);
} // 右下方柱状图
grid4Data.push([data.data.items[i].timestamp,data.data.items[i].volume]); }
} // 重新计算价格的最大最小值,以达到对称的效果
if((lastPrice - priceMax) * -1 > (lastPrice - priceMin)){
priceMin = (lastPrice - ((lastPrice - priceMax)* -1));
}else{
priceMax =(lastPrice + (lastPrice - priceMin));
} priceInterval = (priceMax - lastPrice) / 4;
volumeInterval = volumeMax / 2; setOptions();
} function setOptions(){ // 初始化一个echarts的对象
var chart = echarts.init(document.getElementById('charts')); // echarts折线图的配置项
var option = {
// grid
grid:[
// 第一个grid
{
top:10,// 图表的外边距
height:200,// 图表的高度
left:'0',
width:'50%',//因为是左右各一个图表,使用百分比的方式显得更方便,
},
// 第二个grid,第二个图表是在第一个图表的下方,所以要把它定位到底部
{
top:240,//设置上方的外边距是第一个图表的高度再加10,使用top是方便我们调整下方grid的高度
left:'0',
width:'50%',// 宽度与第一个图表一个大
height:100
},
// 第三个grid,第三个图表是在第一个图表的右方,所以要把它定位到右方
{
top:10,// 图表的外边距
left:'50%',//设置右边图表的左边距是第一个图表的大小,达到定位右边的效果
width:'50%',// 宽度与第一个图表一个大
height:200
},
// 第四个grid,第四个图表是在第三个图表的下方,所以要把它定位到底部
{
top:240,//设置上方的外边距是第三个图表的高度再加10,使用top是方便我们调整下方grid的高度
left:'50%',//设置右边图表的左边距是第三个图表的大小,达到定位右边的效果
width:'50%',// 宽度与第一个图表一个大
height:100
}
],
// 多个图表则会存在对个x轴y轴,所以这里的配置我们也换成数组的方式
// x轴配置,
xAxis:[
// 第一个grid的x轴属性
{ // 告诉echarts,这个第一个grid的x轴
gridIndex:0,
// 坐标轴是否留白
boundaryGap:false,
// x轴的刻度
axisTick:{show:false},
// x轴的刻度值
axisLabel:{show:false},
max:'dataMax',
min:'dataMin',
type: 'time',
axisLine:{
lineStyle:{
color:"#ECEEF2"
}
},
splitLine:{
lineStyle:{
color:"#ECEEF2",
// 设置线条喂风格为虚线
type:"dashed"
}
},
},
// 第二个grid的x轴属性
{
// 告诉echarts,这个第一个grid的x轴
gridIndex:1,
// 坐标轴是否留白
boundaryGap:false,
// x轴的刻度
axisTick:{show:false},
max:'dataMax',
min:'dataMin',
type: 'time',
axisLabel: {
fontSize:12,
show: true,
color:'#888',
formatter: function (value) {
var a = echarts.format.formatTime('hh:mm', value);
if(a == "11:30"){
return "";
}
if(a == "09:30"){
return " 09:30";
}
return a;
}
},
axisLine:{
lineStyle:{
color:"#ECEEF2"
}
},
splitLine:{
lineStyle:{
color:"#ECEEF2",
// 设置线条喂风格为虚线
type:"dashed"
}
},
},
// 第三个grid的x轴属性
{
// 告诉echarts,这个第一个grid的x轴
gridIndex:2,
// 坐标轴是否留白
boundaryGap:false,
// x轴的刻度
axisTick:{show:false},
// x轴的刻度值
axisLabel:{show:false},
type: 'time',
max:'dataMax',
min:'dataMin',
axisLine:{
lineStyle:{
color:"#ECEEF2"
}
},
splitLine:{
lineStyle:{
color:"#ECEEF2",
// 设置线条喂风格为虚线
type:"dashed"
}
},
},
// 第四个grid的x轴属性
{
// 告诉echarts,这个第一个grid的x轴
gridIndex:3,
// 坐标轴是否留白
boundaryGap:false,
// x轴的刻度
axisTick:{show:false},
type: 'time',
max:'dataMax',
min:'dataMin',
axisLabel: {
fontSize:12,
show: true,
showMinLabel:false,
color:'#888',
formatter: function (value) {
var a = echarts.format.formatTime('hh:mm', value);
if(a == "13:00"){
return "11:30/13:00";
}
if(a == "15:00"){
return "15:00 ";
}
return a;
}
},
axisLine:{
lineStyle:{
color:"#ECEEF2"
}
},
splitLine:{
lineStyle:{
color:"#ECEEF2",
// 设置线条喂风格为虚线
type:"dashed"
}
},
}
],
// y轴配置
yAxis: [
// 第一个grid的y轴属性
{
// 去掉刻度值旁边的指示线
axisTick:{show:false},
splitNumber:9,
gridIndex:0,
interval:priceInterval,
max:priceMax,
min:priceMin,
splitLine:{
lineStyle:{
color:"#ECEEF2",
// 设置线条喂风格为虚线
type:"dashed",
}
},
axisLine:{
lineStyle:{
color:"#ECEEF2"
}
},
axisLabel:{
fontSize:10,
margin:0,
// y轴的数值向内显示
align:"left",
formatter: function (value, index) {
return value.toFixed(2);
},
color: function (value, index) { // 中间基准线的数值为黑色
if(parseFloat(value).toFixed(2) == lastPrice){
return NORMAL_COLOR;
} // 上涨区域的数字为红色
if(value > lastPrice){
return UP_COLOR;
} // 下方下跌的数值为绿色
if(value < lastPrice){
return DOWN_COLOR;
} }
},
},
// 第二个grid的y轴属性
{
// 去掉刻度值旁边的指示线
axisTick:{show:false},
splitNumber:3,
gridIndex:1,
interval:volumeInterval,
max:volumeMax,
min:0,
splitLine:{
lineStyle:{
color:"#ECEEF2",
// 设置线条喂风格为虚线
type:"dashed"
}
},
axisLine:{
lineStyle:{
color:"#ECEEF2"
}
},
axisLabel:{
//设置显示坐标轴的数值为不显示
show:false
},
},
// 第三个grid的y轴属性
{
// 去掉刻度值旁边的指示线
axisTick:{show:false},
splitNumber:9,
position:'right',
gridIndex:2,
interval:priceInterval,
max:priceMax,
min:priceMin,
splitLine:{
lineStyle:{
color:"#ECEEF2",
// 设置线条喂风格为虚线
type:"dashed"
}
},
axisLine:{
lineStyle:{
color:"#ECEEF2"
}
},
axisLabel:{
fontSize:10,
margin:0,
// y轴的数值向内显示
align:"right",
formatter: function (value, index) {
var persent = (value - lastPrice) / lastPrice;
persent = (persent < 0) ? persent * -1 : persent;
persent = persent * 100; return persent.toFixed(2) + '%';
},
color: function (value, index) { // 中间基准线的数值为黑色
if(parseFloat(value).toFixed(2) == lastPrice){
return NORMAL_COLOR;
} // 上涨区域的数字为红色
if(value > lastPrice){
return UP_COLOR;
} // 下方下跌的数值为绿色
if(value < lastPrice){
return DOWN_COLOR;
} }
},
},
// 第四个grid的y轴属性
{
// 去掉刻度值旁边的指示线
axisTick:{show:false},
splitNumber:3,
position:'right',
gridIndex:3,
interval:volumeInterval,
max:volumeMax,
min:0,
axisLabel:{
//设置显示坐标轴的数值为不显示
show:false
},
splitLine:{
lineStyle:{
color:"#ECEEF2",
// 设置线条喂风格为虚线
type:"dashed"
}
},
axisLine:{
lineStyle:{
color:"#ECEEF2"
}
},
}
],
// 数据可以通过xAxisIndex,yAxisIndex属性,来指定是哪个grid的数据
series: [
// 第一个图表的数据
{
// 平滑曲线
smooth:true,
// 是否显示折线上的圆点
symbol:'none',
// 线条颜色
lineStyle:{
color:"#0481F8",
width:1
},
xAxisIndex:0,
yAxisIndex:0,
data: grid1Data,
type: 'line',
},
// 第二个图表的数据
{
xAxisIndex:1,
yAxisIndex:1,
// 柱状图柱子宽度
barWidth:1,
data: grid2Data,
type: 'bar',
// 设置柱状图颜色
itemStyle:{
normal: {
color: function (params) {
return volumeColor1[params.dataIndex];
}
}
}
},
// 第三个图表的数据
{
// 平滑曲线
smooth:true,
// 是否显示折线上的圆点
symbol:'none',
// 线条颜色
lineStyle:{
color:"#0481F8",
width:1
},
xAxisIndex:2,
yAxisIndex:2,
data: grid3Data,
type: 'line',
},
// 第四个图表的数据
{
xAxisIndex:3,
yAxisIndex:3,
// 柱状图柱子宽度
barWidth:1,
data: grid4Data,
type: 'bar',
// 设置柱状图颜色
itemStyle:{
normal: {
color: function (params) {
return volumeColor2[params.dataIndex];
}
}
}
}
]
}; chart.setOption(option); }

效果图如下:

我们的分时图已经基本完成了,但是我们还是能看到11:30/13:00这里有一段是没有连接上的,因为是两个图表的原因所以会断开,这个将在下一章修正。下一章我们将添加图表的一些指示器,修正一些小问题。

使用百度echarts仿雪球分时图(三)的更多相关文章

  1. 使用百度echarts仿雪球分时图(四)

    这章节来收拾一下一些小BUG,顺便把各个小提示信息也补上,分时图也就完成了. 上章节末尾提到的一个bug,就是第一个grid跟第三个grid之间是断开的,折线并没有连在一起,所以先来收拾这个问题.没有 ...

  2. 使用百度echarts仿雪球分时图(一)

    第一次写技术博客,有不足的地方希望大家指证出来,我再加以改正,谢谢大家. 之前一直没有找到一个合适的分时图项目,所以决定自己动手撸一个.接触的图表框架不多,在网上看到不少人推荐使用echarts,看了 ...

  3. 使用百度echarts仿雪球分时图(二)

    上一章简单的介绍了一下分时图的构成,其实就是折线图跟柱状图的组成.本来这章打算是把分时图做完,然后再写一章来进行美化和总结,但是仔细观察了一下,发现其实东西还是有点多的.分时图的图表做完后,还要去美化 ...

  4. 使用百度Echarts制作力导向图

    最近项目需求制作一个力导向图来展示企业的画像等关系信息,故想到了百度Echarts的关系图,在这使用Echarts3.0版本来实现.先上效果图,再看代吗 哎,本来想整个工程扔出来,发现好像没地方上传附 ...

  5. WPF仿百度Echarts人口迁移图

    GitHub地址:https://github.com/ptddqr/wpf-echarts-map/tree/master 关于大名鼎鼎的百度Echarts我就不多说了 不了解的朋友直接看官方的例子 ...

  6. C#+JQuery+.Ashx+百度Echarts实现全国省市地图和饼状图动态数据图形报表的统计

    在目前的一个项目中,需要用到报表表现数据,这些数据有多个维度,需要同时表现出来,同时可能会有大量数据呈现的需求,经过几轮挑选,最终选择了百度的echarts作为报表基础类库.echarts功能强大,界 ...

  7. 手把手教你画AndroidK线分时图及指标

    先废话一下:来到公司之前.项目是由外包公司做的,面试初,没有接触过分时图k线这块,认为好难,我能搞定不.可是一段时间之后,发现之前做的那是一片稀烂,可是这货是主功能啊.迟早的自己操刀,痛下决心,开搞, ...

  8. iOS-Andriod百度地图仿百度外卖-饿了么-选择我的地址-POI检索/

    http://zanderzhang.gitcafe.io/2015/09/19/iOS-Andriod百度地图仿百度外卖-饿了么-选择我的地址-POI检索/ 百度外卖选择送货地址: 饿了么选择送货地 ...

  9. Android 仿PhotoShop调色板应用(三) 主体界面绘制

    版权声明:本文为博主原创文章,未经博主允许不得转载. Android 仿PhotoShop调色板应用(三) 主体界面绘制    关于PhotoShop调色板应用的实现我总结了两个最核心的部分:   1 ...

随机推荐

  1. Coarse-to-Fine超分辨率相关

    1.A Coarse-to-Fine Subpixel Registration Method to Recover Local Perspective Deformation in the Appl ...

  2. 21 Flutter仿京东商城项目 商品详情 请求接口渲染数据 商品属性数据渲染

    加群452892873 下载对应21可文件,运行方法,建好项目,直接替换lib目录,在往pubspec.yaml添加上一下扩展.   cupertino_icons: ^0.1.2   flutter ...

  3. 一百三十一:CMS系统之轮播图上传图片功能

    将七牛js放到common下 把获取uptoken的接口放到common视图中 把初始化七牛放到banners.js中 //初始化七牛$(function () { qiniujs.setUp({ ' ...

  4. [Scikit-learn] *2.3 Clustering - DBSCAN: Density-Based Spatial Clustering of Applications with Noise

    http://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html#sklearn.cluster.DBSCAN ...

  5. 配置WEB错误页面

    项目运行时,难免会出现错误,这些错误我们不可以也不方便直接让用户看到,所以配置错误页面是非常必要的. 一下是项目的Web.xml文件,在最下方阴影部分是配置错误界面. <?xml version ...

  6. C#创建windows服务(二:创建和卸载windows服务)

    引用地址: https://docs.microsoft.com/zh-cn/dotnet/framework/windows-services/how-to-create-windows-servi ...

  7. Ubuntu 16.04 RabbitMq 安装与运行

    前言目前公司用阿里云 + redis 的方式实现的消息队列.了解了目前几种主流的消息组件(主要包括rabbitmq.kafka.)的优缺点后,这里为了深入学习rabbitmq,我在自己的腾讯云服务器上 ...

  8. 深入剖析Java虚拟机内存结构

    深入剖析Java虚拟机内存模型 JVM整体架构 JVM整体架构如下: 通过编写代码来分析整个内存区域 public class Math { public static final Integer C ...

  9. kafka的offset相关知识

    Offset存储模型 由于一个partition只能固定的交给一个消费者组中的一个消费者消费,因此Kafka保存offset时并不直接为每个消费者保存,而是以 groupid-topic-partit ...

  10. fatal error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires MFC sha

    调试程序时出现以下问题:d:\program files (x86)\microsoft visual studio 10.0\vc\atlmfc\include\afx.h(24): fatal e ...